This commit is contained in:
1736
trunk/java/com/l2jserver/gameserver/model/actor/L2Attackable.java
Normal file
1736
trunk/java/com/l2jserver/gameserver/model/actor/L2Attackable.java
Normal file
File diff suppressed because it is too large
Load Diff
7069
trunk/java/com/l2jserver/gameserver/model/actor/L2Character.java
Normal file
7069
trunk/java/com/l2jserver/gameserver/model/actor/L2Character.java
Normal file
File diff suppressed because it is too large
Load Diff
183
trunk/java/com/l2jserver/gameserver/model/actor/L2Decoy.java
Normal file
183
trunk/java/com/l2jserver/gameserver/model/actor/L2Decoy.java
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.items.L2Weapon;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.CharInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
|
||||
import com.l2jserver.gameserver.taskmanager.DecayTaskManager;
|
||||
|
||||
public abstract class L2Decoy extends L2Character
|
||||
{
|
||||
private final L2PcInstance _owner;
|
||||
|
||||
public L2Decoy(int objectId, L2CharTemplate template, L2PcInstance owner)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2Decoy);
|
||||
_owner = owner;
|
||||
setXYZInvisible(owner.getX(), owner.getY(), owner.getZ());
|
||||
setIsInvul(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
super.onSpawn();
|
||||
sendPacket(new CharInfo(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAbnormalEffect()
|
||||
{
|
||||
Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
|
||||
|
||||
for (L2PcInstance player : plrs)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
player.sendPacket(new CharInfo(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stopDecay()
|
||||
{
|
||||
DecayTaskManager.getInstance().cancel(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDecay()
|
||||
{
|
||||
deleteMe(_owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
return _owner.isAutoAttackable(attacker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2ItemInstance getActiveWeaponInstance()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Weapon getActiveWeaponItem()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2ItemInstance getSecondaryWeaponInstance()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Weapon getSecondaryWeaponItem()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getId()
|
||||
{
|
||||
return getTemplate().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLevel()
|
||||
{
|
||||
return getTemplate().getLevel();
|
||||
}
|
||||
|
||||
public void deleteMe(L2PcInstance owner)
|
||||
{
|
||||
decayMe();
|
||||
getKnownList().removeAllKnownObjects();
|
||||
owner.setDecoy(null);
|
||||
}
|
||||
|
||||
public synchronized void unSummon(L2PcInstance owner)
|
||||
{
|
||||
|
||||
if (isVisible() && !isDead())
|
||||
{
|
||||
if (getWorldRegion() != null)
|
||||
{
|
||||
getWorldRegion().removeFromZones(this);
|
||||
}
|
||||
owner.setDecoy(null);
|
||||
decayMe();
|
||||
getKnownList().removeAllKnownObjects();
|
||||
}
|
||||
}
|
||||
|
||||
public final L2PcInstance getOwner()
|
||||
{
|
||||
return _owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2PcInstance getActingPlayer()
|
||||
{
|
||||
return _owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2NpcTemplate getTemplate()
|
||||
{
|
||||
return (L2NpcTemplate) super.getTemplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendInfo(L2PcInstance activeChar)
|
||||
{
|
||||
activeChar.sendPacket(new CharInfo(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(L2GameServerPacket mov)
|
||||
{
|
||||
if (getOwner() != null)
|
||||
{
|
||||
getOwner().sendPacket(mov);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(SystemMessageId id)
|
||||
{
|
||||
if (getOwner() != null)
|
||||
{
|
||||
getOwner().sendPacket(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
1942
trunk/java/com/l2jserver/gameserver/model/actor/L2Npc.java
Normal file
1942
trunk/java/com/l2jserver/gameserver/model/actor/L2Npc.java
Normal file
File diff suppressed because it is too large
Load Diff
360
trunk/java/com/l2jserver/gameserver/model/actor/L2Playable.java
Normal file
360
trunk/java/com/l2jserver/gameserver/model/actor/L2Playable.java
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlEvent;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.InstanceManager;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.knownlist.PlayableKnownList;
|
||||
import com.l2jserver.gameserver.model.actor.stat.PlayableStat;
|
||||
import com.l2jserver.gameserver.model.actor.status.PlayableStatus;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jserver.gameserver.model.effects.EffectFlag;
|
||||
import com.l2jserver.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jserver.gameserver.model.entity.Instance;
|
||||
import com.l2jserver.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jserver.gameserver.model.events.impl.character.OnCreatureKill;
|
||||
import com.l2jserver.gameserver.model.events.returns.TerminateReturn;
|
||||
import com.l2jserver.gameserver.model.quest.QuestState;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.serverpackets.EtcStatusUpdate;
|
||||
|
||||
/**
|
||||
* This class represents all Playable characters in the world.<br>
|
||||
* L2Playable:
|
||||
* <ul>
|
||||
* <li>L2PcInstance</li>
|
||||
* <li>L2Summon</li>
|
||||
* </ul>
|
||||
*/
|
||||
public abstract class L2Playable extends L2Character
|
||||
{
|
||||
private L2Character _lockedTarget = null;
|
||||
private L2PcInstance transferDmgTo = null;
|
||||
|
||||
/**
|
||||
* Constructor of L2Playable.<br>
|
||||
* <B><U> Actions</U> :</B>
|
||||
* <ul>
|
||||
* <li>Call the L2Character constructor to create an empty _skills slot and link copy basic Calculator set to this L2Playable</li>
|
||||
* </ul>
|
||||
* @param objectId Identifier of the object to initialized
|
||||
* @param template The L2CharTemplate to apply to the L2Playable
|
||||
*/
|
||||
public L2Playable(int objectId, L2CharTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2Playable);
|
||||
setIsInvul(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayableKnownList getKnownList()
|
||||
{
|
||||
return (PlayableKnownList) super.getKnownList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initKnownList()
|
||||
{
|
||||
setKnownList(new PlayableKnownList(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayableStat getStat()
|
||||
{
|
||||
return (PlayableStat) super.getStat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initCharStat()
|
||||
{
|
||||
setStat(new PlayableStat(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayableStatus getStatus()
|
||||
{
|
||||
return (PlayableStatus) super.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initCharStatus()
|
||||
{
|
||||
setStatus(new PlayableStatus(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
final TerminateReturn returnBack = EventDispatcher.getInstance().notifyEvent(new OnCreatureKill(killer, this), this, TerminateReturn.class);
|
||||
if ((returnBack != null) && returnBack.terminate())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// killing is only possible one time
|
||||
synchronized (this)
|
||||
{
|
||||
if (isDead())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// now reset currentHp to zero
|
||||
setCurrentHp(0);
|
||||
setIsDead(true);
|
||||
}
|
||||
|
||||
// Set target to null and cancel Attack or Cast
|
||||
setTarget(null);
|
||||
|
||||
// Stop movement
|
||||
stopMove(null);
|
||||
|
||||
// Stop HP/MP/CP Regeneration task
|
||||
getStatus().stopHpMpRegeneration();
|
||||
|
||||
boolean deleteBuffs = true;
|
||||
|
||||
if (isNoblesseBlessedAffected())
|
||||
{
|
||||
stopEffects(L2EffectType.NOBLESSE_BLESSING);
|
||||
deleteBuffs = false;
|
||||
}
|
||||
if (isResurrectSpecialAffected())
|
||||
{
|
||||
stopEffects(L2EffectType.RESURRECTION_SPECIAL);
|
||||
deleteBuffs = false;
|
||||
}
|
||||
if (isPlayer())
|
||||
{
|
||||
L2PcInstance activeChar = getActingPlayer();
|
||||
|
||||
if (activeChar.hasCharmOfCourage())
|
||||
{
|
||||
if (activeChar.isInSiege())
|
||||
{
|
||||
getActingPlayer().reviveRequest(getActingPlayer(), null, false, 0);
|
||||
}
|
||||
activeChar.setCharmOfCourage(false);
|
||||
activeChar.sendPacket(new EtcStatusUpdate(activeChar));
|
||||
}
|
||||
}
|
||||
|
||||
if (deleteBuffs)
|
||||
{
|
||||
stopAllEffectsExceptThoseThatLastThroughDeath();
|
||||
}
|
||||
|
||||
// Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform
|
||||
broadcastStatusUpdate();
|
||||
|
||||
if (getWorldRegion() != null)
|
||||
{
|
||||
getWorldRegion().onDeath(this);
|
||||
}
|
||||
|
||||
// Notify Quest of L2Playable's death
|
||||
L2PcInstance actingPlayer = getActingPlayer();
|
||||
|
||||
if (!actingPlayer.isNotifyQuestOfDeathEmpty())
|
||||
{
|
||||
for (QuestState qs : actingPlayer.getNotifyQuestOfDeath())
|
||||
{
|
||||
qs.getQuest().notifyDeath((killer == null ? this : killer), this, qs);
|
||||
}
|
||||
}
|
||||
// Notify instance
|
||||
if (getInstanceId() > 0)
|
||||
{
|
||||
final Instance instance = InstanceManager.getInstance().getInstance(getInstanceId());
|
||||
if (instance != null)
|
||||
{
|
||||
instance.notifyDeath(killer, this);
|
||||
}
|
||||
}
|
||||
|
||||
if (killer != null)
|
||||
{
|
||||
L2PcInstance player = killer.getActingPlayer();
|
||||
|
||||
if (player != null)
|
||||
{
|
||||
player.onKillUpdatePvPKarma(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify L2Character AI
|
||||
getAI().notifyEvent(CtrlEvent.EVT_DEAD);
|
||||
super.updateEffectIcons();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean checkIfPvP(L2Character target)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
return false; // Target is null
|
||||
}
|
||||
if (target == this)
|
||||
{
|
||||
return false; // Target is self
|
||||
}
|
||||
if (!target.isPlayable())
|
||||
{
|
||||
return false; // Target is not a L2Playable
|
||||
}
|
||||
|
||||
final L2PcInstance player = getActingPlayer();
|
||||
if (player == null)
|
||||
{
|
||||
return false; // Active player is null
|
||||
}
|
||||
|
||||
if (player.getKarma() != 0)
|
||||
{
|
||||
return false; // Active player has karma
|
||||
}
|
||||
|
||||
final L2PcInstance targetPlayer = target.getActingPlayer();
|
||||
if (targetPlayer == null)
|
||||
{
|
||||
return false; // Target player is null
|
||||
}
|
||||
|
||||
if (targetPlayer == this)
|
||||
{
|
||||
return false; // Target player is self
|
||||
}
|
||||
if (targetPlayer.getKarma() != 0)
|
||||
{
|
||||
return false; // Target player has karma
|
||||
}
|
||||
if (targetPlayer.getPvpFlag() == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
// Even at war, there should be PvP flag
|
||||
// if(
|
||||
// player.getClan() == null ||
|
||||
// targetPlayer.getClan() == null ||
|
||||
// (
|
||||
// !targetPlayer.getClan().isAtWarWith(player.getClanId()) &&
|
||||
// targetPlayer.getWantsPeace() == 0 &&
|
||||
// player.getWantsPeace() == 0
|
||||
// )
|
||||
// )
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return True.
|
||||
*/
|
||||
@Override
|
||||
public boolean canBeAttacked()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Support for Noblesse Blessing skill, where buffs are retained after resurrect
|
||||
public final boolean isNoblesseBlessedAffected()
|
||||
{
|
||||
return isAffected(EffectFlag.NOBLESS_BLESSING);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if char can resurrect by himself, {@code false} otherwise
|
||||
*/
|
||||
public final boolean isResurrectSpecialAffected()
|
||||
{
|
||||
return isAffected(EffectFlag.RESURRECTION_SPECIAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the Silent Moving mode is active, {@code false} otherwise
|
||||
*/
|
||||
public boolean isSilentMovingAffected()
|
||||
{
|
||||
return isAffected(EffectFlag.SILENT_MOVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* For Newbie Protection Blessing skill, keeps you safe from an attack by a chaotic character >= 10 levels apart from you.
|
||||
* @return
|
||||
*/
|
||||
public final boolean isProtectionBlessingAffected()
|
||||
{
|
||||
return isAffected(EffectFlag.PROTECTION_BLESSING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEffectIcons(boolean partyOnly)
|
||||
{
|
||||
getEffectList().updateEffectIcons(partyOnly);
|
||||
}
|
||||
|
||||
public boolean isLockedTarget()
|
||||
{
|
||||
return _lockedTarget != null;
|
||||
}
|
||||
|
||||
public L2Character getLockedTarget()
|
||||
{
|
||||
return _lockedTarget;
|
||||
}
|
||||
|
||||
public void setLockedTarget(L2Character cha)
|
||||
{
|
||||
_lockedTarget = cha;
|
||||
}
|
||||
|
||||
public void setTransferDamageTo(L2PcInstance val)
|
||||
{
|
||||
transferDmgTo = val;
|
||||
}
|
||||
|
||||
public L2PcInstance getTransferingDamageTo()
|
||||
{
|
||||
return transferDmgTo;
|
||||
}
|
||||
|
||||
public abstract int getKarma();
|
||||
|
||||
public abstract byte getPvpFlag();
|
||||
|
||||
public abstract boolean useMagic(Skill skill, boolean forceUse, boolean dontMove);
|
||||
|
||||
public abstract void storeMe();
|
||||
|
||||
public abstract void storeEffect(boolean storeEffects);
|
||||
|
||||
public abstract void restoreEffects();
|
||||
|
||||
@Override
|
||||
public boolean isPlayable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
1232
trunk/java/com/l2jserver/gameserver/model/actor/L2Summon.java
Normal file
1232
trunk/java/com/l2jserver/gameserver/model/actor/L2Summon.java
Normal file
File diff suppressed because it is too large
Load Diff
83
trunk/java/com/l2jserver/gameserver/model/actor/L2Tower.java
Normal file
83
trunk/java/com/l2jserver/gameserver/model/actor/L2Tower.java
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor;
|
||||
|
||||
import com.l2jserver.gameserver.GeoData;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
|
||||
/**
|
||||
* This class is a super-class for L2ControlTowerInstance and L2FlameTowerInstance.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public abstract class L2Tower extends L2Npc
|
||||
{
|
||||
public L2Tower(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setIsInvul(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeAttacked()
|
||||
{
|
||||
// Attackable during siege by attacker only
|
||||
return ((getCastle() != null) && (getCastle().getResidenceId() > 0) && getCastle().getSiege().isInProgress());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
// Attackable during siege by attacker only
|
||||
return ((attacker != null) && attacker.isPlayer() && (getCastle() != null) && (getCastle().getResidenceId() > 0) && getCastle().getSiege().isInProgress() && getCastle().getSiege().checkIsAttacker(((L2PcInstance) attacker).getClan()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAction(L2PcInstance player, boolean interact)
|
||||
{
|
||||
if (!canTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this != player.getTarget())
|
||||
{
|
||||
// Set the target of the L2PcInstance player
|
||||
player.setTarget(this);
|
||||
}
|
||||
else if (interact)
|
||||
{
|
||||
if (isAutoAttackable(player) && (Math.abs(player.getZ() - getZ()) < 100) && GeoData.getInstance().canSeeTarget(player, this))
|
||||
{
|
||||
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
|
||||
}
|
||||
}
|
||||
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onForcedAttack(L2PcInstance player)
|
||||
{
|
||||
onAction(player);
|
||||
}
|
||||
}
|
||||
522
trunk/java/com/l2jserver/gameserver/model/actor/L2Vehicle.java
Normal file
522
trunk/java/com/l2jserver/gameserver/model/actor/L2Vehicle.java
Normal file
@@ -0,0 +1,522 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.GameTimeController;
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.MapRegionManager;
|
||||
import com.l2jserver.gameserver.model.L2World;
|
||||
import com.l2jserver.gameserver.model.L2WorldRegion;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.TeleportWhereType;
|
||||
import com.l2jserver.gameserver.model.VehiclePathPoint;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.knownlist.VehicleKnownList;
|
||||
import com.l2jserver.gameserver.model.actor.stat.VehicleStat;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jserver.gameserver.model.interfaces.ILocational;
|
||||
import com.l2jserver.gameserver.model.items.L2Weapon;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* @author DS
|
||||
*/
|
||||
public abstract class L2Vehicle extends L2Character
|
||||
{
|
||||
protected int _dockId = 0;
|
||||
protected final FastList<L2PcInstance> _passengers = new FastList<>();
|
||||
protected Location _oustLoc = null;
|
||||
private Runnable _engine = null;
|
||||
|
||||
protected VehiclePathPoint[] _currentPath = null;
|
||||
protected int _runState = 0;
|
||||
|
||||
public L2Vehicle(int objectId, L2CharTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2Vehicle);
|
||||
setIsFlying(true);
|
||||
}
|
||||
|
||||
public boolean isBoat()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAirShip()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean canBeControlled()
|
||||
{
|
||||
return _engine == null;
|
||||
}
|
||||
|
||||
public void registerEngine(Runnable r)
|
||||
{
|
||||
_engine = r;
|
||||
}
|
||||
|
||||
public void runEngine(int delay)
|
||||
{
|
||||
if (_engine != null)
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(_engine, delay);
|
||||
}
|
||||
}
|
||||
|
||||
public void executePath(VehiclePathPoint[] path)
|
||||
{
|
||||
_runState = 0;
|
||||
_currentPath = path;
|
||||
|
||||
if ((_currentPath != null) && (_currentPath.length > 0))
|
||||
{
|
||||
final VehiclePathPoint point = _currentPath[0];
|
||||
if (point.getMoveSpeed() > 0)
|
||||
{
|
||||
getStat().setMoveSpeed(point.getMoveSpeed());
|
||||
}
|
||||
if (point.getRotationSpeed() > 0)
|
||||
{
|
||||
getStat().setRotationSpeed(point.getRotationSpeed());
|
||||
}
|
||||
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(point.getX(), point.getY(), point.getZ(), 0));
|
||||
return;
|
||||
}
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToNextRoutePoint()
|
||||
{
|
||||
_move = null;
|
||||
|
||||
if (_currentPath != null)
|
||||
{
|
||||
_runState++;
|
||||
if (_runState < _currentPath.length)
|
||||
{
|
||||
final VehiclePathPoint point = _currentPath[_runState];
|
||||
if (!isMovementDisabled())
|
||||
{
|
||||
if (point.getMoveSpeed() == 0)
|
||||
{
|
||||
point.setHeading(point.getRotationSpeed());
|
||||
teleToLocation(point, false);
|
||||
_currentPath = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (point.getMoveSpeed() > 0)
|
||||
{
|
||||
getStat().setMoveSpeed(point.getMoveSpeed());
|
||||
}
|
||||
if (point.getRotationSpeed() > 0)
|
||||
{
|
||||
getStat().setRotationSpeed(point.getRotationSpeed());
|
||||
}
|
||||
|
||||
MoveData m = new MoveData();
|
||||
m.disregardingGeodata = false;
|
||||
m.onGeodataPathIndex = -1;
|
||||
m._xDestination = point.getX();
|
||||
m._yDestination = point.getY();
|
||||
m._zDestination = point.getZ();
|
||||
m._heading = 0;
|
||||
|
||||
final double dx = point.getX() - getX();
|
||||
final double dy = point.getY() - getY();
|
||||
final double distance = Math.sqrt((dx * dx) + (dy * dy));
|
||||
if (distance > 1)
|
||||
{
|
||||
setHeading(Util.calculateHeadingFrom(getX(), getY(), point.getX(), point.getY()));
|
||||
}
|
||||
|
||||
m._moveStartTime = GameTimeController.getInstance().getGameTicks();
|
||||
_move = m;
|
||||
|
||||
GameTimeController.getInstance().registerMovingObject(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_currentPath = null;
|
||||
}
|
||||
}
|
||||
|
||||
runEngine(10);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initKnownList()
|
||||
{
|
||||
setKnownList(new VehicleKnownList(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VehicleStat getStat()
|
||||
{
|
||||
return (VehicleStat) super.getStat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initCharStat()
|
||||
{
|
||||
setStat(new VehicleStat(this));
|
||||
}
|
||||
|
||||
public boolean isInDock()
|
||||
{
|
||||
return _dockId > 0;
|
||||
}
|
||||
|
||||
public int getDockId()
|
||||
{
|
||||
return _dockId;
|
||||
}
|
||||
|
||||
public void setInDock(int d)
|
||||
{
|
||||
_dockId = d;
|
||||
}
|
||||
|
||||
public void setOustLoc(Location loc)
|
||||
{
|
||||
_oustLoc = loc;
|
||||
}
|
||||
|
||||
public Location getOustLoc()
|
||||
{
|
||||
return _oustLoc != null ? _oustLoc : MapRegionManager.getInstance().getTeleToLocation(this, TeleportWhereType.TOWN);
|
||||
}
|
||||
|
||||
public void oustPlayers()
|
||||
{
|
||||
L2PcInstance player;
|
||||
|
||||
// Use iterator because oustPlayer will try to remove player from _passengers
|
||||
final Iterator<L2PcInstance> iter = _passengers.iterator();
|
||||
while (iter.hasNext())
|
||||
{
|
||||
player = iter.next();
|
||||
iter.remove();
|
||||
if (player != null)
|
||||
{
|
||||
oustPlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void oustPlayer(L2PcInstance player)
|
||||
{
|
||||
player.setVehicle(null);
|
||||
player.setInVehiclePosition(null);
|
||||
removePassenger(player);
|
||||
}
|
||||
|
||||
public boolean addPassenger(L2PcInstance player)
|
||||
{
|
||||
if ((player == null) || _passengers.contains(player))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// already in other vehicle
|
||||
if ((player.getVehicle() != null) && (player.getVehicle() != this))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_passengers.add(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void removePassenger(L2PcInstance player)
|
||||
{
|
||||
try
|
||||
{
|
||||
_passengers.remove(player);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return _passengers.isEmpty();
|
||||
}
|
||||
|
||||
public List<L2PcInstance> getPassengers()
|
||||
{
|
||||
return _passengers;
|
||||
}
|
||||
|
||||
public void broadcastToPassengers(L2GameServerPacket sm)
|
||||
{
|
||||
for (L2PcInstance player : _passengers)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume ticket(s) and teleport player from boat if no correct ticket
|
||||
* @param itemId Ticket itemId
|
||||
* @param count Ticket count
|
||||
* @param oustX
|
||||
* @param oustY
|
||||
* @param oustZ
|
||||
*/
|
||||
public void payForRide(int itemId, int count, int oustX, int oustY, int oustZ)
|
||||
{
|
||||
final Collection<L2PcInstance> passengers = getKnownList().getKnownPlayersInRadius(1000);
|
||||
if ((passengers != null) && !passengers.isEmpty())
|
||||
{
|
||||
L2ItemInstance ticket;
|
||||
InventoryUpdate iu;
|
||||
for (L2PcInstance player : passengers)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (player.isInBoat() && (player.getBoat() == this))
|
||||
{
|
||||
if (itemId > 0)
|
||||
{
|
||||
ticket = player.getInventory().getItemByItemId(itemId);
|
||||
if ((ticket == null) || (player.getInventory().destroyItem("Boat", ticket, count, player, this) == null))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_DO_NOT_POSSESS_THE_CORRECT_TICKET_TO_BOARD_THE_BOAT);
|
||||
player.teleToLocation(new Location(oustX, oustY, oustZ), true);
|
||||
continue;
|
||||
}
|
||||
iu = new InventoryUpdate();
|
||||
iu.addModifiedItem(ticket);
|
||||
player.sendPacket(iu);
|
||||
}
|
||||
addPassenger(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updatePosition(int gameTicks)
|
||||
{
|
||||
final boolean result = super.updatePosition(gameTicks);
|
||||
|
||||
for (L2PcInstance player : _passengers)
|
||||
{
|
||||
if ((player != null) && (player.getVehicle() == this))
|
||||
{
|
||||
player.setXYZ(getX(), getY(), getZ());
|
||||
player.revalidateZone(false);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teleToLocation(ILocational loc, boolean allowRandomOffset)
|
||||
{
|
||||
if (isMoving())
|
||||
{
|
||||
stopMove(null, false);
|
||||
}
|
||||
|
||||
setIsTeleporting(true);
|
||||
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
|
||||
for (L2PcInstance player : _passengers)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
player.teleToLocation(loc, false);
|
||||
}
|
||||
}
|
||||
|
||||
decayMe();
|
||||
setXYZ(loc.getX(), loc.getY(), loc.getZ());
|
||||
|
||||
// temporary fix for heading on teleports
|
||||
if (loc.getHeading() != 0)
|
||||
{
|
||||
setHeading(loc.getHeading());
|
||||
}
|
||||
|
||||
onTeleported();
|
||||
revalidateZone(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopMove(Location loc, boolean updateKnownObjects)
|
||||
{
|
||||
_move = null;
|
||||
if (loc != null)
|
||||
{
|
||||
setXYZ(loc.getX(), loc.getY(), loc.getZ());
|
||||
setHeading(loc.getHeading());
|
||||
revalidateZone(true);
|
||||
}
|
||||
|
||||
if (Config.MOVE_BASED_KNOWNLIST && updateKnownObjects)
|
||||
{
|
||||
getKnownList().findObjects();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteMe()
|
||||
{
|
||||
_engine = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (isMoving())
|
||||
{
|
||||
stopMove(null);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Failed stopMove().", e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
oustPlayers();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Failed oustPlayers().", e);
|
||||
}
|
||||
|
||||
final L2WorldRegion oldRegion = getWorldRegion();
|
||||
|
||||
try
|
||||
{
|
||||
decayMe();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Failed decayMe().", e);
|
||||
}
|
||||
|
||||
if (oldRegion != null)
|
||||
{
|
||||
oldRegion.removeFromZones(this);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
getKnownList().removeAllKnownObjects();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Failed cleaning knownlist.", e);
|
||||
}
|
||||
|
||||
// Remove L2Object object from _allObjects of L2World
|
||||
L2World.getInstance().removeObject(this);
|
||||
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAbnormalEffect()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2ItemInstance getActiveWeaponInstance()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Weapon getActiveWeaponItem()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2ItemInstance getSecondaryWeaponInstance()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Weapon getSecondaryWeaponItem()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLevel()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public class AIAccessor extends L2Character.AIAccessor
|
||||
{
|
||||
@Override
|
||||
public void detachAI()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVehicle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.appearance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.Sex;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
public class PcAppearance
|
||||
{
|
||||
public static final int DEFAULT_TITLE_COLOR = 0xECF9A2;
|
||||
|
||||
private L2PcInstance _owner;
|
||||
|
||||
private byte _face;
|
||||
|
||||
private byte _hairColor;
|
||||
|
||||
private byte _hairStyle;
|
||||
|
||||
private boolean _sex; // Female true(1)
|
||||
|
||||
/** true if the player is invisible */
|
||||
private boolean _ghostmode = false;
|
||||
|
||||
/** The current visible name of this player, not necessarily the real one */
|
||||
private String _visibleName;
|
||||
|
||||
/** The current visible title of this player, not necessarily the real one */
|
||||
private String _visibleTitle;
|
||||
|
||||
/** The default name color is 0xFFFFFF. */
|
||||
private int _nameColor = 0xFFFFFF;
|
||||
|
||||
/** The default title color is 0xECF9A2. */
|
||||
private int _titleColor = DEFAULT_TITLE_COLOR;
|
||||
|
||||
public PcAppearance(byte face, byte hColor, byte hStyle, boolean sex)
|
||||
{
|
||||
_face = face;
|
||||
_hairColor = hColor;
|
||||
_hairStyle = hStyle;
|
||||
_sex = sex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param visibleName The visibleName to set.
|
||||
*/
|
||||
public final void setVisibleName(String visibleName)
|
||||
{
|
||||
_visibleName = visibleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the visibleName.
|
||||
*/
|
||||
public final String getVisibleName()
|
||||
{
|
||||
if (_visibleName == null)
|
||||
{
|
||||
return getOwner().getName();
|
||||
}
|
||||
return _visibleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param visibleTitle The visibleTitle to set.
|
||||
*/
|
||||
public final void setVisibleTitle(String visibleTitle)
|
||||
{
|
||||
_visibleTitle = visibleTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the visibleTitle.
|
||||
*/
|
||||
public final String getVisibleTitle()
|
||||
{
|
||||
if (_visibleTitle == null)
|
||||
{
|
||||
return getOwner().getTitle();
|
||||
}
|
||||
return _visibleTitle;
|
||||
}
|
||||
|
||||
public final byte getFace()
|
||||
{
|
||||
return _face;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value
|
||||
*/
|
||||
public final void setFace(int value)
|
||||
{
|
||||
_face = (byte) value;
|
||||
}
|
||||
|
||||
public final byte getHairColor()
|
||||
{
|
||||
return _hairColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value
|
||||
*/
|
||||
public final void setHairColor(int value)
|
||||
{
|
||||
_hairColor = (byte) value;
|
||||
}
|
||||
|
||||
public final byte getHairStyle()
|
||||
{
|
||||
return _hairStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value
|
||||
*/
|
||||
public final void setHairStyle(int value)
|
||||
{
|
||||
_hairStyle = (byte) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if char is female
|
||||
*/
|
||||
public final boolean getSex()
|
||||
{
|
||||
return _sex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Sex of the char
|
||||
*/
|
||||
public Sex getSexType()
|
||||
{
|
||||
return _sex ? Sex.FEMALE : Sex.MALE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isfemale
|
||||
*/
|
||||
public final void setSex(boolean isfemale)
|
||||
{
|
||||
_sex = isfemale;
|
||||
}
|
||||
|
||||
public void setGhostMode(boolean b)
|
||||
{
|
||||
_ghostmode = b;
|
||||
}
|
||||
|
||||
public boolean isGhost()
|
||||
{
|
||||
return _ghostmode;
|
||||
}
|
||||
|
||||
public int getNameColor()
|
||||
{
|
||||
return _nameColor;
|
||||
}
|
||||
|
||||
public void setNameColor(int nameColor)
|
||||
{
|
||||
if (nameColor < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_nameColor = nameColor;
|
||||
}
|
||||
|
||||
public void setNameColor(int red, int green, int blue)
|
||||
{
|
||||
_nameColor = (red & 0xFF) + ((green & 0xFF) << 8) + ((blue & 0xFF) << 16);
|
||||
}
|
||||
|
||||
public int getTitleColor()
|
||||
{
|
||||
return _titleColor;
|
||||
}
|
||||
|
||||
public void setTitleColor(int titleColor)
|
||||
{
|
||||
if (titleColor < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_titleColor = titleColor;
|
||||
}
|
||||
|
||||
public void setTitleColor(int red, int green, int blue)
|
||||
{
|
||||
_titleColor = (red & 0xFF) + ((green & 0xFF) << 8) + ((blue & 0xFF) << 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param owner The owner to set.
|
||||
*/
|
||||
public void setOwner(L2PcInstance owner)
|
||||
{
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the owner.
|
||||
*/
|
||||
public L2PcInstance getOwner()
|
||||
{
|
||||
return _owner;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision: $ $Date: $
|
||||
* @author LBaldi
|
||||
*/
|
||||
public class L2AdventurerInstance extends L2NpcInstance
|
||||
{
|
||||
public L2AdventurerInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2AdventurerInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "data/html/adventurer_guildsman/" + pom + ".htm";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.ai.L2AirShipAI;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.AirShipManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Vehicle;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExAirShipInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExGetOffAirShip;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExGetOnAirShip;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExMoveToLocationAirShip;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExStopMoveAirShip;
|
||||
|
||||
/**
|
||||
* Flying airships. Very similar to Maktakien boats (see L2BoatInstance) but these do fly :P
|
||||
* @author DrHouse, DS
|
||||
*/
|
||||
public class L2AirShipInstance extends L2Vehicle
|
||||
{
|
||||
public L2AirShipInstance(int objectId, L2CharTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2AirShipInstance);
|
||||
setAI(new L2AirShipAI(new AIAccessor()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAirShip()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isOwner(L2PcInstance player)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getOwnerId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean isCaptain(L2PcInstance player)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getCaptainId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getHelmObjectId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getHelmItemId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public boolean setCaptain(L2PcInstance player)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getFuel()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setFuel(int f)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public int getMaxFuel()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setMaxFuel(int mf)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToNextRoutePoint()
|
||||
{
|
||||
final boolean result = super.moveToNextRoutePoint();
|
||||
if (result)
|
||||
{
|
||||
broadcastPacket(new ExMoveToLocationAirShip(this));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addPassenger(L2PcInstance player)
|
||||
{
|
||||
if (!super.addPassenger(player))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
player.setVehicle(this);
|
||||
player.setInVehiclePosition(new Location(0, 0, 0));
|
||||
player.broadcastPacket(new ExGetOnAirShip(player, this));
|
||||
player.getKnownList().removeAllKnownObjects();
|
||||
player.setXYZ(getX(), getY(), getZ());
|
||||
player.revalidateZone(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void oustPlayer(L2PcInstance player)
|
||||
{
|
||||
super.oustPlayer(player);
|
||||
final Location loc = getOustLoc();
|
||||
if (player.isOnline())
|
||||
{
|
||||
player.broadcastPacket(new ExGetOffAirShip(player, this, loc.getX(), loc.getY(), loc.getZ()));
|
||||
player.getKnownList().removeAllKnownObjects();
|
||||
player.setXYZ(loc.getX(), loc.getY(), loc.getZ());
|
||||
player.revalidateZone(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setXYZInvisible(loc.getX(), loc.getY(), loc.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteMe()
|
||||
{
|
||||
if (!super.deleteMe())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AirShipManager.getInstance().removeAirShip(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopMove(Location loc, boolean updateKnownObjects)
|
||||
{
|
||||
super.stopMove(loc, updateKnownObjects);
|
||||
|
||||
broadcastPacket(new ExStopMoveAirShip(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAbnormalEffect()
|
||||
{
|
||||
broadcastPacket(new ExAirShipInfo(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendInfo(L2PcInstance activeChar)
|
||||
{
|
||||
if (isVisibleFor(activeChar))
|
||||
{
|
||||
activeChar.sendPacket(new ExAirShipInfo(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
|
||||
/**
|
||||
* This class manages all Castle Siege Artefacts.<BR>
|
||||
* <BR>
|
||||
* @version $Revision: 1.11.2.1.2.7 $ $Date: 2005/04/06 16:13:40 $
|
||||
*/
|
||||
public final class L2ArtefactInstance extends L2Npc
|
||||
{
|
||||
/**
|
||||
* Constructor of L2ArtefactInstance (use L2Character and L2NpcInstance constructor).<BR>
|
||||
* <BR>
|
||||
* <B><U> Actions</U> :</B><BR>
|
||||
* <BR>
|
||||
* <li>Call the L2Character constructor to set the _template of the L2ArtefactInstance (copy skills from template to object and link _calculators to NPC_STD_CALCULATOR)</li> <li>Set the name of the L2ArtefactInstance</li> <li>Create a RandomAnimation Task that will be launched after the
|
||||
* calculated delay if the server allow it</li><BR>
|
||||
* <BR>
|
||||
* @param objectId the identifier of the object to initialized
|
||||
* @param template to apply to the NPC
|
||||
*/
|
||||
public L2ArtefactInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2ArtefactInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
super.onSpawn();
|
||||
getCastle().registerArtefact(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return False.
|
||||
*/
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeAttacked()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onForcedAttack(L2PcInstance player)
|
||||
{
|
||||
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reduceCurrentHp(double damage, L2Character attacker, Skill skill)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reduceCurrentHp(double damage, L2Character attacker, boolean awake, boolean isDOT, Skill skill)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,728 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import static com.l2jserver.gameserver.model.itemcontainer.Inventory.MAX_ADENA;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.AuctionManager;
|
||||
import com.l2jserver.gameserver.instancemanager.ClanHallManager;
|
||||
import com.l2jserver.gameserver.instancemanager.MapRegionManager;
|
||||
import com.l2jserver.gameserver.model.ClanPrivilege;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.entity.Auction;
|
||||
import com.l2jserver.gameserver.model.entity.Auction.Bidder;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
|
||||
public final class L2AuctioneerInstance extends L2Npc
|
||||
{
|
||||
private static final int COND_ALL_FALSE = 0;
|
||||
private static final int COND_BUSY_BECAUSE_OF_SIEGE = 1;
|
||||
private static final int COND_REGULAR = 3;
|
||||
|
||||
private final Map<Integer, Auction> _pendingAuctions = new FastMap<>();
|
||||
|
||||
public L2AuctioneerInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2AuctioneerInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
int condition = validateCondition(player);
|
||||
if (condition <= COND_ALL_FALSE)
|
||||
{
|
||||
// TODO: html
|
||||
player.sendMessage("Wrong conditions.");
|
||||
return;
|
||||
}
|
||||
else if (condition == COND_BUSY_BECAUSE_OF_SIEGE)
|
||||
{
|
||||
String filename = "data/html/auction/auction-busy.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
else if (condition == COND_REGULAR)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(command, " ");
|
||||
String actualCommand = st.nextToken(); // Get actual command
|
||||
|
||||
String val = "";
|
||||
if (st.countTokens() >= 1)
|
||||
{
|
||||
val = st.nextToken();
|
||||
}
|
||||
|
||||
if (actualCommand.equalsIgnoreCase("auction"))
|
||||
{
|
||||
if (val.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
int days = Integer.parseInt(val);
|
||||
try
|
||||
{
|
||||
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
|
||||
long bid = 0;
|
||||
if (st.countTokens() >= 1)
|
||||
{
|
||||
bid = Math.min(Long.parseLong(st.nextToken()), MAX_ADENA);
|
||||
}
|
||||
|
||||
Auction a = new Auction(player.getClan().getHideoutId(), player.getClan(), days * 86400000L, bid, ClanHallManager.getInstance().getClanHallByOwner(player.getClan()).getName());
|
||||
if (_pendingAuctions.get(a.getId()) != null)
|
||||
{
|
||||
_pendingAuctions.remove(a.getId());
|
||||
}
|
||||
|
||||
_pendingAuctions.put(a.getId(), a);
|
||||
|
||||
String filename = "data/html/auction/AgitSale3.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%x%", val);
|
||||
html.replace("%AGIT_AUCTION_END%", String.valueOf(format.format(a.getEndDate())));
|
||||
html.replace("%AGIT_AUCTION_MINBID%", String.valueOf(a.getStartingBid()));
|
||||
html.replace("%AGIT_AUCTION_MIN%", String.valueOf(a.getStartingBid()));
|
||||
html.replace("%AGIT_AUCTION_DESC%", ClanHallManager.getInstance().getClanHallByOwner(player.getClan()).getDesc());
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_sale2");
|
||||
html.replace("%objectId%", String.valueOf((getObjectId())));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
player.sendMessage("Invalid bid!");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
player.sendMessage("Invalid auction duration!");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("confirmAuction"))
|
||||
{
|
||||
try
|
||||
{
|
||||
Auction a = _pendingAuctions.get(player.getClan().getHideoutId());
|
||||
a.confirmAuction();
|
||||
_pendingAuctions.remove(player.getClan().getHideoutId());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
player.sendMessage("Invalid auction");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("bidding"))
|
||||
{
|
||||
if (val.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.warning("bidding show successful");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
|
||||
int auctionId = Integer.parseInt(val);
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.warning("auction test started");
|
||||
}
|
||||
|
||||
String filename = "data/html/auction/AgitAuctionInfo.htm";
|
||||
Auction a = AuctionManager.getInstance().getAuction(auctionId);
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
if (a != null)
|
||||
{
|
||||
html.replace("%AGIT_NAME%", a.getItemName());
|
||||
html.replace("%OWNER_PLEDGE_NAME%", a.getSellerClanName());
|
||||
html.replace("%OWNER_PLEDGE_MASTER%", a.getSellerName());
|
||||
html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getGrade() * 10));
|
||||
html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getLease()));
|
||||
html.replace("%AGIT_LOCATION%", ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getLocation());
|
||||
html.replace("%AGIT_AUCTION_END%", String.valueOf(format.format(a.getEndDate())));
|
||||
html.replace("%AGIT_AUCTION_REMAIN%", String.valueOf((a.getEndDate() - System.currentTimeMillis()) / 3600000) + " hours " + String.valueOf((((a.getEndDate() - System.currentTimeMillis()) / 60000) % 60)) + " minutes");
|
||||
html.replace("%AGIT_AUCTION_MINBID%", String.valueOf(a.getStartingBid()));
|
||||
html.replace("%AGIT_AUCTION_COUNT%", String.valueOf(a.getBidders().size()));
|
||||
html.replace("%AGIT_AUCTION_DESC%", ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getDesc());
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_list");
|
||||
html.replace("%AGIT_LINK_BIDLIST%", "bypass -h npc_" + getObjectId() + "_bidlist " + a.getId());
|
||||
html.replace("%AGIT_LINK_RE%", "bypass -h npc_" + getObjectId() + "_bid1 " + a.getId());
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("Auctioneer Auction null for AuctionId : " + auctionId);
|
||||
}
|
||||
|
||||
player.sendPacket(html);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
player.sendMessage("Invalid auction!");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("bid"))
|
||||
{
|
||||
if (val.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
int auctionId = Integer.parseInt(val);
|
||||
try
|
||||
{
|
||||
long bid = 0;
|
||||
if (st.countTokens() >= 1)
|
||||
{
|
||||
bid = Math.min(Long.parseLong(st.nextToken()), MAX_ADENA);
|
||||
}
|
||||
|
||||
AuctionManager.getInstance().getAuction(auctionId).setBid(player, bid);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
player.sendMessage("Invalid bid!");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
player.sendMessage("Invalid auction!");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("bid1"))
|
||||
{
|
||||
if ((player.getClan() == null) || (player.getClan().getLevel() < 2))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.ONLY_A_CLAN_LEADER_WHOSE_CLAN_IS_OF_LEVEL_2_OR_ABOVE_IS_ALLOWED_TO_PARTICIPATE_IN_A_CLAN_HALL_AUCTION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (val.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (((player.getClan().getAuctionBiddedAt() > 0) && (player.getClan().getAuctionBiddedAt() != Integer.parseInt(val))) || (player.getClan().getHideoutId() > 0))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.SINCE_YOU_HAVE_ALREADY_SUBMITTED_A_BID_YOU_ARE_NOT_ALLOWED_TO_PARTICIPATE_IN_ANOTHER_AUCTION_AT_THIS_TIME);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
String filename = "data/html/auction/AgitBid1.htm";
|
||||
|
||||
long minimumBid = AuctionManager.getInstance().getAuction(Integer.parseInt(val)).getHighestBidderMaxBid();
|
||||
if (minimumBid == 0)
|
||||
{
|
||||
minimumBid = AuctionManager.getInstance().getAuction(Integer.parseInt(val)).getStartingBid();
|
||||
}
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_bidding " + val);
|
||||
html.replace("%PLEDGE_ADENA%", String.valueOf(player.getClan().getWarehouse().getAdena()));
|
||||
html.replace("%AGIT_AUCTION_MINBID%", String.valueOf(minimumBid));
|
||||
html.replace("npc_%objectId%_bid", "npc_" + getObjectId() + "_bid " + val);
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
player.sendMessage("Invalid auction!");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("list"))
|
||||
{
|
||||
List<Auction> auctions = AuctionManager.getInstance().getAuctions();
|
||||
SimpleDateFormat format = new SimpleDateFormat("yy/MM/dd");
|
||||
/** Limit for make new page, prevent client crash **/
|
||||
int limit = 15;
|
||||
int start;
|
||||
int i = 1;
|
||||
double npage = Math.ceil((float) auctions.size() / limit);
|
||||
|
||||
if (val.isEmpty())
|
||||
{
|
||||
start = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = (limit * (Integer.parseInt(val) - 1)) + 1;
|
||||
limit *= Integer.parseInt(val);
|
||||
}
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.warning("cmd list: auction test started");
|
||||
}
|
||||
|
||||
StringBuilder items = new StringBuilder();
|
||||
items.append("<table width=280 border=0><tr>");
|
||||
for (int j = 1; j <= npage; j++)
|
||||
{
|
||||
items.append("<td><center><a action=\"bypass -h npc_");
|
||||
items.append(getObjectId());
|
||||
items.append("_list ");
|
||||
items.append(j);
|
||||
items.append("\"> Page ");
|
||||
items.append(j);
|
||||
items.append(" </a></center></td>");
|
||||
}
|
||||
|
||||
items.append("</tr></table>");
|
||||
items.append("<table width=280 border=0>");
|
||||
|
||||
for (Auction a : auctions)
|
||||
{
|
||||
if (a == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i > limit)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (i < start)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
items.append("<tr>");
|
||||
items.append("<td>");
|
||||
items.append(ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getLocation());
|
||||
items.append("</td>");
|
||||
items.append("<td><a action=\"bypass -h npc_");
|
||||
items.append(getObjectId());
|
||||
items.append("_bidding ");
|
||||
items.append(a.getId());
|
||||
items.append("\">");
|
||||
items.append(a.getItemName());
|
||||
items.append("</a></td>");
|
||||
items.append("<td>" + format.format(a.getEndDate()));
|
||||
items.append("</td>");
|
||||
items.append("<td>");
|
||||
items.append(a.getStartingBid());
|
||||
items.append("</td>");
|
||||
items.append("</tr>");
|
||||
}
|
||||
|
||||
items.append("</table>");
|
||||
String filename = "data/html/auction/AgitAuctionList.htm";
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_start");
|
||||
html.replace("%itemsField%", items.toString());
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("bidlist"))
|
||||
{
|
||||
int auctionId = 0;
|
||||
if (val.isEmpty())
|
||||
{
|
||||
if (player.getClan().getAuctionBiddedAt() <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auctionId = player.getClan().getAuctionBiddedAt();
|
||||
}
|
||||
else
|
||||
{
|
||||
auctionId = Integer.parseInt(val);
|
||||
}
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.warning("cmd bidlist: auction test started");
|
||||
}
|
||||
|
||||
String biders = "";
|
||||
Map<Integer, Bidder> bidders = AuctionManager.getInstance().getAuction(auctionId).getBidders();
|
||||
for (Bidder b : bidders.values())
|
||||
{
|
||||
biders += "<tr>" + "<td>" + b.getClanName() + "</td><td>" + b.getName() + "</td><td>" + b.getTimeBid().get(Calendar.YEAR) + "/" + (b.getTimeBid().get(Calendar.MONTH) + 1) + "/" + b.getTimeBid().get(Calendar.DATE) + "</td><td>" + b.getBid() + "</td>" + "</tr>";
|
||||
}
|
||||
String filename = "data/html/auction/AgitBidderList.htm";
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%AGIT_LIST%", biders);
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_selectedItems");
|
||||
html.replace("%x%", val);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("selectedItems"))
|
||||
{
|
||||
if ((player.getClan() != null) && (player.getClan().getHideoutId() == 0) && (player.getClan().getAuctionBiddedAt() > 0))
|
||||
{
|
||||
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
|
||||
String filename = "data/html/auction/AgitBidInfo.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
Auction a = AuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt());
|
||||
if (a != null)
|
||||
{
|
||||
html.replace("%AGIT_NAME%", a.getItemName());
|
||||
html.replace("%OWNER_PLEDGE_NAME%", a.getSellerClanName());
|
||||
html.replace("%OWNER_PLEDGE_MASTER%", a.getSellerName());
|
||||
html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getGrade() * 10));
|
||||
html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getLease()));
|
||||
html.replace("%AGIT_LOCATION%", ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getLocation());
|
||||
html.replace("%AGIT_AUCTION_END%", String.valueOf(format.format(a.getEndDate())));
|
||||
html.replace("%AGIT_AUCTION_REMAIN%", String.valueOf((a.getEndDate() - System.currentTimeMillis()) / 3600000) + " hours " + String.valueOf((((a.getEndDate() - System.currentTimeMillis()) / 60000) % 60)) + " minutes");
|
||||
html.replace("%AGIT_AUCTION_MINBID%", String.valueOf(a.getStartingBid()));
|
||||
html.replace("%AGIT_AUCTION_MYBID%", String.valueOf(a.getBidders().get(player.getClanId()).getBid()));
|
||||
html.replace("%AGIT_AUCTION_DESC%", ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getDesc());
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_start");
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("Auctioneer Auction null for AuctionBiddedAt : " + player.getClan().getAuctionBiddedAt());
|
||||
}
|
||||
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
else if ((player.getClan() != null) && (AuctionManager.getInstance().getAuction(player.getClan().getHideoutId()) != null))
|
||||
{
|
||||
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
|
||||
String filename = "data/html/auction/AgitSaleInfo.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
Auction a = AuctionManager.getInstance().getAuction(player.getClan().getHideoutId());
|
||||
if (a != null)
|
||||
{
|
||||
html.replace("%AGIT_NAME%", a.getItemName());
|
||||
html.replace("%AGIT_OWNER_PLEDGE_NAME%", a.getSellerClanName());
|
||||
html.replace("%OWNER_PLEDGE_MASTER%", a.getSellerName());
|
||||
html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getGrade() * 10));
|
||||
html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getLease()));
|
||||
html.replace("%AGIT_LOCATION%", ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getLocation());
|
||||
html.replace("%AGIT_AUCTION_END%", String.valueOf(format.format(a.getEndDate())));
|
||||
html.replace("%AGIT_AUCTION_REMAIN%", String.valueOf((a.getEndDate() - System.currentTimeMillis()) / 3600000) + " hours " + String.valueOf((((a.getEndDate() - System.currentTimeMillis()) / 60000) % 60)) + " minutes");
|
||||
html.replace("%AGIT_AUCTION_MINBID%", String.valueOf(a.getStartingBid()));
|
||||
html.replace("%AGIT_AUCTION_BIDCOUNT%", String.valueOf(a.getBidders().size()));
|
||||
html.replace("%AGIT_AUCTION_DESC%", ClanHallManager.getInstance().getAuctionableHallById(a.getItemId()).getDesc());
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_start");
|
||||
html.replace("%id%", String.valueOf(a.getId()));
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("Auctioneer Auction null for getHasHideout : " + player.getClan().getHideoutId());
|
||||
}
|
||||
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
else if ((player.getClan() != null) && (player.getClan().getHideoutId() != 0))
|
||||
{
|
||||
int ItemId = player.getClan().getHideoutId();
|
||||
String filename = "data/html/auction/AgitInfo.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
if (ClanHallManager.getInstance().getAuctionableHallById(ItemId) != null)
|
||||
{
|
||||
html.replace("%AGIT_NAME%", ClanHallManager.getInstance().getAuctionableHallById(ItemId).getName());
|
||||
html.replace("%AGIT_OWNER_PLEDGE_NAME%", player.getClan().getName());
|
||||
html.replace("%OWNER_PLEDGE_MASTER%", player.getClan().getLeaderName());
|
||||
html.replace("%AGIT_SIZE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(ItemId).getGrade() * 10));
|
||||
html.replace("%AGIT_LEASE%", String.valueOf(ClanHallManager.getInstance().getAuctionableHallById(ItemId).getLease()));
|
||||
html.replace("%AGIT_LOCATION%", ClanHallManager.getInstance().getAuctionableHallById(ItemId).getLocation());
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_start");
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("Clan Hall ID NULL : " + ItemId + " Can be caused by concurent write in ClanHallManager");
|
||||
}
|
||||
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
else if ((player.getClan() != null) && (player.getClan().getHideoutId() == 0))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THERE_ARE_NO_OFFERINGS_I_OWN_OR_I_MADE_A_BID_FOR);
|
||||
return;
|
||||
}
|
||||
else if (player.getClan() == null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_REQUIREMENTS_TO_PARTICIPATE_IN_AN_AUCTION);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("cancelBid"))
|
||||
{
|
||||
long bid = AuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt()).getBidders().get(player.getClanId()).getBid();
|
||||
String filename = "data/html/auction/AgitBidCancel.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%AGIT_BID%", String.valueOf(bid));
|
||||
html.replace("%AGIT_BID_REMAIN%", String.valueOf((long) (bid * 0.9)));
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_selectedItems");
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("doCancelBid"))
|
||||
{
|
||||
if (AuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt()) != null)
|
||||
{
|
||||
AuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt()).cancelBid(player.getClanId());
|
||||
player.sendPacket(SystemMessageId.YOU_HAVE_CANCELED_YOUR_BID);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("cancelAuction"))
|
||||
{
|
||||
if (!player.hasClanPrivilege(ClanPrivilege.CH_AUCTION))
|
||||
{
|
||||
String filename = "data/html/auction/not_authorized.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
String filename = "data/html/auction/AgitSaleCancel.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%AGIT_DEPOSIT%", String.valueOf(ClanHallManager.getInstance().getClanHallByOwner(player.getClan()).getLease()));
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_selectedItems");
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("doCancelAuction"))
|
||||
{
|
||||
if (AuctionManager.getInstance().getAuction(player.getClan().getHideoutId()) != null)
|
||||
{
|
||||
AuctionManager.getInstance().getAuction(player.getClan().getHideoutId()).cancelAuction();
|
||||
player.sendMessage("Your auction has been canceled");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("sale2"))
|
||||
{
|
||||
String filename = "data/html/auction/AgitSale2.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%AGIT_LAST_PRICE%", String.valueOf(ClanHallManager.getInstance().getClanHallByOwner(player.getClan()).getLease()));
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_sale");
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("sale"))
|
||||
{
|
||||
if (!player.hasClanPrivilege(ClanPrivilege.CH_AUCTION))
|
||||
{
|
||||
String filename = "data/html/auction/not_authorized.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
String filename = "data/html/auction/AgitSale1.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%AGIT_DEPOSIT%", String.valueOf(ClanHallManager.getInstance().getClanHallByOwner(player.getClan()).getLease()));
|
||||
html.replace("%AGIT_PLEDGE_ADENA%", String.valueOf(player.getClan().getWarehouse().getAdena()));
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_selectedItems");
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("rebid"))
|
||||
{
|
||||
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
|
||||
if (!player.hasClanPrivilege(ClanPrivilege.CH_AUCTION))
|
||||
{
|
||||
String filename = "data/html/auction/not_authorized.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
String filename = "data/html/auction/AgitBid2.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
Auction a = AuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt());
|
||||
if (a != null)
|
||||
{
|
||||
html.replace("%AGIT_AUCTION_BID%", String.valueOf(a.getBidders().get(player.getClanId()).getBid()));
|
||||
html.replace("%AGIT_AUCTION_MINBID%", String.valueOf(a.getStartingBid()));
|
||||
html.replace("%AGIT_AUCTION_END%", String.valueOf(format.format(a.getEndDate())));
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_selectedItems");
|
||||
html.replace("npc_%objectId%_bid1", "npc_" + getObjectId() + "_bid1 " + a.getId());
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("Auctioneer Auction null for AuctionBiddedAt : " + player.getClan().getAuctionBiddedAt());
|
||||
}
|
||||
|
||||
player.sendPacket(html);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
player.sendMessage("Invalid auction!");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("location"))
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/auction/location.htm");
|
||||
html.replace("%location%", MapRegionManager.getInstance().getClosestTownName(player));
|
||||
html.replace("%LOCATION%", getPictureName(player));
|
||||
html.replace("%AGIT_LINK_BACK%", "bypass -h npc_" + getObjectId() + "_start");
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("start"))
|
||||
{
|
||||
showChatWindow(player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
super.onBypassFeedback(player, command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showChatWindow(L2PcInstance player)
|
||||
{
|
||||
String filename = "data/html/auction/auction-no.htm";
|
||||
|
||||
int condition = validateCondition(player);
|
||||
if (condition == COND_BUSY_BECAUSE_OF_SIEGE)
|
||||
{
|
||||
filename = "data/html/auction/auction-busy.htm"; // Busy because of siege
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = "data/html/auction/auction.htm";
|
||||
}
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
html.replace("%npcId%", String.valueOf(getId()));
|
||||
html.replace("%npcname%", getName());
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
private int validateCondition(L2PcInstance player)
|
||||
{
|
||||
if ((getCastle() != null) && (getCastle().getResidenceId() > 0))
|
||||
{
|
||||
if (getCastle().getSiege().isInProgress())
|
||||
{
|
||||
return COND_BUSY_BECAUSE_OF_SIEGE; // Busy because of siege
|
||||
}
|
||||
return COND_REGULAR;
|
||||
}
|
||||
|
||||
return COND_ALL_FALSE;
|
||||
}
|
||||
|
||||
private String getPictureName(L2PcInstance plyr)
|
||||
{
|
||||
int nearestTownId = MapRegionManager.getInstance().getMapRegionLocId(plyr);
|
||||
String nearestTown;
|
||||
|
||||
switch (nearestTownId)
|
||||
{
|
||||
case 911:
|
||||
nearestTown = "GLUDIN";
|
||||
break;
|
||||
case 912:
|
||||
nearestTown = "GLUDIO";
|
||||
break;
|
||||
case 916:
|
||||
nearestTown = "DION";
|
||||
break;
|
||||
case 918:
|
||||
nearestTown = "GIRAN";
|
||||
break;
|
||||
case 1537:
|
||||
nearestTown = "RUNE";
|
||||
break;
|
||||
case 1538:
|
||||
nearestTown = "GODARD";
|
||||
break;
|
||||
case 1714:
|
||||
nearestTown = "SCHUTTGART";
|
||||
break;
|
||||
default:
|
||||
nearestTown = "ADEN";
|
||||
break;
|
||||
}
|
||||
|
||||
return nearestTown;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.PetDataTable;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.enums.CategoryType;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.L2PetData.L2PetSkillLearn;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.model.skills.BuffInfo;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jserver.util.Rnd;
|
||||
|
||||
public final class L2BabyPetInstance extends L2PetInstance
|
||||
{
|
||||
private static final int BUFF_CONTROL = 5771;
|
||||
private static final int AWAKENING = 5753;
|
||||
|
||||
protected List<SkillHolder> _buffs = null;
|
||||
protected SkillHolder _majorHeal = null;
|
||||
protected SkillHolder _minorHeal = null;
|
||||
protected SkillHolder _recharge = null;
|
||||
|
||||
private Future<?> _castTask;
|
||||
|
||||
protected boolean _bufferMode = true;
|
||||
|
||||
public L2BabyPetInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, L2ItemInstance control)
|
||||
{
|
||||
super(objectId, template, owner, control);
|
||||
setInstanceType(InstanceType.L2BabyPetInstance);
|
||||
}
|
||||
|
||||
public L2BabyPetInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, L2ItemInstance control, byte level)
|
||||
{
|
||||
super(objectId, template, owner, control, level);
|
||||
setInstanceType(InstanceType.L2BabyPetInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
super.onSpawn();
|
||||
|
||||
double healPower = 0;
|
||||
for (L2PetSkillLearn psl : PetDataTable.getInstance().getPetData(getId()).getAvailableSkills())
|
||||
{
|
||||
int id = psl.getSkillId();
|
||||
int lvl = PetDataTable.getInstance().getPetData(getId()).getAvailableLevel(id, getLevel());
|
||||
if (lvl == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final Skill skill = SkillData.getInstance().getSkill(id, lvl);
|
||||
if (skill == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((skill.getId() == BUFF_CONTROL) || (skill.getId() == AWAKENING))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skill.hasEffectType(L2EffectType.MANAHEAL_BY_LEVEL))
|
||||
{
|
||||
_recharge = new SkillHolder(skill);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skill.hasEffectType(L2EffectType.HEAL))
|
||||
{
|
||||
if (healPower == 0)
|
||||
{
|
||||
// set both heal types to the same skill
|
||||
_majorHeal = new SkillHolder(skill);
|
||||
_minorHeal = _majorHeal;
|
||||
healPower = skill.getPower();
|
||||
}
|
||||
else
|
||||
{
|
||||
// another heal skill found - search for most powerful
|
||||
if (skill.getPower() > healPower)
|
||||
{
|
||||
_majorHeal = new SkillHolder(skill);
|
||||
}
|
||||
else
|
||||
{
|
||||
_minorHeal = new SkillHolder(skill);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skill.isContinuous() && !skill.isDebuff())
|
||||
{
|
||||
if (_buffs == null)
|
||||
{
|
||||
_buffs = new ArrayList<>();
|
||||
}
|
||||
_buffs.add(new SkillHolder(skill));
|
||||
}
|
||||
}
|
||||
startCastTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
stopCastTask();
|
||||
abortCast();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void unSummon(L2PcInstance owner)
|
||||
{
|
||||
stopCastTask();
|
||||
abortCast();
|
||||
super.unSummon(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRevive()
|
||||
{
|
||||
super.doRevive();
|
||||
startCastTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDecay()
|
||||
{
|
||||
super.onDecay();
|
||||
|
||||
if (_buffs != null)
|
||||
{
|
||||
_buffs.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private final void startCastTask()
|
||||
{
|
||||
if ((_majorHeal != null) || (_buffs != null) || ((_recharge != null) && (_castTask == null) && !isDead()))
|
||||
{
|
||||
_castTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new CastTask(this), 3000, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void switchMode()
|
||||
{
|
||||
_bufferMode = !_bufferMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if this pet is in support mode.
|
||||
* @return {@code true} if this baby pet is in support mode, {@code false} otherwise
|
||||
*/
|
||||
public boolean isInSupportMode()
|
||||
{
|
||||
return _bufferMode;
|
||||
}
|
||||
|
||||
private final void stopCastTask()
|
||||
{
|
||||
if (_castTask != null)
|
||||
{
|
||||
_castTask.cancel(false);
|
||||
_castTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void castSkill(Skill skill)
|
||||
{
|
||||
// casting automatically stops any other action (such as autofollow or a move-to).
|
||||
// We need to gather the necessary info to restore the previous state.
|
||||
final boolean previousFollowStatus = getFollowStatus();
|
||||
|
||||
// pet not following and owner outside cast range
|
||||
if (!previousFollowStatus && !isInsideRadius(getOwner(), skill.getCastRange(), true, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
setTarget(getOwner());
|
||||
useMagic(skill, false, false);
|
||||
|
||||
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.YOUR_PET_USES_S1);
|
||||
msg.addSkillName(skill);
|
||||
sendPacket(msg);
|
||||
|
||||
// calling useMagic changes the follow status, if the babypet actually casts
|
||||
// (as opposed to failing due some factors, such as too low MP, etc).
|
||||
// if the status has actually been changed, revert it. Else, allow the pet to
|
||||
// continue whatever it was trying to do.
|
||||
// NOTE: This is important since the pet may have been told to attack a target.
|
||||
// reverting the follow status will abort this attack! While aborting the attack
|
||||
// in order to heal is natural, it is not acceptable to abort the attack on its own,
|
||||
// merely because the timer stroke and without taking any other action...
|
||||
if (previousFollowStatus != getFollowStatus())
|
||||
{
|
||||
setFollowStatus(previousFollowStatus);
|
||||
}
|
||||
}
|
||||
|
||||
private class CastTask implements Runnable
|
||||
{
|
||||
private final L2BabyPetInstance _baby;
|
||||
private final List<Skill> _currentBuffs = new ArrayList<>();
|
||||
|
||||
public CastTask(L2BabyPetInstance baby)
|
||||
{
|
||||
_baby = baby;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
final L2PcInstance owner = _baby.getOwner();
|
||||
// If the owner doesn't meet the conditions avoid casting.
|
||||
if ((owner == null) || owner.isDead() || owner.isInvul())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the pet doesn't meet the conditions avoid casting.
|
||||
if (_baby.isCastingNow() || _baby.isBetrayed() || _baby.isMuted() || _baby.isOutOfControl() || !_bufferMode || (_baby.getAI().getIntention() == CtrlIntention.AI_INTENTION_CAST))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Skill skill = null;
|
||||
if (_majorHeal != null)
|
||||
{
|
||||
// If the owner's HP is more than 80% for Baby Pets and 70% for Improved Baby pets, do nothing.
|
||||
// If the owner's HP is very low, under 15% for Baby pets and under 30% for Improved Baby Pets, have 75% chances of using a strong heal.
|
||||
// Otherwise, have 25% chances for weak heal.
|
||||
final double hpPercent = owner.getCurrentHp() / owner.getMaxHp();
|
||||
final boolean isImprovedBaby = isInCategory(CategoryType.BABY_PET_GROUP);
|
||||
if ((isImprovedBaby && (hpPercent < 0.3)) || (!isImprovedBaby && (hpPercent < 0.15)))
|
||||
{
|
||||
skill = _majorHeal.getSkill();
|
||||
if (!_baby.isSkillDisabled(skill) && (Rnd.get(100) <= 75))
|
||||
{
|
||||
if (_baby.getCurrentMp() >= skill.getMpConsume())
|
||||
{
|
||||
castSkill(skill);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((_majorHeal.getSkill() != _minorHeal.getSkill()) && ((isImprovedBaby && (hpPercent < 0.7)) || (!isImprovedBaby && (hpPercent < 0.8))))
|
||||
{
|
||||
// Cast _minorHeal only if it's different than _majorHeal, then pet has two heals available.
|
||||
skill = _minorHeal.getSkill();
|
||||
if (!_baby.isSkillDisabled(skill) && (Rnd.get(100) <= 25))
|
||||
{
|
||||
if (_baby.getCurrentMp() >= skill.getMpConsume())
|
||||
{
|
||||
castSkill(skill);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Buff Control is not active
|
||||
if (!_baby.isAffectedBySkill(BUFF_CONTROL))
|
||||
{
|
||||
// searching for usable buffs
|
||||
if ((_buffs != null) && !_buffs.isEmpty())
|
||||
{
|
||||
for (SkillHolder buff : _buffs)
|
||||
{
|
||||
skill = buff.getSkill();
|
||||
if (_baby.isSkillDisabled(skill))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_baby.getCurrentMp() < skill.getMpConsume())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// If owner already have the buff, continue.
|
||||
final BuffInfo buffInfo = owner.getEffectList().getBuffInfoByAbnormalType(skill.getAbnormalType());
|
||||
if ((buffInfo != null) && (skill.getAbnormalLvl() <= buffInfo.getSkill().getAbnormalLvl()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// If owner have the buff blocked, continue.
|
||||
if ((owner.getEffectList().getAllBlockedBuffSlots() != null) && owner.getEffectList().getAllBlockedBuffSlots().contains(skill.getAbnormalType()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
_currentBuffs.add(skill);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_currentBuffs.isEmpty())
|
||||
{
|
||||
skill = _currentBuffs.get(Rnd.get(_currentBuffs.size()));
|
||||
castSkill(skill);
|
||||
_currentBuffs.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// buffs/heal not casted, trying recharge, if exist recharge casted only if owner in combat stance.
|
||||
if ((_recharge != null) && owner.isInCombat() && ((owner.getCurrentMp() / owner.getMaxMp()) < 0.6) && (Rnd.get(100) <= 60))
|
||||
{
|
||||
skill = _recharge.getSkill();
|
||||
if (!_baby.isSkillDisabled(skill) && (_baby.getCurrentMp() >= skill.getMpConsume()))
|
||||
{
|
||||
castSkill(skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.datatables.ItemTable;
|
||||
import com.l2jserver.gameserver.model.ArenaParticipantsHolder;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.entity.BlockCheckerEngine;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExCubeGameChangePoints;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExCubeGameExtendedChangePoints;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcInfo;
|
||||
import com.l2jserver.util.Rnd;
|
||||
|
||||
/**
|
||||
* @author BiggBoss
|
||||
*/
|
||||
public class L2BlockInstance extends L2MonsterInstance
|
||||
{
|
||||
private int _colorEffect;
|
||||
|
||||
/**
|
||||
* @param objectId
|
||||
* @param template
|
||||
*/
|
||||
public L2BlockInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will change the color of the block and update the appearance in the known players clients
|
||||
* @param attacker
|
||||
* @param holder
|
||||
* @param team
|
||||
*/
|
||||
public void changeColor(L2PcInstance attacker, ArenaParticipantsHolder holder, int team)
|
||||
{
|
||||
// Do not update color while sending old info
|
||||
synchronized (this)
|
||||
{
|
||||
final BlockCheckerEngine event = holder.getEvent();
|
||||
if (_colorEffect == 0x53)
|
||||
{
|
||||
// Change color
|
||||
_colorEffect = 0x00;
|
||||
// BroadCast to all known players
|
||||
broadcastPacket(new NpcInfo(this));
|
||||
increaseTeamPointsAndSend(attacker, team, event);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Change color
|
||||
_colorEffect = 0x53;
|
||||
// BroadCast to all known players
|
||||
broadcastPacket(new NpcInfo(this));
|
||||
increaseTeamPointsAndSend(attacker, team, event);
|
||||
}
|
||||
// 30% chance to drop the event items
|
||||
int random = Rnd.get(100);
|
||||
// Bond
|
||||
if ((random > 69) && (random <= 84))
|
||||
{
|
||||
dropItem(13787, event, attacker);
|
||||
}
|
||||
else if (random > 84)
|
||||
{
|
||||
dropItem(13788, event, attacker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the block is red or blue. Mainly used in block spawn
|
||||
* @param isRed
|
||||
*/
|
||||
public void setRed(boolean isRed)
|
||||
{
|
||||
_colorEffect = isRed ? 0x53 : 0x00;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the block is red at this moment, {@code false} otherwise
|
||||
*/
|
||||
@Override
|
||||
public int getColorEffect()
|
||||
{
|
||||
return _colorEffect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
if (attacker instanceof L2PcInstance)
|
||||
{
|
||||
return (attacker.getActingPlayer() != null) && (attacker.getActingPlayer().getBlockCheckerArena() > -1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAction(L2PcInstance player, boolean interact)
|
||||
{
|
||||
if (!canTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player.setLastFolkNPC(this);
|
||||
|
||||
if (player.getTarget() != this)
|
||||
{
|
||||
player.setTarget(this);
|
||||
getAI(); // wake up ai
|
||||
}
|
||||
else if (interact)
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
|
||||
private void increaseTeamPointsAndSend(L2PcInstance player, int team, BlockCheckerEngine eng)
|
||||
{
|
||||
eng.increasePlayerPoints(player, team);
|
||||
|
||||
int timeLeft = (int) ((eng.getStarterTime() - System.currentTimeMillis()) / 1000);
|
||||
boolean isRed = eng.getHolder().getRedPlayers().contains(player);
|
||||
|
||||
ExCubeGameChangePoints changePoints = new ExCubeGameChangePoints(timeLeft, eng.getBluePoints(), eng.getRedPoints());
|
||||
ExCubeGameExtendedChangePoints secretPoints = new ExCubeGameExtendedChangePoints(timeLeft, eng.getBluePoints(), eng.getRedPoints(), isRed, player, eng.getPlayerPoints(player, isRed));
|
||||
|
||||
eng.getHolder().broadCastPacketToTeam(changePoints);
|
||||
eng.getHolder().broadCastPacketToTeam(secretPoints);
|
||||
}
|
||||
|
||||
private void dropItem(int id, BlockCheckerEngine eng, L2PcInstance player)
|
||||
{
|
||||
L2ItemInstance drop = ItemTable.getInstance().createItem("Loot", id, 1, player, this);
|
||||
int x = getX() + Rnd.get(50);
|
||||
int y = getY() + Rnd.get(50);
|
||||
int z = getZ();
|
||||
|
||||
drop.dropMe(this, x, y, z);
|
||||
|
||||
eng.addNewDrop(drop);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.gameserver.ai.L2BoatAI;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Vehicle;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.VehicleDeparture;
|
||||
import com.l2jserver.gameserver.network.serverpackets.VehicleInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.VehicleStarted;
|
||||
|
||||
/**
|
||||
* @author Maktakien, DS
|
||||
*/
|
||||
public class L2BoatInstance extends L2Vehicle
|
||||
{
|
||||
protected static final Logger _logBoat = Logger.getLogger(L2BoatInstance.class.getName());
|
||||
|
||||
public L2BoatInstance(int objectId, L2CharTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2BoatInstance);
|
||||
setAI(new L2BoatAI(new AIAccessor()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBoat()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToNextRoutePoint()
|
||||
{
|
||||
final boolean result = super.moveToNextRoutePoint();
|
||||
if (result)
|
||||
{
|
||||
broadcastPacket(new VehicleDeparture(this));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void oustPlayer(L2PcInstance player)
|
||||
{
|
||||
super.oustPlayer(player);
|
||||
|
||||
final Location loc = getOustLoc();
|
||||
if (player.isOnline())
|
||||
{
|
||||
player.teleToLocation(loc.getX(), loc.getY(), loc.getZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setXYZInvisible(loc.getX(), loc.getY(), loc.getZ()); // disconnects handling
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopMove(Location loc, boolean updateKnownObjects)
|
||||
{
|
||||
super.stopMove(loc, updateKnownObjects);
|
||||
|
||||
broadcastPacket(new VehicleStarted(this, 0));
|
||||
broadcastPacket(new VehicleInfo(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendInfo(L2PcInstance activeChar)
|
||||
{
|
||||
activeChar.sendPacket(new VehicleInfo(this));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.ClanPrivilege;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
|
||||
|
||||
public class L2CastleDoormenInstance extends L2DoormenInstance
|
||||
{
|
||||
public L2CastleDoormenInstance(int objectID, L2NpcTemplate template)
|
||||
{
|
||||
super(objectID, template);
|
||||
setInstanceType(InstanceType.L2CastleDoormenInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void openDoors(L2PcInstance player, String command)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(command.substring(10), ", ");
|
||||
st.nextToken();
|
||||
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
if (getConquerableHall() != null)
|
||||
{
|
||||
getConquerableHall().openCloseDoor(Integer.parseInt(st.nextToken()), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
getCastle().openDoor(player, Integer.parseInt(st.nextToken()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void closeDoors(L2PcInstance player, String command)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(command.substring(11), ", ");
|
||||
st.nextToken();
|
||||
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
if (getConquerableHall() != null)
|
||||
{
|
||||
getConquerableHall().openCloseDoor(Integer.parseInt(st.nextToken()), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
getCastle().closeDoor(player, Integer.parseInt(st.nextToken()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean isOwnerClan(L2PcInstance player)
|
||||
{
|
||||
if ((player.getClan() != null) && player.hasClanPrivilege(ClanPrivilege.CS_OPEN_DOOR))
|
||||
{
|
||||
SiegableHall hall = getConquerableHall();
|
||||
// save in variable because it's a costly call
|
||||
if (hall != null)
|
||||
{
|
||||
if (player.getClanId() == hall.getOwnerId())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (getCastle() != null)
|
||||
{
|
||||
if (player.getClanId() == getCastle().getOwnerId())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean isUnderSiege()
|
||||
{
|
||||
SiegableHall hall = getConquerableHall();
|
||||
if (hall != null)
|
||||
{
|
||||
return hall.isInSiege();
|
||||
}
|
||||
return getCastle().getZone().isActive();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.datatables.NpcData;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
/**
|
||||
* This class manages all chest.
|
||||
* @author Julian
|
||||
*/
|
||||
public final class L2ChestInstance extends L2MonsterInstance
|
||||
{
|
||||
private volatile boolean _specialDrop;
|
||||
|
||||
public L2ChestInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2ChestInstance);
|
||||
setIsNoRndWalk(true);
|
||||
_specialDrop = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
super.onSpawn();
|
||||
_specialDrop = false;
|
||||
setMustRewardExpSp(true);
|
||||
}
|
||||
|
||||
public synchronized void setSpecialDrop()
|
||||
{
|
||||
_specialDrop = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doItemDrop(L2NpcTemplate npcTemplate, L2Character lastAttacker)
|
||||
{
|
||||
int id = getTemplate().getId();
|
||||
|
||||
if (!_specialDrop)
|
||||
{
|
||||
if ((id >= 18265) && (id <= 18286))
|
||||
{
|
||||
id += 3536;
|
||||
}
|
||||
else if ((id == 18287) || (id == 18288))
|
||||
{
|
||||
id = 21671;
|
||||
}
|
||||
else if ((id == 18289) || (id == 18290))
|
||||
{
|
||||
id = 21694;
|
||||
}
|
||||
else if ((id == 18291) || (id == 18292))
|
||||
{
|
||||
id = 21717;
|
||||
}
|
||||
else if ((id == 18293) || (id == 18294))
|
||||
{
|
||||
id = 21740;
|
||||
}
|
||||
else if ((id == 18295) || (id == 18296))
|
||||
{
|
||||
id = 21763;
|
||||
}
|
||||
else if ((id == 18297) || (id == 18298))
|
||||
{
|
||||
id = 21786;
|
||||
}
|
||||
}
|
||||
super.doItemDrop(NpcData.getInstance().getTemplate(id), lastAttacker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMovementDisabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRandomAnimation()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jserver.gameserver.datatables.ClanTable;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.ClanHallManager;
|
||||
import com.l2jserver.gameserver.model.L2Clan;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.entity.ClanHall;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jserver.gameserver.util.Evolve;
|
||||
|
||||
public class L2ClanHallDoormenInstance extends L2DoormenInstance
|
||||
{
|
||||
private volatile boolean _init = false;
|
||||
private ClanHall _clanHall = null;
|
||||
private boolean _hasEvolve = false;
|
||||
|
||||
// list of clan halls with evolve function, should be sorted
|
||||
private static final int[] CH_WITH_EVOLVE =
|
||||
{
|
||||
36,
|
||||
37,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
51,
|
||||
52,
|
||||
53,
|
||||
54,
|
||||
55,
|
||||
56,
|
||||
57
|
||||
};
|
||||
|
||||
public L2ClanHallDoormenInstance(int objectID, L2NpcTemplate template)
|
||||
{
|
||||
super(objectID, template);
|
||||
setInstanceType(InstanceType.L2ClanHallDoormenInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
if (_hasEvolve && command.startsWith("evolve"))
|
||||
{
|
||||
if (isOwnerClan(player))
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(command, " ");
|
||||
if (st.countTokens() < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
st.nextToken();
|
||||
boolean ok = false;
|
||||
switch (Integer.parseInt(st.nextToken()))
|
||||
{
|
||||
case 1:
|
||||
ok = Evolve.doEvolve(player, this, 9882, 10307, 55);
|
||||
break;
|
||||
case 2:
|
||||
ok = Evolve.doEvolve(player, this, 4422, 10308, 55);
|
||||
break;
|
||||
case 3:
|
||||
ok = Evolve.doEvolve(player, this, 4423, 10309, 55);
|
||||
break;
|
||||
case 4:
|
||||
ok = Evolve.doEvolve(player, this, 4424, 10310, 55);
|
||||
break;
|
||||
case 5:
|
||||
ok = Evolve.doEvolve(player, this, 10426, 10611, 70);
|
||||
break;
|
||||
}
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
if (ok)
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/clanHallDoormen/evolve-ok.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/clanHallDoormen/evolve-no.htm");
|
||||
}
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
}
|
||||
super.onBypassFeedback(player, command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showChatWindow(L2PcInstance player)
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
|
||||
if (getClanHall() != null)
|
||||
{
|
||||
L2Clan owner = ClanTable.getInstance().getClan(getClanHall().getOwnerId());
|
||||
if (isOwnerClan(player))
|
||||
{
|
||||
if (_hasEvolve)
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/clanHallDoormen/doormen2.htm");
|
||||
html.replace("%clanname%", owner.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/clanHallDoormen/doormen1.htm");
|
||||
html.replace("%clanname%", owner.getName());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((owner != null) && (owner.getLeader() != null))
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/clanHallDoormen/doormen-no.htm");
|
||||
html.replace("%leadername%", owner.getLeaderName());
|
||||
html.replace("%clanname%", owner.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/clanHallDoormen/emptyowner.htm");
|
||||
html.replace("%hallname%", getClanHall().getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void openDoors(L2PcInstance player, String command)
|
||||
{
|
||||
getClanHall().openCloseDoors(true);
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/clanHallDoormen/doormen-opened.htm");
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void closeDoors(L2PcInstance player, String command)
|
||||
{
|
||||
getClanHall().openCloseDoors(false);
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/clanHallDoormen/doormen-closed.htm");
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
private final ClanHall getClanHall()
|
||||
{
|
||||
if (!_init)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (!_init)
|
||||
{
|
||||
_clanHall = ClanHallManager.getInstance().getNearbyClanHall(getX(), getY(), 500);
|
||||
if (_clanHall != null)
|
||||
{
|
||||
_hasEvolve = Arrays.binarySearch(CH_WITH_EVOLVE, _clanHall.getId()) >= 0;
|
||||
}
|
||||
_init = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _clanHall;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean isOwnerClan(L2PcInstance player)
|
||||
{
|
||||
if ((player.getClan() != null) && (getClanHall() != null))
|
||||
{
|
||||
if (player.getClanId() == getClanHall().getOwnerId())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.cache.HtmCache;
|
||||
import com.l2jserver.gameserver.datatables.ClassListData;
|
||||
import com.l2jserver.gameserver.datatables.ItemTable;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
import com.l2jserver.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jserver.gameserver.network.serverpackets.TutorialCloseHtml;
|
||||
import com.l2jserver.gameserver.network.serverpackets.TutorialShowHtml;
|
||||
import com.l2jserver.gameserver.network.serverpackets.TutorialShowQuestionMark;
|
||||
import com.l2jserver.gameserver.network.serverpackets.UserInfo;
|
||||
import com.l2jserver.util.StringUtil;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision: 1.4.2.1.2.7 $ $Date: 2005/03/27 15:29:32 $
|
||||
*/
|
||||
public final class L2ClassMasterInstance extends L2MerchantInstance
|
||||
{
|
||||
/**
|
||||
* @param objectId
|
||||
* @param template
|
||||
*/
|
||||
public L2ClassMasterInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2ClassMasterInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "data/html/classmaster/" + pom + ".htm";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
if (command.startsWith("1stClass"))
|
||||
{
|
||||
showHtmlMenu(player, getObjectId(), 1);
|
||||
}
|
||||
else if (command.startsWith("2ndClass"))
|
||||
{
|
||||
showHtmlMenu(player, getObjectId(), 2);
|
||||
}
|
||||
else if (command.startsWith("3rdClass"))
|
||||
{
|
||||
showHtmlMenu(player, getObjectId(), 3);
|
||||
}
|
||||
else if (command.startsWith("change_class"))
|
||||
{
|
||||
int val = Integer.parseInt(command.substring(13));
|
||||
|
||||
if (checkAndChangeClass(player, val))
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/classmaster/ok.htm");
|
||||
html.replace("%name%", ClassListData.getInstance().getClass(val).getClientCode());
|
||||
player.sendPacket(html);
|
||||
}
|
||||
}
|
||||
else if (command.startsWith("become_noble"))
|
||||
{
|
||||
if (!player.isNoble())
|
||||
{
|
||||
player.setNoble(true);
|
||||
player.sendPacket(new UserInfo(player));
|
||||
player.sendPacket(new ExBrExtraUserInfo(player));
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/classmaster/nobleok.htm");
|
||||
player.sendPacket(html);
|
||||
}
|
||||
}
|
||||
else if (command.startsWith("learn_skills"))
|
||||
{
|
||||
player.giveAvailableSkills(Config.AUTO_LEARN_FS_SKILLS, true);
|
||||
}
|
||||
else if (command.startsWith("increase_clan_level"))
|
||||
{
|
||||
if (!player.isClanLeader())
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/classmaster/noclanleader.htm");
|
||||
player.sendPacket(html);
|
||||
}
|
||||
else if (player.getClan().getLevel() >= 5)
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/classmaster/noclanlevel.htm");
|
||||
player.sendPacket(html);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.getClan().changeLevel(5);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onBypassFeedback(player, command);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void onTutorialLink(L2PcInstance player, String request)
|
||||
{
|
||||
if (!Config.ALTERNATE_CLASS_MASTER || (request == null) || !request.startsWith("CO"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.getFloodProtectors().getServerBypass().tryPerformAction("changeclass"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
int val = Integer.parseInt(request.substring(2));
|
||||
checkAndChangeClass(player, val);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
}
|
||||
player.sendPacket(TutorialCloseHtml.STATIC_PACKET);
|
||||
}
|
||||
|
||||
public static final void onTutorialQuestionMark(L2PcInstance player, int number)
|
||||
{
|
||||
if (!Config.ALTERNATE_CLASS_MASTER || (number != 1001))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
showTutorialHtml(player);
|
||||
}
|
||||
|
||||
public static final void showQuestionMark(L2PcInstance player)
|
||||
{
|
||||
if (!Config.ALTERNATE_CLASS_MASTER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final ClassId classId = player.getClassId();
|
||||
if (getMinLevel(classId.level()) > player.getLevel())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Config.CLASS_MASTER_SETTINGS.isAllowed(classId.level() + 1))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player.sendPacket(new TutorialShowQuestionMark(1001));
|
||||
}
|
||||
|
||||
private static final void showHtmlMenu(L2PcInstance player, int objectId, int level)
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(objectId);
|
||||
|
||||
if (!Config.ALLOW_CLASS_MASTERS)
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/classmaster/disabled.htm");
|
||||
}
|
||||
else if (!Config.CLASS_MASTER_SETTINGS.isAllowed(level))
|
||||
{
|
||||
final int jobLevel = player.getClassId().level();
|
||||
final StringBuilder sb = new StringBuilder(100);
|
||||
sb.append("<html><body>");
|
||||
switch (jobLevel)
|
||||
{
|
||||
case 0:
|
||||
if (Config.CLASS_MASTER_SETTINGS.isAllowed(1))
|
||||
{
|
||||
sb.append("Come back here when you reached level 20 to change your class.<br>");
|
||||
}
|
||||
else if (Config.CLASS_MASTER_SETTINGS.isAllowed(2))
|
||||
{
|
||||
sb.append("Come back after your first occupation change.<br>");
|
||||
}
|
||||
else if (Config.CLASS_MASTER_SETTINGS.isAllowed(3))
|
||||
{
|
||||
sb.append("Come back after your second occupation change.<br>");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("I can't change your occupation.<br>");
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (Config.CLASS_MASTER_SETTINGS.isAllowed(2))
|
||||
{
|
||||
sb.append("Come back here when you reached level 40 to change your class.<br>");
|
||||
}
|
||||
else if (Config.CLASS_MASTER_SETTINGS.isAllowed(3))
|
||||
{
|
||||
sb.append("Come back after your second occupation change.<br>");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("I can't change your occupation.<br>");
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (Config.CLASS_MASTER_SETTINGS.isAllowed(3))
|
||||
{
|
||||
sb.append("Come back here when you reached level 76 to change your class.<br>");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("I can't change your occupation.<br>");
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
sb.append("There is no class change available for you anymore.<br>");
|
||||
break;
|
||||
}
|
||||
sb.append("</body></html>");
|
||||
html.setHtml(sb.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
final ClassId currentClassId = player.getClassId();
|
||||
if (currentClassId.level() >= level)
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/classmaster/nomore.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
final int minLevel = getMinLevel(currentClassId.level());
|
||||
if ((player.getLevel() >= minLevel) || Config.ALLOW_ENTIRE_TREE)
|
||||
{
|
||||
final StringBuilder menu = new StringBuilder(100);
|
||||
for (ClassId cid : ClassId.values())
|
||||
{
|
||||
if ((cid == ClassId.INSPECTOR) && (player.getTotalSubClasses() < 2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (validateClassId(currentClassId, cid) && (cid.level() == level))
|
||||
{
|
||||
StringUtil.append(menu, "<a action=\"bypass -h npc_%objectId%_change_class ", String.valueOf(cid.getId()), "\">", ClassListData.getInstance().getClass(cid).getClientCode(), "</a><br>");
|
||||
}
|
||||
}
|
||||
|
||||
if (menu.length() > 0)
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/classmaster/template.htm");
|
||||
html.replace("%name%", ClassListData.getInstance().getClass(currentClassId).getClientCode());
|
||||
html.replace("%menu%", menu.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/classmaster/comebacklater.htm");
|
||||
html.replace("%level%", String.valueOf(getMinLevel(level - 1)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (minLevel < Integer.MAX_VALUE)
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/classmaster/comebacklater.htm");
|
||||
html.replace("%level%", String.valueOf(minLevel));
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/classmaster/nomore.htm");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
html.replace("%objectId%", String.valueOf(objectId));
|
||||
html.replace("%req_items%", getRequiredItems(level));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
private static final void showTutorialHtml(L2PcInstance player)
|
||||
{
|
||||
final ClassId currentClassId = player.getClassId();
|
||||
if ((getMinLevel(currentClassId.level()) > player.getLevel()) && !Config.ALLOW_ENTIRE_TREE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String msg = HtmCache.getInstance().getHtm(player.getHtmlPrefix(), "data/html/classmaster/tutorialtemplate.htm");
|
||||
msg = msg.replaceAll("%name%", ClassListData.getInstance().getClass(currentClassId).getEscapedClientCode());
|
||||
|
||||
final StringBuilder menu = new StringBuilder(100);
|
||||
for (ClassId cid : ClassId.values())
|
||||
{
|
||||
if ((cid == ClassId.INSPECTOR) && (player.getTotalSubClasses() < 2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (validateClassId(currentClassId, cid))
|
||||
{
|
||||
StringUtil.append(menu, "<a action=\"link CO", String.valueOf(cid.getId()), "\">", ClassListData.getInstance().getClass(cid).getEscapedClientCode(), "</a><br>");
|
||||
}
|
||||
}
|
||||
|
||||
msg = msg.replaceAll("%menu%", menu.toString());
|
||||
msg = msg.replace("%req_items%", getRequiredItems(currentClassId.level() + 1));
|
||||
player.sendPacket(new TutorialShowHtml(msg));
|
||||
}
|
||||
|
||||
private static final boolean checkAndChangeClass(L2PcInstance player, int val)
|
||||
{
|
||||
final ClassId currentClassId = player.getClassId();
|
||||
if ((getMinLevel(currentClassId.level()) > player.getLevel()) && !Config.ALLOW_ENTIRE_TREE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!validateClassId(currentClassId, val))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final int newJobLevel = currentClassId.level() + 1;
|
||||
|
||||
// Weight/Inventory check
|
||||
if (!Config.CLASS_MASTER_SETTINGS.getRewardItems(newJobLevel).isEmpty() && !player.isInventoryUnder90(false))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.UNABLE_TO_PROCESS_THIS_REQUEST_UNTIL_YOUR_INVENTORY_S_WEIGHT_AND_SLOT_COUNT_ARE_LESS_THAN_80_PERCENT_OF_CAPACITY);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if player have all required items for class transfer
|
||||
for (ItemHolder holder : Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel))
|
||||
{
|
||||
if (player.getInventory().getInventoryItemCount(holder.getId(), -1) < holder.getCount())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.INCORRECT_ITEM_COUNT2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// get all required items for class transfer
|
||||
for (ItemHolder holder : Config.CLASS_MASTER_SETTINGS.getRequireItems(newJobLevel))
|
||||
{
|
||||
if (!player.destroyItemByItemId("ClassMaster", holder.getId(), holder.getCount(), player, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// reward player with items
|
||||
for (ItemHolder holder : Config.CLASS_MASTER_SETTINGS.getRewardItems(newJobLevel))
|
||||
{
|
||||
player.addItem("ClassMaster", holder.getId(), holder.getCount(), player, true);
|
||||
}
|
||||
|
||||
player.setClassId(val);
|
||||
|
||||
if (player.isSubClassActive())
|
||||
{
|
||||
player.getSubClasses().get(player.getClassIndex()).setClassId(player.getActiveClass());
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setBaseClass(player.getActiveClass());
|
||||
}
|
||||
|
||||
player.broadcastUserInfo();
|
||||
|
||||
if (Config.CLASS_MASTER_SETTINGS.isAllowed(player.getClassId().level() + 1) && Config.ALTERNATE_CLASS_MASTER && (((player.getClassId().level() == 1) && (player.getLevel() >= 40)) || ((player.getClassId().level() == 2) && (player.getLevel() >= 76))))
|
||||
{
|
||||
showQuestionMark(player);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param level - current skillId level (0 - start, 1 - first, etc)
|
||||
* @return minimum player level required for next class transfer
|
||||
*/
|
||||
private static final int getMinLevel(int level)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
return 20;
|
||||
case 1:
|
||||
return 40;
|
||||
case 2:
|
||||
return 76;
|
||||
default:
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if class change is possible
|
||||
* @param oldCID current player ClassId
|
||||
* @param val new class index
|
||||
* @return
|
||||
*/
|
||||
private static final boolean validateClassId(ClassId oldCID, int val)
|
||||
{
|
||||
return validateClassId(oldCID, ClassId.getClassId(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if class change is possible
|
||||
* @param oldCID current player ClassId
|
||||
* @param newCID new ClassId
|
||||
* @return true if class change is possible
|
||||
*/
|
||||
private static final boolean validateClassId(ClassId oldCID, ClassId newCID)
|
||||
{
|
||||
if ((newCID == null) || (newCID.getRace() == null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (oldCID.equals(newCID.getParent()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Config.ALLOW_ENTIRE_TREE && newCID.childOf(oldCID))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String getRequiredItems(int level)
|
||||
{
|
||||
if ((Config.CLASS_MASTER_SETTINGS.getRequireItems(level) == null) || Config.CLASS_MASTER_SETTINGS.getRequireItems(level).isEmpty())
|
||||
{
|
||||
return "<tr><td>none</td></tr>";
|
||||
}
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (ItemHolder holder : Config.CLASS_MASTER_SETTINGS.getRequireItems(level))
|
||||
{
|
||||
sb.append("<tr><td><font color=\"LEVEL\">" + holder.getCount() + "</font></td><td>" + ItemTable.getInstance().getTemplate(holder.getId()).getName() + "</td></tr>");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.L2Spawn;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Tower;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
/**
|
||||
* Class for Control Tower instance.
|
||||
*/
|
||||
public class L2ControlTowerInstance extends L2Tower
|
||||
{
|
||||
private volatile List<L2Spawn> _guards;
|
||||
|
||||
public L2ControlTowerInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2ControlTowerInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (getCastle().getSiege().isInProgress())
|
||||
{
|
||||
getCastle().getSiege().killedCT(this);
|
||||
|
||||
if ((_guards != null) && !_guards.isEmpty())
|
||||
{
|
||||
for (L2Spawn spawn : _guards)
|
||||
{
|
||||
if (spawn == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
spawn.stopRespawn();
|
||||
// spawn.getLastSpawn().doDie(spawn.getLastSpawn());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Error at L2ControlTowerInstance", e);
|
||||
}
|
||||
}
|
||||
_guards.clear();
|
||||
}
|
||||
}
|
||||
return super.doDie(killer);
|
||||
}
|
||||
|
||||
public void registerGuard(L2Spawn guard)
|
||||
{
|
||||
getGuards().add(guard);
|
||||
}
|
||||
|
||||
private final List<L2Spawn> getGuards()
|
||||
{
|
||||
if (_guards == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_guards == null)
|
||||
{
|
||||
_guards = new FastList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return _guards;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.model.actor.stat.ControllableAirShipStat;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.DeleteObject;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
public class L2ControllableAirShipInstance extends L2AirShipInstance
|
||||
{
|
||||
private static final int HELM = 13556;
|
||||
private static final int LOW_FUEL = 40;
|
||||
|
||||
private int _fuel = 0;
|
||||
private int _maxFuel = 0;
|
||||
|
||||
private final int _ownerId;
|
||||
private int _helmId;
|
||||
private L2PcInstance _captain = null;
|
||||
|
||||
private Future<?> _consumeFuelTask;
|
||||
private Future<?> _checkTask;
|
||||
|
||||
public L2ControllableAirShipInstance(int objectId, L2CharTemplate template, int ownerId)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2ControllableAirShipInstance);
|
||||
_ownerId = ownerId;
|
||||
_helmId = IdFactory.getInstance().getNextId(); // not forget to release !
|
||||
}
|
||||
|
||||
@Override
|
||||
public ControllableAirShipStat getStat()
|
||||
{
|
||||
return (ControllableAirShipStat) super.getStat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initCharStat()
|
||||
{
|
||||
setStat(new ControllableAirShipStat(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeControlled()
|
||||
{
|
||||
return super.canBeControlled() && !isInDock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOwner(L2PcInstance player)
|
||||
{
|
||||
if (_ownerId == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (player.getClanId() == _ownerId) || (player.getObjectId() == _ownerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOwnerId()
|
||||
{
|
||||
return _ownerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCaptain(L2PcInstance player)
|
||||
{
|
||||
return (_captain != null) && (player == _captain);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCaptainId()
|
||||
{
|
||||
return _captain != null ? _captain.getObjectId() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHelmObjectId()
|
||||
{
|
||||
return _helmId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHelmItemId()
|
||||
{
|
||||
return HELM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setCaptain(L2PcInstance player)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
_captain = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((_captain == null) && (player.getAirShip() == this))
|
||||
{
|
||||
final int x = player.getInVehiclePosition().getX() - 0x16e;
|
||||
final int y = player.getInVehiclePosition().getY();
|
||||
final int z = player.getInVehiclePosition().getZ() - 0x6b;
|
||||
if (((x * x) + (y * y) + (z * z)) > 2500)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_CONTROL_BECAUSE_YOU_ARE_TOO_FAR);
|
||||
return false;
|
||||
}
|
||||
// TODO: Missing message ID: 2739 Message: You cannot control the helm because you do not meet the requirements.
|
||||
else if (player.isInCombat())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_IN_A_BATTLE);
|
||||
return false;
|
||||
}
|
||||
else if (player.isSitting())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_IN_A_SITTING_POSITION);
|
||||
return false;
|
||||
}
|
||||
else if (player.isParalyzed())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_YOU_ARE_PETRIFIED);
|
||||
return false;
|
||||
}
|
||||
else if (player.isCursedWeaponEquipped())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_A_CURSED_WEAPON_IS_EQUIPPED);
|
||||
return false;
|
||||
}
|
||||
else if (player.isFishing())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_FISHING);
|
||||
return false;
|
||||
}
|
||||
else if (player.isDead() || player.isFakeDeath())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHEN_YOU_ARE_DEAD);
|
||||
return false;
|
||||
}
|
||||
else if (player.isCastingNow())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_USING_A_SKILL);
|
||||
return false;
|
||||
}
|
||||
else if (player.isTransformed())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_TRANSFORMED);
|
||||
return false;
|
||||
}
|
||||
else if (player.isCombatFlagEquipped())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_HOLDING_A_FLAG);
|
||||
return false;
|
||||
}
|
||||
else if (player.isInDuel())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_IN_A_DUEL);
|
||||
return false;
|
||||
}
|
||||
_captain = player;
|
||||
player.broadcastUserInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
updateAbnormalEffect();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFuel()
|
||||
{
|
||||
return _fuel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFuel(int f)
|
||||
{
|
||||
|
||||
final int old = _fuel;
|
||||
if (f < 0)
|
||||
{
|
||||
_fuel = 0;
|
||||
}
|
||||
else if (f > _maxFuel)
|
||||
{
|
||||
_fuel = _maxFuel;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fuel = f;
|
||||
}
|
||||
|
||||
if ((_fuel == 0) && (old > 0))
|
||||
{
|
||||
broadcastToPassengers(SystemMessage.getSystemMessage(SystemMessageId.THE_AIRSHIP_S_FUEL_EP_HAS_RUN_OUT_THE_AIRSHIP_S_SPEED_WILL_BE_GREATLY_DECREASED_IN_THIS_CONDITION));
|
||||
}
|
||||
else if (_fuel < LOW_FUEL)
|
||||
{
|
||||
broadcastToPassengers(SystemMessage.getSystemMessage(SystemMessageId.THE_AIRSHIP_S_FUEL_EP_WILL_SOON_RUN_OUT));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxFuel()
|
||||
{
|
||||
return _maxFuel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxFuel(int mf)
|
||||
{
|
||||
_maxFuel = mf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void oustPlayer(L2PcInstance player)
|
||||
{
|
||||
if (player == _captain)
|
||||
{
|
||||
setCaptain(null); // no need to broadcast userinfo here
|
||||
}
|
||||
|
||||
super.oustPlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
super.onSpawn();
|
||||
_checkTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new CheckTask(), 60000, 10000);
|
||||
_consumeFuelTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new ConsumeFuelTask(), 60000, 60000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteMe()
|
||||
{
|
||||
if (!super.deleteMe())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_checkTask != null)
|
||||
{
|
||||
_checkTask.cancel(false);
|
||||
_checkTask = null;
|
||||
}
|
||||
if (_consumeFuelTask != null)
|
||||
{
|
||||
_consumeFuelTask.cancel(false);
|
||||
_consumeFuelTask = null;
|
||||
}
|
||||
|
||||
broadcastPacket(new DeleteObject(_helmId));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshID()
|
||||
{
|
||||
super.refreshID();
|
||||
IdFactory.getInstance().releaseId(_helmId);
|
||||
_helmId = IdFactory.getInstance().getNextId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendInfo(L2PcInstance activeChar)
|
||||
{
|
||||
super.sendInfo(activeChar);
|
||||
if (_captain != null)
|
||||
{
|
||||
_captain.sendInfo(activeChar);
|
||||
}
|
||||
}
|
||||
|
||||
protected final class ConsumeFuelTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
int fuel = getFuel();
|
||||
if (fuel > 0)
|
||||
{
|
||||
fuel -= 10;
|
||||
if (fuel < 0)
|
||||
{
|
||||
fuel = 0;
|
||||
}
|
||||
|
||||
setFuel(fuel);
|
||||
updateAbnormalEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected final class CheckTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (isVisible() && isEmpty() && !isInDock())
|
||||
{
|
||||
// deleteMe() can't be called from CheckTask because task should not cancel itself
|
||||
ThreadPoolManager.getInstance().executeGeneral(new DecayTask());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected final class DecayTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
deleteMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.ai.L2CharacterAI;
|
||||
import com.l2jserver.gameserver.ai.L2ControllableMobAI;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
/**
|
||||
* @author littlecrow
|
||||
*/
|
||||
public class L2ControllableMobInstance extends L2MonsterInstance
|
||||
{
|
||||
private boolean _isInvul;
|
||||
|
||||
protected class ControllableAIAcessor extends AIAccessor
|
||||
{
|
||||
@Override
|
||||
public void detachAI()
|
||||
{
|
||||
// do nothing, AI of controllable mobs can't be detached automatically
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAggressive()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAggroRange()
|
||||
{
|
||||
// force mobs to be aggro
|
||||
return 500;
|
||||
}
|
||||
|
||||
public L2ControllableMobInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2ControllableMobInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected L2CharacterAI initAI()
|
||||
{
|
||||
return new L2ControllableMobAI(new ControllableAIAcessor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInvul()
|
||||
{
|
||||
return _isInvul;
|
||||
}
|
||||
|
||||
public void setInvul(boolean isInvul)
|
||||
{
|
||||
_isInvul = isInvul;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
setAI(null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,782 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.ai.CtrlEvent;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.instancemanager.DuelManager;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.L2Party;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.tasks.cubics.CubicAction;
|
||||
import com.l2jserver.gameserver.model.actor.tasks.cubics.CubicDisappear;
|
||||
import com.l2jserver.gameserver.model.actor.tasks.cubics.CubicHeal;
|
||||
import com.l2jserver.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jserver.gameserver.model.entity.TvTEvent;
|
||||
import com.l2jserver.gameserver.model.entity.TvTEventTeam;
|
||||
import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.stats.Formulas;
|
||||
import com.l2jserver.gameserver.model.stats.Stats;
|
||||
import com.l2jserver.gameserver.model.zone.ZoneId;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.util.Rnd;
|
||||
|
||||
public final class L2CubicInstance implements IIdentifiable
|
||||
{
|
||||
private static final Logger _log = Logger.getLogger(L2CubicInstance.class.getName());
|
||||
|
||||
// Type of Cubics
|
||||
public static final int STORM_CUBIC = 1;
|
||||
public static final int VAMPIRIC_CUBIC = 2;
|
||||
public static final int LIFE_CUBIC = 3;
|
||||
public static final int VIPER_CUBIC = 4;
|
||||
public static final int POLTERGEIST_CUBIC = 5;
|
||||
public static final int BINDING_CUBIC = 6;
|
||||
public static final int AQUA_CUBIC = 7;
|
||||
public static final int SPARK_CUBIC = 8;
|
||||
public static final int ATTRACT_CUBIC = 9;
|
||||
public static final int SMART_CUBIC_EVATEMPLAR = 10;
|
||||
public static final int SMART_CUBIC_SHILLIENTEMPLAR = 11;
|
||||
public static final int SMART_CUBIC_ARCANALORD = 12;
|
||||
public static final int SMART_CUBIC_ELEMENTALMASTER = 13;
|
||||
public static final int SMART_CUBIC_SPECTRALMASTER = 14;
|
||||
|
||||
// Max range of cubic skills
|
||||
// TODO: Check/fix the max range
|
||||
public static final int MAX_MAGIC_RANGE = 900;
|
||||
|
||||
// Cubic skills
|
||||
public static final int SKILL_CUBIC_HEAL = 4051;
|
||||
public static final int SKILL_CUBIC_CURE = 5579;
|
||||
|
||||
private final L2PcInstance _owner;
|
||||
private L2Character _target;
|
||||
|
||||
private final int _cubicId;
|
||||
private final int _cubicPower;
|
||||
private final int _cubicDelay;
|
||||
private final int _cubicSkillChance;
|
||||
private final int _cubicMaxCount;
|
||||
private boolean _active;
|
||||
private final boolean _givenByOther;
|
||||
|
||||
private final List<Skill> _skills = new ArrayList<>();
|
||||
|
||||
private Future<?> _disappearTask;
|
||||
private Future<?> _actionTask;
|
||||
|
||||
public L2CubicInstance(L2PcInstance owner, int cubicId, int level, int cubicPower, int cubicDelay, int cubicSkillChance, int cubicMaxCount, int cubicDuration, boolean givenByOther)
|
||||
{
|
||||
_owner = owner;
|
||||
_cubicId = cubicId;
|
||||
_cubicPower = cubicPower;
|
||||
_cubicDelay = cubicDelay * 1000;
|
||||
_cubicSkillChance = cubicSkillChance;
|
||||
_cubicMaxCount = cubicMaxCount;
|
||||
_active = false;
|
||||
_givenByOther = givenByOther;
|
||||
|
||||
switch (_cubicId)
|
||||
{
|
||||
case STORM_CUBIC:
|
||||
_skills.add(SkillData.getInstance().getSkill(4049, level));
|
||||
break;
|
||||
case VAMPIRIC_CUBIC:
|
||||
_skills.add(SkillData.getInstance().getSkill(4050, level));
|
||||
break;
|
||||
case LIFE_CUBIC:
|
||||
_skills.add(SkillData.getInstance().getSkill(4051, level));
|
||||
doAction();
|
||||
break;
|
||||
case VIPER_CUBIC:
|
||||
_skills.add(SkillData.getInstance().getSkill(4052, level));
|
||||
break;
|
||||
case POLTERGEIST_CUBIC:
|
||||
_skills.add(SkillData.getInstance().getSkill(4053, level));
|
||||
_skills.add(SkillData.getInstance().getSkill(4054, level));
|
||||
_skills.add(SkillData.getInstance().getSkill(4055, level));
|
||||
break;
|
||||
case BINDING_CUBIC:
|
||||
_skills.add(SkillData.getInstance().getSkill(4164, level));
|
||||
break;
|
||||
case AQUA_CUBIC:
|
||||
_skills.add(SkillData.getInstance().getSkill(4165, level));
|
||||
break;
|
||||
case SPARK_CUBIC:
|
||||
_skills.add(SkillData.getInstance().getSkill(4166, level));
|
||||
break;
|
||||
case ATTRACT_CUBIC:
|
||||
_skills.add(SkillData.getInstance().getSkill(5115, level));
|
||||
_skills.add(SkillData.getInstance().getSkill(5116, level));
|
||||
break;
|
||||
case SMART_CUBIC_ARCANALORD:
|
||||
_skills.add(SkillData.getInstance().getSkill(4051, 7));
|
||||
_skills.add(SkillData.getInstance().getSkill(4165, 9));
|
||||
break;
|
||||
case SMART_CUBIC_ELEMENTALMASTER:
|
||||
_skills.add(SkillData.getInstance().getSkill(4049, 8));
|
||||
_skills.add(SkillData.getInstance().getSkill(4166, 9));
|
||||
break;
|
||||
case SMART_CUBIC_SPECTRALMASTER:
|
||||
_skills.add(SkillData.getInstance().getSkill(4049, 8));
|
||||
_skills.add(SkillData.getInstance().getSkill(4052, 6));
|
||||
break;
|
||||
case SMART_CUBIC_EVATEMPLAR:
|
||||
_skills.add(SkillData.getInstance().getSkill(4053, 8));
|
||||
_skills.add(SkillData.getInstance().getSkill(4165, 9));
|
||||
break;
|
||||
case SMART_CUBIC_SHILLIENTEMPLAR:
|
||||
_skills.add(SkillData.getInstance().getSkill(4049, 8));
|
||||
_skills.add(SkillData.getInstance().getSkill(5115, 4));
|
||||
break;
|
||||
}
|
||||
_disappearTask = ThreadPoolManager.getInstance().scheduleGeneral(new CubicDisappear(this), cubicDuration * 1000); // disappear
|
||||
}
|
||||
|
||||
public synchronized void doAction()
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_active = true;
|
||||
|
||||
switch (_cubicId)
|
||||
{
|
||||
case AQUA_CUBIC:
|
||||
case BINDING_CUBIC:
|
||||
case SPARK_CUBIC:
|
||||
case STORM_CUBIC:
|
||||
case POLTERGEIST_CUBIC:
|
||||
case VAMPIRIC_CUBIC:
|
||||
case VIPER_CUBIC:
|
||||
case ATTRACT_CUBIC:
|
||||
case SMART_CUBIC_ARCANALORD:
|
||||
case SMART_CUBIC_ELEMENTALMASTER:
|
||||
case SMART_CUBIC_SPECTRALMASTER:
|
||||
case SMART_CUBIC_EVATEMPLAR:
|
||||
case SMART_CUBIC_SHILLIENTEMPLAR:
|
||||
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new CubicAction(this, _cubicSkillChance), 0, _cubicDelay);
|
||||
break;
|
||||
case LIFE_CUBIC:
|
||||
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new CubicHeal(this), 0, _cubicDelay);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId()
|
||||
{
|
||||
return _cubicId;
|
||||
}
|
||||
|
||||
public L2PcInstance getOwner()
|
||||
{
|
||||
return _owner;
|
||||
}
|
||||
|
||||
public int getCubicPower()
|
||||
{
|
||||
return _cubicPower;
|
||||
}
|
||||
|
||||
public L2Character getTarget()
|
||||
{
|
||||
return _target;
|
||||
}
|
||||
|
||||
public void setTarget(L2Character target)
|
||||
{
|
||||
_target = target;
|
||||
}
|
||||
|
||||
public List<Skill> getSkills()
|
||||
{
|
||||
return _skills;
|
||||
}
|
||||
|
||||
public int getCubicMaxCount()
|
||||
{
|
||||
return _cubicMaxCount;
|
||||
}
|
||||
|
||||
public void stopAction()
|
||||
{
|
||||
_target = null;
|
||||
if (_actionTask != null)
|
||||
{
|
||||
_actionTask.cancel(true);
|
||||
_actionTask = null;
|
||||
}
|
||||
_active = false;
|
||||
}
|
||||
|
||||
public void cancelDisappear()
|
||||
{
|
||||
if (_disappearTask != null)
|
||||
{
|
||||
_disappearTask.cancel(true);
|
||||
_disappearTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
/** this sets the enemy target for a cubic */
|
||||
public void getCubicTarget()
|
||||
{
|
||||
try
|
||||
{
|
||||
_target = null;
|
||||
L2Object ownerTarget = _owner.getTarget();
|
||||
if (ownerTarget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// TvT event targeting
|
||||
if (TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(_owner.getObjectId()))
|
||||
{
|
||||
TvTEventTeam enemyTeam = TvTEvent.getParticipantEnemyTeam(_owner.getObjectId());
|
||||
|
||||
if (ownerTarget.getActingPlayer() != null)
|
||||
{
|
||||
L2PcInstance target = ownerTarget.getActingPlayer();
|
||||
if (enemyTeam.containsPlayer(target.getObjectId()) && !(target.isDead()))
|
||||
{
|
||||
_target = (L2Character) ownerTarget;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Duel targeting
|
||||
if (_owner.isInDuel())
|
||||
{
|
||||
L2PcInstance PlayerA = DuelManager.getInstance().getDuel(_owner.getDuelId()).getPlayerA();
|
||||
L2PcInstance PlayerB = DuelManager.getInstance().getDuel(_owner.getDuelId()).getPlayerB();
|
||||
|
||||
if (DuelManager.getInstance().getDuel(_owner.getDuelId()).isPartyDuel())
|
||||
{
|
||||
L2Party partyA = PlayerA.getParty();
|
||||
L2Party partyB = PlayerB.getParty();
|
||||
L2Party partyEnemy = null;
|
||||
|
||||
if (partyA != null)
|
||||
{
|
||||
if (partyA.getMembers().contains(_owner))
|
||||
{
|
||||
if (partyB != null)
|
||||
{
|
||||
partyEnemy = partyB;
|
||||
}
|
||||
else
|
||||
{
|
||||
_target = PlayerB;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
partyEnemy = partyA;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PlayerA == _owner)
|
||||
{
|
||||
if (partyB != null)
|
||||
{
|
||||
partyEnemy = partyB;
|
||||
}
|
||||
else
|
||||
{
|
||||
_target = PlayerB;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_target = PlayerA;
|
||||
}
|
||||
}
|
||||
if ((_target == PlayerA) || (_target == PlayerB))
|
||||
{
|
||||
if (_target == ownerTarget)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (partyEnemy != null)
|
||||
{
|
||||
if (partyEnemy.getMembers().contains(ownerTarget))
|
||||
{
|
||||
_target = (L2Character) ownerTarget;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((PlayerA != _owner) && (ownerTarget == PlayerA))
|
||||
{
|
||||
_target = PlayerA;
|
||||
return;
|
||||
}
|
||||
if ((PlayerB != _owner) && (ownerTarget == PlayerB))
|
||||
{
|
||||
_target = PlayerB;
|
||||
return;
|
||||
}
|
||||
_target = null;
|
||||
return;
|
||||
}
|
||||
// Olympiad targeting
|
||||
if (_owner.isInOlympiadMode())
|
||||
{
|
||||
if (_owner.isOlympiadStart())
|
||||
{
|
||||
if (ownerTarget instanceof L2Playable)
|
||||
{
|
||||
final L2PcInstance targetPlayer = ownerTarget.getActingPlayer();
|
||||
if ((targetPlayer != null) && (targetPlayer.getOlympiadGameId() == _owner.getOlympiadGameId()) && (targetPlayer.getOlympiadSide() != _owner.getOlympiadSide()))
|
||||
{
|
||||
_target = (L2Character) ownerTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// test owners target if it is valid then use it
|
||||
if ((ownerTarget instanceof L2Character) && (ownerTarget != _owner.getSummon()) && (ownerTarget != _owner))
|
||||
{
|
||||
// target mob which has aggro on you or your summon
|
||||
if (ownerTarget instanceof L2Attackable)
|
||||
{
|
||||
if ((((L2Attackable) ownerTarget).getAggroList().get(_owner) != null) && !((L2Attackable) ownerTarget).isDead())
|
||||
{
|
||||
_target = (L2Character) ownerTarget;
|
||||
return;
|
||||
}
|
||||
if (_owner.hasSummon())
|
||||
{
|
||||
if ((((L2Attackable) ownerTarget).getAggroList().get(_owner.getSummon()) != null) && !((L2Attackable) ownerTarget).isDead())
|
||||
{
|
||||
_target = (L2Character) ownerTarget;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get target in pvp or in siege
|
||||
L2PcInstance enemy = null;
|
||||
|
||||
if (((_owner.getPvpFlag() > 0) && !_owner.isInsideZone(ZoneId.PEACE)) || _owner.isInsideZone(ZoneId.PVP))
|
||||
{
|
||||
if (!((L2Character) ownerTarget).isDead())
|
||||
{
|
||||
enemy = ownerTarget.getActingPlayer();
|
||||
}
|
||||
|
||||
if (enemy != null)
|
||||
{
|
||||
boolean targetIt = true;
|
||||
|
||||
if (_owner.getParty() != null)
|
||||
{
|
||||
if (_owner.getParty().getMembers().contains(enemy))
|
||||
{
|
||||
targetIt = false;
|
||||
}
|
||||
else if (_owner.getParty().getCommandChannel() != null)
|
||||
{
|
||||
if (_owner.getParty().getCommandChannel().getMembers().contains(enemy))
|
||||
{
|
||||
targetIt = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((_owner.getClan() != null) && !_owner.isInsideZone(ZoneId.PVP))
|
||||
{
|
||||
if (_owner.getClan().isMember(enemy.getObjectId()))
|
||||
{
|
||||
targetIt = false;
|
||||
}
|
||||
if ((_owner.getAllyId() > 0) && (enemy.getAllyId() > 0))
|
||||
{
|
||||
if (_owner.getAllyId() == enemy.getAllyId())
|
||||
{
|
||||
targetIt = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((enemy.getPvpFlag() == 0) && !enemy.isInsideZone(ZoneId.PVP))
|
||||
{
|
||||
targetIt = false;
|
||||
}
|
||||
if (enemy.isInsideZone(ZoneId.PEACE))
|
||||
{
|
||||
targetIt = false;
|
||||
}
|
||||
if ((_owner.getSiegeState() > 0) && (_owner.getSiegeState() == enemy.getSiegeState()))
|
||||
{
|
||||
targetIt = false;
|
||||
}
|
||||
if (!enemy.isVisible())
|
||||
{
|
||||
targetIt = false;
|
||||
}
|
||||
|
||||
if (targetIt)
|
||||
{
|
||||
_target = enemy;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void useCubicContinuous(Skill skill, L2Object[] targets)
|
||||
{
|
||||
for (L2Character target : (L2Character[]) targets)
|
||||
{
|
||||
if ((target == null) || target.isDead())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skill.isBad())
|
||||
{
|
||||
byte shld = Formulas.calcShldUse(getOwner(), target, skill);
|
||||
boolean acted = Formulas.calcCubicSkillSuccess(this, target, skill, shld);
|
||||
if (!acted)
|
||||
{
|
||||
getOwner().sendPacket(SystemMessageId.YOUR_ATTACK_HAS_FAILED);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Apply effects
|
||||
skill.applyEffects(getOwner(), this, target, false, false, true, 0);
|
||||
|
||||
// If this is a bad skill notify the duel manager, so it can be removed after the duel (player & target must be in the same duel).
|
||||
if (target.isPlayer() && target.getActingPlayer().isInDuel() && skill.isBad() && (getOwner().getDuelId() == target.getActingPlayer().getDuelId()))
|
||||
{
|
||||
DuelManager.getInstance().onBuff(target.getActingPlayer(), skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param activeCubic
|
||||
* @param skill
|
||||
* @param targets
|
||||
*/
|
||||
public void useCubicMdam(L2CubicInstance activeCubic, Skill skill, L2Object[] targets)
|
||||
{
|
||||
for (L2Character target : (L2Character[]) targets)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
if (target.isPlayer())
|
||||
{
|
||||
target.stopFakeDeath(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
boolean mcrit = Formulas.calcMCrit(activeCubic.getOwner().getMCriticalHit(target, skill));
|
||||
byte shld = Formulas.calcShldUse(activeCubic.getOwner(), target, skill);
|
||||
int damage = (int) Formulas.calcMagicDam(activeCubic, target, skill, mcrit, shld);
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("L2SkillMdam: useCubicSkill() -> damage = " + damage);
|
||||
}
|
||||
|
||||
if (damage > 0)
|
||||
{
|
||||
// Manage attack or cast break of the target (calculating rate, sending message...)
|
||||
if (!target.isRaid() && Formulas.calcAtkBreak(target, damage))
|
||||
{
|
||||
target.breakAttack();
|
||||
target.breakCast();
|
||||
}
|
||||
|
||||
// Shield Deflect Magic: If target is reflecting the skill then no damage is done.
|
||||
if (target.getStat().calcStat(Stats.VENGEANCE_SKILL_MAGIC_DAMAGE, 0, target, skill) > Rnd.get(100))
|
||||
{
|
||||
damage = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
activeCubic.getOwner().sendDamageMessage(target, damage, mcrit, false, false);
|
||||
target.reduceCurrentHp(damage, activeCubic.getOwner(), skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void useCubicDrain(L2CubicInstance activeCubic, Skill skill, L2Object[] targets)
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("L2SkillDrain: useCubicSkill()");
|
||||
}
|
||||
|
||||
for (L2Character target : (L2Character[]) targets)
|
||||
{
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean mcrit = Formulas.calcMCrit(activeCubic.getOwner().getMCriticalHit(target, skill));
|
||||
byte shld = Formulas.calcShldUse(activeCubic.getOwner(), target, skill);
|
||||
|
||||
int damage = (int) Formulas.calcMagicDam(activeCubic, target, skill, mcrit, shld);
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("L2SkillDrain: useCubicSkill() -> damage = " + damage);
|
||||
}
|
||||
|
||||
// TODO: Unhardcode fixed value
|
||||
double hpAdd = (0.4 * damage);
|
||||
L2PcInstance owner = activeCubic.getOwner();
|
||||
double hp = ((owner.getCurrentHp() + hpAdd) > owner.getMaxHp() ? owner.getMaxHp() : (owner.getCurrentHp() + hpAdd));
|
||||
|
||||
owner.setCurrentHp(hp);
|
||||
|
||||
// Check to see if we should damage the target
|
||||
if ((damage > 0) && !target.isDead())
|
||||
{
|
||||
target.reduceCurrentHp(damage, activeCubic.getOwner(), skill);
|
||||
|
||||
// Manage attack or cast break of the target (calculating rate, sending message...)
|
||||
if (!target.isRaid() && Formulas.calcAtkBreak(target, damage))
|
||||
{
|
||||
target.breakAttack();
|
||||
target.breakCast();
|
||||
}
|
||||
owner.sendDamageMessage(target, damage, mcrit, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void useCubicDisabler(Skill skill, L2Object[] targets)
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Disablers: useCubicSkill()");
|
||||
}
|
||||
|
||||
for (L2Character target : (L2Character[]) targets)
|
||||
{
|
||||
if ((target == null) || target.isDead())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
byte shld = Formulas.calcShldUse(getOwner(), target, skill);
|
||||
|
||||
if (skill.hasEffectType(L2EffectType.STUN, L2EffectType.PARALYZE, L2EffectType.ROOT))
|
||||
{
|
||||
if (Formulas.calcCubicSkillSuccess(this, target, skill, shld))
|
||||
{
|
||||
// Apply effects
|
||||
skill.applyEffects(getOwner(), this, target, false, false, true, 0);
|
||||
|
||||
// If this is a bad skill notify the duel manager, so it can be removed after the duel (player & target must be in the same duel).
|
||||
if (target.isPlayer() && target.getActingPlayer().isInDuel() && skill.isBad() && (getOwner().getDuelId() == target.getActingPlayer().getDuelId()))
|
||||
{
|
||||
DuelManager.getInstance().onBuff(target.getActingPlayer(), skill);
|
||||
}
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Disablers: useCubicSkill() -> success");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Disablers: useCubicSkill() -> failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (skill.hasEffectType(L2EffectType.AGGRESSION))
|
||||
{
|
||||
if (Formulas.calcCubicSkillSuccess(this, target, skill, shld))
|
||||
{
|
||||
if (target.isAttackable())
|
||||
{
|
||||
target.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, getOwner(), (int) ((150 * skill.getPower()) / (target.getLevel() + 7)));
|
||||
}
|
||||
|
||||
// Apply effects
|
||||
skill.applyEffects(getOwner(), this, target, false, false, true, 0);
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Disablers: useCubicSkill() -> success");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Disablers: useCubicSkill() -> failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param owner
|
||||
* @param target
|
||||
* @return true if the target is inside of the owner's max Cubic range
|
||||
*/
|
||||
public static boolean isInCubicRange(L2Character owner, L2Character target)
|
||||
{
|
||||
if ((owner == null) || (target == null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int x, y, z;
|
||||
// temporary range check until real behavior of cubics is known/coded
|
||||
int range = MAX_MAGIC_RANGE;
|
||||
|
||||
x = (owner.getX() - target.getX());
|
||||
y = (owner.getY() - target.getY());
|
||||
z = (owner.getZ() - target.getZ());
|
||||
|
||||
return (((x * x) + (y * y) + (z * z)) <= (range * range));
|
||||
}
|
||||
|
||||
/** this sets the friendly target for a cubic */
|
||||
public void cubicTargetForHeal()
|
||||
{
|
||||
L2Character target = null;
|
||||
double percentleft = 100.0;
|
||||
L2Party party = _owner.getParty();
|
||||
|
||||
// if owner is in a duel but not in a party duel, then it is the same as he does not have a party
|
||||
if (_owner.isInDuel())
|
||||
{
|
||||
if (!DuelManager.getInstance().getDuel(_owner.getDuelId()).isPartyDuel())
|
||||
{
|
||||
party = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ((party != null) && !_owner.isInOlympiadMode())
|
||||
{
|
||||
// Get all visible objects in a spheric area near the L2Character
|
||||
// Get a list of Party Members
|
||||
for (L2Character partyMember : party.getMembers())
|
||||
{
|
||||
if (!partyMember.isDead())
|
||||
{
|
||||
// if party member not dead, check if he is in cast range of heal cubic
|
||||
if (isInCubicRange(_owner, partyMember))
|
||||
{
|
||||
// member is in cubic casting range, check if he need heal and if he have
|
||||
// the lowest HP
|
||||
if (partyMember.getCurrentHp() < partyMember.getMaxHp())
|
||||
{
|
||||
if (percentleft > (partyMember.getCurrentHp() / partyMember.getMaxHp()))
|
||||
{
|
||||
percentleft = (partyMember.getCurrentHp() / partyMember.getMaxHp());
|
||||
target = partyMember;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (partyMember.getSummon() != null)
|
||||
{
|
||||
if (partyMember.getSummon().isDead())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// If party member's pet not dead, check if it is in cast range of heal cubic.
|
||||
if (!isInCubicRange(_owner, partyMember.getSummon()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// member's pet is in cubic casting range, check if he need heal and if he have
|
||||
// the lowest HP
|
||||
if (partyMember.getSummon().getCurrentHp() < partyMember.getSummon().getMaxHp())
|
||||
{
|
||||
if (percentleft > (partyMember.getSummon().getCurrentHp() / partyMember.getSummon().getMaxHp()))
|
||||
{
|
||||
percentleft = (partyMember.getSummon().getCurrentHp() / partyMember.getSummon().getMaxHp());
|
||||
target = partyMember.getSummon();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_owner.getCurrentHp() < _owner.getMaxHp())
|
||||
{
|
||||
percentleft = (_owner.getCurrentHp() / _owner.getMaxHp());
|
||||
target = _owner;
|
||||
}
|
||||
if (_owner.hasSummon())
|
||||
{
|
||||
if (!_owner.getSummon().isDead() && (_owner.getSummon().getCurrentHp() < _owner.getSummon().getMaxHp()) && (percentleft > (_owner.getSummon().getCurrentHp() / _owner.getSummon().getMaxHp())) && isInCubicRange(_owner, _owner.getSummon()))
|
||||
{
|
||||
target = _owner.getSummon();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_target = target;
|
||||
}
|
||||
|
||||
public boolean givenByOther()
|
||||
{
|
||||
return _givenByOther;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Decoy;
|
||||
import com.l2jserver.gameserver.model.actor.knownlist.DecoyKnownList;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.taskmanager.DecayTaskManager;
|
||||
|
||||
public class L2DecoyInstance extends L2Decoy
|
||||
{
|
||||
private int _totalLifeTime;
|
||||
private int _timeRemaining;
|
||||
private Future<?> _DecoyLifeTask;
|
||||
private Future<?> _HateSpam;
|
||||
|
||||
public L2DecoyInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, int totalLifeTime)
|
||||
{
|
||||
super(objectId, template, owner);
|
||||
setInstanceType(InstanceType.L2DecoyInstance);
|
||||
_totalLifeTime = totalLifeTime;
|
||||
_timeRemaining = _totalLifeTime;
|
||||
int skilllevel = getTemplate().getDisplayId() - 13070;
|
||||
_DecoyLifeTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new DecoyLifetime(getOwner(), this), 1000, 1000);
|
||||
_HateSpam = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new HateSpam(this, SkillData.getInstance().getSkill(5272, skilllevel)), 2000, 5000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (_HateSpam != null)
|
||||
{
|
||||
_HateSpam.cancel(true);
|
||||
_HateSpam = null;
|
||||
}
|
||||
_totalLifeTime = 0;
|
||||
DecayTaskManager.getInstance().add(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DecoyKnownList getKnownList()
|
||||
{
|
||||
return (DecoyKnownList) super.getKnownList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initKnownList()
|
||||
{
|
||||
setKnownList(new DecoyKnownList(this));
|
||||
}
|
||||
|
||||
static class DecoyLifetime implements Runnable
|
||||
{
|
||||
private final L2PcInstance _activeChar;
|
||||
|
||||
private final L2DecoyInstance _Decoy;
|
||||
|
||||
DecoyLifetime(L2PcInstance activeChar, L2DecoyInstance Decoy)
|
||||
{
|
||||
_activeChar = activeChar;
|
||||
_Decoy = Decoy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
_Decoy.decTimeRemaining(1000);
|
||||
double newTimeRemaining = _Decoy.getTimeRemaining();
|
||||
if (newTimeRemaining < 0)
|
||||
{
|
||||
_Decoy.unSummon(_activeChar);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Decoy Error: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class HateSpam implements Runnable
|
||||
{
|
||||
private final L2DecoyInstance _activeChar;
|
||||
private final Skill _skill;
|
||||
|
||||
HateSpam(L2DecoyInstance activeChar, Skill Hate)
|
||||
{
|
||||
_activeChar = activeChar;
|
||||
_skill = Hate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
_activeChar.setTarget(_activeChar);
|
||||
_activeChar.doCast(_skill);
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Decoy Error: ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unSummon(L2PcInstance owner)
|
||||
{
|
||||
if (_DecoyLifeTask != null)
|
||||
{
|
||||
_DecoyLifeTask.cancel(true);
|
||||
_DecoyLifeTask = null;
|
||||
}
|
||||
if (_HateSpam != null)
|
||||
{
|
||||
_HateSpam.cancel(true);
|
||||
_HateSpam = null;
|
||||
}
|
||||
super.unSummon(owner);
|
||||
}
|
||||
|
||||
public void decTimeRemaining(int value)
|
||||
{
|
||||
_timeRemaining -= value;
|
||||
}
|
||||
|
||||
public int getTimeRemaining()
|
||||
{
|
||||
return _timeRemaining;
|
||||
}
|
||||
|
||||
public int getTotalLifeTime()
|
||||
{
|
||||
return _totalLifeTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.ai.L2CharacterAI;
|
||||
import com.l2jserver.gameserver.ai.L2FortSiegeGuardAI;
|
||||
import com.l2jserver.gameserver.ai.L2SiegeGuardAI;
|
||||
import com.l2jserver.gameserver.ai.L2SpecialSiegeGuardAI;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jserver.gameserver.instancemanager.FortManager;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.knownlist.DefenderKnownList;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.entity.Castle;
|
||||
import com.l2jserver.gameserver.model.entity.Fort;
|
||||
import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
|
||||
public class L2DefenderInstance extends L2Attackable
|
||||
{
|
||||
private Castle _castle = null; // the castle which the instance should defend
|
||||
private Fort _fort = null; // the fortress which the instance should defend
|
||||
private SiegableHall _hall = null; // the siegable hall which the instance should defend
|
||||
|
||||
public L2DefenderInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2DefenderInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefenderKnownList getKnownList()
|
||||
{
|
||||
return (DefenderKnownList) super.getKnownList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initKnownList()
|
||||
{
|
||||
setKnownList(new DefenderKnownList(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected L2CharacterAI initAI()
|
||||
{
|
||||
if ((getConquerableHall() == null) && (getCastle(10000) == null))
|
||||
{
|
||||
return new L2FortSiegeGuardAI(new AIAccessor());
|
||||
}
|
||||
else if (getCastle(10000) != null)
|
||||
{
|
||||
return new L2SiegeGuardAI(new AIAccessor());
|
||||
}
|
||||
return new L2SpecialSiegeGuardAI(new AIAccessor());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return True if a siege is in progress and the L2Character attacker isn't a Defender.
|
||||
* @param attacker The L2Character that the L2SiegeGuardInstance try to attack
|
||||
*/
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
// Attackable during siege by all except defenders
|
||||
if (!(attacker instanceof L2Playable))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
L2PcInstance player = attacker.getActingPlayer();
|
||||
|
||||
// Check if siege is in progress
|
||||
if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive()) || ((_hall != null) && _hall.getSiegeZone().isActive()))
|
||||
{
|
||||
int activeSiegeId = (_fort != null ? _fort.getResidenceId() : (_castle != null ? _castle.getResidenceId() : (_hall != null ? _hall.getId() : 0)));
|
||||
|
||||
// Check if player is an enemy of this defender npc
|
||||
if ((player != null) && (((player.getSiegeState() == 2) && !player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)) || (player.getSiegeState() == 0)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRandomAnimation()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method forces guard to return to home location previously set
|
||||
*/
|
||||
@Override
|
||||
public void returnHome()
|
||||
{
|
||||
if (getWalkSpeed() <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (getSpawn() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!isInsideRadius(getSpawn(), 40, false, false))
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info(getObjectId() + ": moving home");
|
||||
}
|
||||
setisReturningToSpawnPoint(true);
|
||||
clearAggroList();
|
||||
|
||||
if (hasAI())
|
||||
{
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, getSpawn().getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
super.onSpawn();
|
||||
|
||||
_fort = FortManager.getInstance().getFort(getX(), getY(), getZ());
|
||||
_castle = CastleManager.getInstance().getCastle(getX(), getY(), getZ());
|
||||
_hall = getConquerableHall();
|
||||
if ((_fort == null) && (_castle == null) && (_hall == null))
|
||||
{
|
||||
_log.warning("L2DefenderInstance spawned outside of Fortress, Castle or Siegable hall Zone! NpcId: " + getId() + " x=" + getX() + " y=" + getY() + " z=" + getZ());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom onAction behaviour. Note that super() is not called because guards need extra check to see if a player should interact or ATTACK them when clicked.
|
||||
*/
|
||||
@Override
|
||||
public void onAction(L2PcInstance player, boolean interact)
|
||||
{
|
||||
if (!canTarget(player))
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the L2PcInstance already target the L2NpcInstance
|
||||
if (this != player.getTarget())
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("new target selected:" + getObjectId());
|
||||
}
|
||||
|
||||
// Set the target of the L2PcInstance player
|
||||
player.setTarget(this);
|
||||
}
|
||||
else if (interact)
|
||||
{
|
||||
if (isAutoAttackable(player) && !isAlikeDead())
|
||||
{
|
||||
if (Math.abs(player.getZ() - getZ()) < 600) // this max heigth difference might need some tweaking
|
||||
{
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
|
||||
}
|
||||
}
|
||||
if (!isAutoAttackable(player))
|
||||
{
|
||||
if (!canInteract(player))
|
||||
{
|
||||
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDamageHate(L2Character attacker, int damage, int aggro)
|
||||
{
|
||||
if (attacker == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(attacker instanceof L2DefenderInstance))
|
||||
{
|
||||
if ((damage == 0) && (aggro <= 1) && (attacker instanceof L2Playable))
|
||||
{
|
||||
L2PcInstance player = attacker.getActingPlayer();
|
||||
// Check if siege is in progress
|
||||
if (((_fort != null) && _fort.getZone().isActive()) || ((_castle != null) && _castle.getZone().isActive()) || ((_hall != null) && _hall.getSiegeZone().isActive()))
|
||||
{
|
||||
int activeSiegeId = (_fort != null ? _fort.getResidenceId() : (_castle != null ? _castle.getResidenceId() : (_hall != null ? _hall.getId() : 0)));
|
||||
if ((player != null) && (((player.getSiegeState() == 2) && player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1))))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
super.addDamageHate(attacker, damage, aggro);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,812 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.ai.L2CharacterAI;
|
||||
import com.l2jserver.gameserver.ai.L2DoorAI;
|
||||
import com.l2jserver.gameserver.datatables.DoorTable;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.enums.Race;
|
||||
import com.l2jserver.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jserver.gameserver.instancemanager.ClanHallManager;
|
||||
import com.l2jserver.gameserver.instancemanager.FortManager;
|
||||
import com.l2jserver.gameserver.instancemanager.InstanceManager;
|
||||
import com.l2jserver.gameserver.model.L2Clan;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.knownlist.DoorKnownList;
|
||||
import com.l2jserver.gameserver.model.actor.stat.DoorStat;
|
||||
import com.l2jserver.gameserver.model.actor.status.DoorStatus;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2DoorTemplate;
|
||||
import com.l2jserver.gameserver.model.entity.Castle;
|
||||
import com.l2jserver.gameserver.model.entity.ClanHall;
|
||||
import com.l2jserver.gameserver.model.entity.Fort;
|
||||
import com.l2jserver.gameserver.model.entity.Instance;
|
||||
import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
|
||||
import com.l2jserver.gameserver.model.items.L2Weapon;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.DoorStatusUpdate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.OnEventTrigger;
|
||||
import com.l2jserver.gameserver.network.serverpackets.StaticObject;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jserver.util.Rnd;
|
||||
|
||||
public class L2DoorInstance extends L2Character
|
||||
{
|
||||
public static final byte OPEN_BY_CLICK = 1;
|
||||
public static final byte OPEN_BY_TIME = 2;
|
||||
public static final byte OPEN_BY_ITEM = 4;
|
||||
public static final byte OPEN_BY_SKILL = 8;
|
||||
public static final byte OPEN_BY_CYCLE = 16;
|
||||
|
||||
/** The castle index in the array of L2Castle this L2NpcInstance belongs to */
|
||||
private int _castleIndex = -2;
|
||||
/** The fort index in the array of L2Fort this L2NpcInstance belongs to */
|
||||
private int _fortIndex = -2;
|
||||
private ClanHall _clanHall;
|
||||
private boolean _open = false;
|
||||
private boolean _isAttackableDoor = false;
|
||||
private boolean _isTargetable;
|
||||
private int _meshindex = 1;
|
||||
// used for autoclose on open
|
||||
private Future<?> _autoCloseTask;
|
||||
|
||||
/**
|
||||
* @param objectId
|
||||
* @param template
|
||||
*/
|
||||
public L2DoorInstance(int objectId, L2DoorTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2DoorInstance);
|
||||
setIsInvul(false);
|
||||
setLethalable(false);
|
||||
_open = template.isOpenByDefault();
|
||||
_isAttackableDoor = template.isAttackable();
|
||||
_isTargetable = template.isTargetable();
|
||||
|
||||
if (getGroupName() != null)
|
||||
{
|
||||
DoorTable.addDoorGroup(getGroupName(), getId());
|
||||
}
|
||||
|
||||
if (isOpenableByTime())
|
||||
{
|
||||
startTimerOpen();
|
||||
}
|
||||
|
||||
int clanhallId = template.getClanHallId();
|
||||
if (clanhallId > 0)
|
||||
{
|
||||
ClanHall hall = ClanHallManager.getAllClanHalls().get(clanhallId);
|
||||
if (hall != null)
|
||||
{
|
||||
setClanHall(hall);
|
||||
hall.getDoors().add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** This class may be created only by L2Character and only for AI */
|
||||
public class AIAccessor extends L2Character.AIAccessor
|
||||
{
|
||||
@Override
|
||||
public L2DoorInstance getActor()
|
||||
{
|
||||
return L2DoorInstance.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveTo(int x, int y, int z, int offset)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveTo(int x, int y, int z)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopMove(Location loc)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAttack(L2Character target)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCast(Skill skill)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected L2CharacterAI initAI()
|
||||
{
|
||||
return new L2DoorAI(new AIAccessor());
|
||||
}
|
||||
|
||||
private void startTimerOpen()
|
||||
{
|
||||
int delay = _open ? getTemplate().getOpenTime() : getTemplate().getCloseTime();
|
||||
if (getTemplate().getRandomTime() > 0)
|
||||
{
|
||||
delay += Rnd.get(getTemplate().getRandomTime());
|
||||
}
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new TimerOpen(), delay * 1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final DoorKnownList getKnownList()
|
||||
{
|
||||
return (DoorKnownList) super.getKnownList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initKnownList()
|
||||
{
|
||||
setKnownList(new DoorKnownList(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2DoorTemplate getTemplate()
|
||||
{
|
||||
return (L2DoorTemplate) super.getTemplate();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final DoorStatus getStatus()
|
||||
{
|
||||
return (DoorStatus) super.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initCharStatus()
|
||||
{
|
||||
setStatus(new DoorStatus(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initCharStat()
|
||||
{
|
||||
setStat(new DoorStat(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public DoorStat getStat()
|
||||
{
|
||||
return (DoorStat) super.getStat();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if door is open-able by skill.
|
||||
*/
|
||||
public final boolean isOpenableBySkill()
|
||||
{
|
||||
return (getTemplate().getOpenType() & OPEN_BY_SKILL) == OPEN_BY_SKILL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if door is open-able by item.
|
||||
*/
|
||||
public final boolean isOpenableByItem()
|
||||
{
|
||||
return (getTemplate().getOpenType() & OPEN_BY_ITEM) == OPEN_BY_ITEM;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if door is open-able by double-click.
|
||||
*/
|
||||
public final boolean isOpenableByClick()
|
||||
{
|
||||
return (getTemplate().getOpenType() & OPEN_BY_CLICK) == OPEN_BY_CLICK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if door is open-able by time.
|
||||
*/
|
||||
public final boolean isOpenableByTime()
|
||||
{
|
||||
return (getTemplate().getOpenType() & OPEN_BY_TIME) == OPEN_BY_TIME;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if door is open-able by Field Cycle system.
|
||||
*/
|
||||
public final boolean isOpenableByCycle()
|
||||
{
|
||||
return (getTemplate().getOpenType() & OPEN_BY_CYCLE) == OPEN_BY_CYCLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getLevel()
|
||||
{
|
||||
return getTemplate().getLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the door ID.
|
||||
* @return the door ID
|
||||
*/
|
||||
@Override
|
||||
public int getId()
|
||||
{
|
||||
return getTemplate().getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the open.
|
||||
*/
|
||||
public boolean getOpen()
|
||||
{
|
||||
return _open;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param open The open to set.
|
||||
*/
|
||||
public void setOpen(boolean open)
|
||||
{
|
||||
_open = open;
|
||||
if (getChildId() > 0)
|
||||
{
|
||||
L2DoorInstance sibling = getSiblingDoor(getChildId());
|
||||
if (sibling != null)
|
||||
{
|
||||
sibling.notifyChildEvent(open);
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.log(Level.WARNING, getClass().getSimpleName() + ": cannot find child id: " + getChildId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getIsAttackableDoor()
|
||||
{
|
||||
return _isAttackableDoor;
|
||||
}
|
||||
|
||||
public boolean getIsShowHp()
|
||||
{
|
||||
return getTemplate().isShowHp();
|
||||
}
|
||||
|
||||
public void setIsAttackableDoor(boolean val)
|
||||
{
|
||||
_isAttackableDoor = val;
|
||||
}
|
||||
|
||||
public int getDamage()
|
||||
{
|
||||
int dmg = 6 - (int) Math.ceil((getCurrentHp() / getMaxHp()) * 6);
|
||||
if (dmg > 6)
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
if (dmg < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return dmg;
|
||||
}
|
||||
|
||||
// TODO: Replace index with the castle id itself.
|
||||
public final Castle getCastle()
|
||||
{
|
||||
if (_castleIndex < 0)
|
||||
{
|
||||
_castleIndex = CastleManager.getInstance().getCastleIndex(this);
|
||||
}
|
||||
if (_castleIndex < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return CastleManager.getInstance().getCastles().get(_castleIndex);
|
||||
}
|
||||
|
||||
// TODO: Replace index with the fort id itself.
|
||||
public final Fort getFort()
|
||||
{
|
||||
if (_fortIndex < 0)
|
||||
{
|
||||
_fortIndex = FortManager.getInstance().getFortIndex(this);
|
||||
}
|
||||
if (_fortIndex < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return FortManager.getInstance().getForts().get(_fortIndex);
|
||||
}
|
||||
|
||||
public void setClanHall(ClanHall clanhall)
|
||||
{
|
||||
_clanHall = clanhall;
|
||||
}
|
||||
|
||||
public ClanHall getClanHall()
|
||||
{
|
||||
return _clanHall;
|
||||
}
|
||||
|
||||
public boolean isEnemy()
|
||||
{
|
||||
if ((getCastle() != null) && (getCastle().getResidenceId() > 0) && getCastle().getZone().isActive() && getIsShowHp())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ((getFort() != null) && (getFort().getResidenceId() > 0) && getFort().getZone().isActive() && getIsShowHp())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ((getClanHall() != null) && getClanHall().isSiegableHall() && ((SiegableHall) getClanHall()).getSiegeZone().isActive() && getIsShowHp())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
// Doors can`t be attacked by NPCs
|
||||
if (!(attacker instanceof L2Playable))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getIsAttackableDoor())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!getIsShowHp())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
L2PcInstance actingPlayer = attacker.getActingPlayer();
|
||||
|
||||
if (getClanHall() != null)
|
||||
{
|
||||
SiegableHall hall = (SiegableHall) getClanHall();
|
||||
if (!hall.isSiegableHall())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return hall.isInSiege() && hall.getSiege().doorIsAutoAttackable() && hall.getSiege().checkIsAttacker(actingPlayer.getClan());
|
||||
}
|
||||
// Attackable only during siege by everyone (not owner)
|
||||
boolean isCastle = ((getCastle() != null) && (getCastle().getResidenceId() > 0) && getCastle().getZone().isActive());
|
||||
boolean isFort = ((getFort() != null) && (getFort().getResidenceId() > 0) && getFort().getZone().isActive());
|
||||
|
||||
if (isFort)
|
||||
{
|
||||
L2Clan clan = actingPlayer.getClan();
|
||||
if ((clan != null) && (clan == getFort().getOwnerClan()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (isCastle)
|
||||
{
|
||||
L2Clan clan = actingPlayer.getClan();
|
||||
if ((clan != null) && (clan.getId() == getCastle().getOwnerId()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return (isCastle || isFort);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAbnormalEffect()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return null.
|
||||
*/
|
||||
@Override
|
||||
public L2ItemInstance getActiveWeaponInstance()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Weapon getActiveWeaponItem()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2ItemInstance getSecondaryWeaponInstance()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Weapon getSecondaryWeaponItem()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastStatusUpdate()
|
||||
{
|
||||
Collection<L2PcInstance> knownPlayers = getKnownList().getKnownPlayers().values();
|
||||
if ((knownPlayers == null) || knownPlayers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StaticObject su = new StaticObject(this, false);
|
||||
StaticObject targetableSu = new StaticObject(this, true);
|
||||
DoorStatusUpdate dsu = new DoorStatusUpdate(this);
|
||||
OnEventTrigger oe = null;
|
||||
if (getEmitter() > 0)
|
||||
{
|
||||
oe = new OnEventTrigger(this, getOpen());
|
||||
}
|
||||
|
||||
for (L2PcInstance player : knownPlayers)
|
||||
{
|
||||
if ((player == null) || !isVisibleFor(player))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player.isGM() || (((getCastle() != null) && (getCastle().getResidenceId() > 0)) || ((getFort() != null) && (getFort().getResidenceId() > 0))))
|
||||
{
|
||||
player.sendPacket(targetableSu);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(su);
|
||||
}
|
||||
|
||||
player.sendPacket(dsu);
|
||||
if (oe != null)
|
||||
{
|
||||
player.sendPacket(oe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void openMe()
|
||||
{
|
||||
if (getGroupName() != null)
|
||||
{
|
||||
manageGroupOpen(true, getGroupName());
|
||||
return;
|
||||
}
|
||||
setOpen(true);
|
||||
broadcastStatusUpdate();
|
||||
startAutoCloseTask();
|
||||
}
|
||||
|
||||
public final void closeMe()
|
||||
{
|
||||
// remove close task
|
||||
Future<?> oldTask = _autoCloseTask;
|
||||
if (oldTask != null)
|
||||
{
|
||||
_autoCloseTask = null;
|
||||
oldTask.cancel(false);
|
||||
}
|
||||
if (getGroupName() != null)
|
||||
{
|
||||
manageGroupOpen(false, getGroupName());
|
||||
return;
|
||||
}
|
||||
setOpen(false);
|
||||
broadcastStatusUpdate();
|
||||
}
|
||||
|
||||
private void manageGroupOpen(boolean open, String groupName)
|
||||
{
|
||||
Set<Integer> set = DoorTable.getDoorsByGroup(groupName);
|
||||
L2DoorInstance first = null;
|
||||
for (Integer id : set)
|
||||
{
|
||||
L2DoorInstance door = getSiblingDoor(id);
|
||||
if (first == null)
|
||||
{
|
||||
first = door;
|
||||
}
|
||||
|
||||
if (door.getOpen() != open)
|
||||
{
|
||||
door.setOpen(open);
|
||||
door.broadcastStatusUpdate();
|
||||
}
|
||||
}
|
||||
if ((first != null) && open)
|
||||
{
|
||||
first.startAutoCloseTask(); // only one from group
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Door notify child about open state change
|
||||
* @param open true if opened
|
||||
*/
|
||||
private void notifyChildEvent(boolean open)
|
||||
{
|
||||
byte openThis = open ? getTemplate().getMasterDoorOpen() : getTemplate().getMasterDoorClose();
|
||||
|
||||
if (openThis == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (openThis == 1)
|
||||
{
|
||||
openMe();
|
||||
}
|
||||
else if (openThis == -1)
|
||||
{
|
||||
closeMe();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getClass().getSimpleName() + "[" + getTemplate().getId() + "](" + getObjectId() + ")";
|
||||
}
|
||||
|
||||
public String getDoorName()
|
||||
{
|
||||
return getTemplate().getName();
|
||||
}
|
||||
|
||||
public int getX(int i)
|
||||
{
|
||||
return getTemplate().getNodeX()[i];
|
||||
}
|
||||
|
||||
public int getY(int i)
|
||||
{
|
||||
return getTemplate().getNodeY()[i];
|
||||
}
|
||||
|
||||
public int getZMin()
|
||||
{
|
||||
return getTemplate().getNodeZ();
|
||||
}
|
||||
|
||||
public int getZMax()
|
||||
{
|
||||
return getTemplate().getNodeZ() + getTemplate().getHeight();
|
||||
}
|
||||
|
||||
public Collection<L2DefenderInstance> getKnownDefenders()
|
||||
{
|
||||
FastList<L2DefenderInstance> result = new FastList<>();
|
||||
|
||||
Collection<L2Object> objs = getKnownList().getKnownObjects().values();
|
||||
for (L2Object obj : objs)
|
||||
{
|
||||
if (obj instanceof L2DefenderInstance)
|
||||
{
|
||||
result.add((L2DefenderInstance) obj);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setMeshIndex(int mesh)
|
||||
{
|
||||
_meshindex = mesh;
|
||||
}
|
||||
|
||||
public int getMeshIndex()
|
||||
{
|
||||
return _meshindex;
|
||||
}
|
||||
|
||||
public int getEmitter()
|
||||
{
|
||||
return getTemplate().getEmmiter();
|
||||
}
|
||||
|
||||
public boolean isWall()
|
||||
{
|
||||
return getTemplate().isWall();
|
||||
}
|
||||
|
||||
public String getGroupName()
|
||||
{
|
||||
return getTemplate().getGroupName();
|
||||
}
|
||||
|
||||
public int getChildId()
|
||||
{
|
||||
return getTemplate().getChildDoorId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reduceCurrentHp(double damage, L2Character attacker, boolean awake, boolean isDOT, Skill skill)
|
||||
{
|
||||
if (isWall() && (getInstanceId() == 0))
|
||||
{
|
||||
if (!attacker.isServitor())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final L2ServitorInstance servitor = (L2ServitorInstance) attacker;
|
||||
if (servitor.getTemplate().getRace() != Race.SIEGE_WEAPON)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
super.reduceCurrentHp(damage, attacker, awake, isDOT, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reduceCurrentHpByDOT(double i, L2Character attacker, Skill skill)
|
||||
{
|
||||
// doors can't be damaged by DOTs
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isFort = ((getFort() != null) && (getFort().getResidenceId() > 0) && getFort().getSiege().isInProgress());
|
||||
boolean isCastle = ((getCastle() != null) && (getCastle().getResidenceId() > 0) && getCastle().getSiege().isInProgress());
|
||||
boolean isHall = ((getClanHall() != null) && getClanHall().isSiegableHall() && ((SiegableHall) getClanHall()).isInSiege());
|
||||
|
||||
if (isFort || isCastle || isHall)
|
||||
{
|
||||
broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.THE_CASTLE_GATE_HAS_BEEN_DESTROYED));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendInfo(L2PcInstance activeChar)
|
||||
{
|
||||
if (isVisibleFor(activeChar))
|
||||
{
|
||||
if (getEmitter() > 0)
|
||||
{
|
||||
activeChar.sendPacket(new OnEventTrigger(this, getOpen()));
|
||||
}
|
||||
|
||||
activeChar.sendPacket(new StaticObject(this, activeChar.isGM()));
|
||||
}
|
||||
}
|
||||
|
||||
public void setTargetable(boolean b)
|
||||
{
|
||||
_isTargetable = b;
|
||||
broadcastStatusUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTargetable()
|
||||
{
|
||||
return _isTargetable;
|
||||
}
|
||||
|
||||
public boolean checkCollision()
|
||||
{
|
||||
return getTemplate().isCheckCollision();
|
||||
}
|
||||
|
||||
/**
|
||||
* All doors are stored at DoorTable except instance doors
|
||||
* @param doorId
|
||||
* @return
|
||||
*/
|
||||
private L2DoorInstance getSiblingDoor(int doorId)
|
||||
{
|
||||
if (getInstanceId() == 0)
|
||||
{
|
||||
return DoorTable.getInstance().getDoor(doorId);
|
||||
}
|
||||
|
||||
Instance inst = InstanceManager.getInstance().getInstance(getInstanceId());
|
||||
if (inst != null)
|
||||
{
|
||||
return inst.getDoor(doorId);
|
||||
}
|
||||
|
||||
return null; // 2 late
|
||||
}
|
||||
|
||||
private void startAutoCloseTask()
|
||||
{
|
||||
if ((getTemplate().getCloseTime() < 0) || isOpenableByTime())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Future<?> oldTask = _autoCloseTask;
|
||||
if (oldTask != null)
|
||||
{
|
||||
_autoCloseTask = null;
|
||||
oldTask.cancel(false);
|
||||
}
|
||||
_autoCloseTask = ThreadPoolManager.getInstance().scheduleGeneral(new AutoClose(), getTemplate().getCloseTime() * 1000);
|
||||
}
|
||||
|
||||
class AutoClose implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (getOpen())
|
||||
{
|
||||
closeMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TimerOpen implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
boolean open = getOpen();
|
||||
if (open)
|
||||
{
|
||||
closeMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
openMe();
|
||||
}
|
||||
|
||||
int delay = open ? getTemplate().getCloseTime() : getTemplate().getOpenTime();
|
||||
if (getTemplate().getRandomTime() > 0)
|
||||
{
|
||||
delay += Rnd.get(getTemplate().getRandomTime());
|
||||
}
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(this, delay * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDoor()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jserver.gameserver.datatables.DoorTable;
|
||||
import com.l2jserver.gameserver.datatables.TeleportLocationTable;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.L2TeleportLocation;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public class L2DoormenInstance extends L2NpcInstance
|
||||
{
|
||||
/**
|
||||
* @param objectID
|
||||
* @param template
|
||||
*/
|
||||
public L2DoormenInstance(int objectID, L2NpcTemplate template)
|
||||
{
|
||||
super(objectID, template);
|
||||
setInstanceType(InstanceType.L2DoormenInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
if (command.startsWith("Chat"))
|
||||
{
|
||||
showChatWindow(player);
|
||||
return;
|
||||
}
|
||||
else if (command.startsWith("open_doors"))
|
||||
{
|
||||
if (isOwnerClan(player))
|
||||
{
|
||||
if (isUnderSiege())
|
||||
{
|
||||
cannotManageDoors(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
openDoors(player, command);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (command.startsWith("close_doors"))
|
||||
{
|
||||
if (isOwnerClan(player))
|
||||
{
|
||||
if (isUnderSiege())
|
||||
{
|
||||
cannotManageDoors(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
closeDoors(player, command);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (command.startsWith("tele"))
|
||||
{
|
||||
if (isOwnerClan(player))
|
||||
{
|
||||
doTeleport(player, command);
|
||||
}
|
||||
return;
|
||||
}
|
||||
super.onBypassFeedback(player, command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showChatWindow(L2PcInstance player)
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
|
||||
if (!isOwnerClan(player))
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/doormen/" + getTemplate().getId() + "-no.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/doormen/" + getTemplate().getId() + ".htm");
|
||||
}
|
||||
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
protected void openDoors(L2PcInstance player, String command)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(command.substring(10), ", ");
|
||||
st.nextToken();
|
||||
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
DoorTable.getInstance().getDoor(Integer.parseInt(st.nextToken())).openMe();
|
||||
}
|
||||
}
|
||||
|
||||
protected void closeDoors(L2PcInstance player, String command)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(command.substring(11), ", ");
|
||||
st.nextToken();
|
||||
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
DoorTable.getInstance().getDoor(Integer.parseInt(st.nextToken())).closeMe();
|
||||
}
|
||||
}
|
||||
|
||||
protected void cannotManageDoors(L2PcInstance player)
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/doormen/" + getTemplate().getId() + "-busy.htm");
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
protected void doTeleport(L2PcInstance player, String command)
|
||||
{
|
||||
final int whereTo = Integer.parseInt(command.substring(5).trim());
|
||||
L2TeleportLocation list = TeleportLocationTable.getInstance().getTemplate(whereTo);
|
||||
if (list != null)
|
||||
{
|
||||
if (!player.isAlikeDead())
|
||||
{
|
||||
player.teleToLocation(list.getLocX(), list.getLocY(), list.getLocZ(), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("No teleport destination with id:" + whereTo);
|
||||
}
|
||||
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
protected boolean isOwnerClan(L2PcInstance player)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isUnderSiege()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
|
||||
public class L2EffectPointInstance extends L2Npc
|
||||
{
|
||||
private final L2PcInstance _owner;
|
||||
|
||||
public L2EffectPointInstance(int objectId, L2NpcTemplate template, L2Character owner)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2EffectPointInstance);
|
||||
setIsInvul(false);
|
||||
_owner = owner == null ? null : owner.getActingPlayer();
|
||||
if (owner != null)
|
||||
{
|
||||
setInstanceId(owner.getInstanceId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2PcInstance getActingPlayer()
|
||||
{
|
||||
return _owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* this is called when a player interacts with this NPC
|
||||
* @param player
|
||||
*/
|
||||
@Override
|
||||
public void onAction(L2PcInstance player, boolean interact)
|
||||
{
|
||||
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionShift(L2PcInstance player)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
/**
|
||||
* @author Gnacik
|
||||
*/
|
||||
public class L2EventMonsterInstance extends L2MonsterInstance
|
||||
{
|
||||
// Block offensive skills usage on event mobs
|
||||
// mainly for AoE skills, disallow kill many event mobs
|
||||
// with one skill
|
||||
public boolean block_skill_attack = false;
|
||||
|
||||
// Event mobs should drop items to ground
|
||||
// but item pickup must be protected to killer
|
||||
// Todo: Some mobs need protect drop for spawner
|
||||
public boolean drop_on_ground = false;
|
||||
|
||||
public L2EventMonsterInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2EventMobInstance);
|
||||
}
|
||||
|
||||
public void eventSetBlockOffensiveSkills(boolean value)
|
||||
{
|
||||
block_skill_attack = value;
|
||||
}
|
||||
|
||||
public void eventSetDropOnGround(boolean value)
|
||||
{
|
||||
drop_on_ground = value;
|
||||
}
|
||||
|
||||
public boolean eventDropOnGround()
|
||||
{
|
||||
return drop_on_ground;
|
||||
}
|
||||
|
||||
public boolean eventSkillAttackBlocked()
|
||||
{
|
||||
return block_skill_attack;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
// This class is here mostly for convenience and for avoidance of hardcoded IDs.
|
||||
// It refers to Beast (mobs) that can be attacked but can also be fed
|
||||
// For example, the Beast Farm's Alpen Buffalo.
|
||||
// This class is only truly used by the handlers in order to check the correctness
|
||||
// of the target. However, no additional tasks are needed, since they are all
|
||||
// handled by scripted AI.
|
||||
public class L2FeedableBeastInstance extends L2MonsterInstance
|
||||
{
|
||||
public L2FeedableBeastInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2FeedableBeastInstance);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jserver.gameserver.datatables.SkillTreesData;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.L2SkillLearn;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.base.AcquireSkillType;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExAcquirableSkillListByClass;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
public final class L2FishermanInstance extends L2MerchantInstance
|
||||
{
|
||||
public L2FishermanInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2FishermanInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "data/html/fisherman/" + pom + ".htm";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
if (command.equalsIgnoreCase("FishSkillList"))
|
||||
{
|
||||
showFishSkillList(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onBypassFeedback(player, command);
|
||||
}
|
||||
}
|
||||
|
||||
public static void showFishSkillList(L2PcInstance player)
|
||||
{
|
||||
final List<L2SkillLearn> skills = SkillTreesData.getInstance().getAvailableFishingSkills(player);
|
||||
|
||||
if (skills.isEmpty())
|
||||
{
|
||||
final int minlLevel = SkillTreesData.getInstance().getMinLevelForNewSkill(player, SkillTreesData.getInstance().getFishingSkillTree());
|
||||
if (minlLevel > 0)
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_DO_NOT_HAVE_ANY_FURTHER_SKILLS_TO_LEARN_COME_BACK_WHEN_YOU_HAVE_REACHED_LEVEL_S1);
|
||||
sm.addInt(minlLevel);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THERE_ARE_NO_OTHER_SKILLS_TO_LEARN);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(new ExAcquirableSkillListByClass(skills, AcquireSkillType.FISHING));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Tower;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.zone.L2ZoneType;
|
||||
|
||||
/**
|
||||
* Class for Flame Control Tower instance.
|
||||
* @author JIV
|
||||
*/
|
||||
public class L2FlameTowerInstance extends L2Tower
|
||||
{
|
||||
private int _upgradeLevel = 0;
|
||||
private List<Integer> _zoneList;
|
||||
|
||||
public L2FlameTowerInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2FlameTowerInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
enableZones(false);
|
||||
return super.doDie(killer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteMe()
|
||||
{
|
||||
enableZones(false);
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
public final void enableZones(boolean state)
|
||||
{
|
||||
if ((_zoneList != null) && (_upgradeLevel != 0))
|
||||
{
|
||||
final int maxIndex = _upgradeLevel * 2;
|
||||
for (int i = 0; i < maxIndex; i++)
|
||||
{
|
||||
final L2ZoneType zone = ZoneManager.getInstance().getZoneById(_zoneList.get(i));
|
||||
if (zone != null)
|
||||
{
|
||||
zone.setEnabled(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final void setUpgradeLevel(int level)
|
||||
{
|
||||
_upgradeLevel = level;
|
||||
}
|
||||
|
||||
public final void setZoneList(List<Integer> list)
|
||||
{
|
||||
_zoneList = list;
|
||||
enableZones(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
public final class L2FlyMonsterInstance extends L2MonsterInstance
|
||||
{
|
||||
public L2FlyMonsterInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2FlyMonsterInstance);
|
||||
setIsFlying(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
public final class L2FlyNpcInstance extends L2NpcInstance
|
||||
{
|
||||
public L2FlyNpcInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2FlyNpcInstance);
|
||||
setIsFlying(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
public final class L2FlyRaidBossInstance extends L2RaidBossInstance
|
||||
{
|
||||
public L2FlyRaidBossInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2FlyRaidBossInstance);
|
||||
setIsFlying(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
|
||||
public final class L2FlyTerrainObjectInstance extends L2Npc
|
||||
{
|
||||
public L2FlyTerrainObjectInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2FlyTerrainObjectInstance);
|
||||
setIsFlying(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAction(L2PcInstance player, boolean interact)
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionShift(L2PcInstance player)
|
||||
{
|
||||
if (player.isGM())
|
||||
{
|
||||
super.onActionShift(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.FortSiegeManager;
|
||||
import com.l2jserver.gameserver.model.FortSiegeSpawn;
|
||||
import com.l2jserver.gameserver.model.L2Spawn;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
|
||||
public class L2FortCommanderInstance extends L2DefenderInstance
|
||||
{
|
||||
|
||||
private boolean _canTalk;
|
||||
|
||||
public L2FortCommanderInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2FortCommanderInstance);
|
||||
_canTalk = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return True if a siege is in progress and the L2Character attacker isn't a Defender.
|
||||
* @param attacker The L2Character that the L2CommanderInstance try to attack
|
||||
*/
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
if ((attacker == null) || !(attacker instanceof L2PcInstance))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isFort = ((getFort() != null) && (getFort().getResidenceId() > 0) && getFort().getSiege().isInProgress() && !getFort().getSiege().checkIsDefender(((L2PcInstance) attacker).getClan()));
|
||||
|
||||
// Attackable during siege by all except defenders
|
||||
return (isFort);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDamageHate(L2Character attacker, int damage, int aggro)
|
||||
{
|
||||
if (attacker == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(attacker instanceof L2FortCommanderInstance))
|
||||
{
|
||||
super.addDamageHate(attacker, damage, aggro);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getFort().getSiege().isInProgress())
|
||||
{
|
||||
getFort().getSiege().killedCommander(this);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method forces guard to return to home location previously set
|
||||
*/
|
||||
@Override
|
||||
public void returnHome()
|
||||
{
|
||||
if (!isInsideRadius(getSpawn(), 200, false, false))
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info(getObjectId() + ": moving home");
|
||||
}
|
||||
setisReturningToSpawnPoint(true);
|
||||
clearAggroList();
|
||||
|
||||
if (hasAI())
|
||||
{
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, getSpawn().getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void addDamage(L2Character attacker, int damage, Skill skill)
|
||||
{
|
||||
L2Spawn spawn = getSpawn();
|
||||
if ((spawn != null) && canTalk())
|
||||
{
|
||||
FastList<FortSiegeSpawn> commanders = FortSiegeManager.getInstance().getCommanderSpawnList(getFort().getResidenceId());
|
||||
for (FortSiegeSpawn spawn2 : commanders)
|
||||
{
|
||||
if (spawn2.getId() == spawn.getId())
|
||||
{
|
||||
NpcStringId npcString = null;
|
||||
switch (spawn2.getMessageId())
|
||||
{
|
||||
case 1:
|
||||
npcString = NpcStringId.ATTACKING_THE_ENEMY_S_REINFORCEMENTS_IS_NECESSARY_TIME_TO_DIE;
|
||||
break;
|
||||
case 2:
|
||||
if (attacker instanceof L2Summon)
|
||||
{
|
||||
attacker = ((L2Summon) attacker).getOwner();
|
||||
}
|
||||
npcString = NpcStringId.EVERYONE_CONCENTRATE_YOUR_ATTACKS_ON_S1_SHOW_THE_ENEMY_YOUR_RESOLVE;
|
||||
break;
|
||||
case 3:
|
||||
npcString = NpcStringId.FIRE_SPIRIT_UNLEASH_YOUR_POWER_BURN_THE_ENEMY;
|
||||
break;
|
||||
}
|
||||
if (npcString != null)
|
||||
{
|
||||
NpcSay ns = new NpcSay(getObjectId(), Say2.NPC_SHOUT, getId(), npcString);
|
||||
if (npcString.getParamCount() == 1)
|
||||
{
|
||||
ns.addStringParameter(attacker.getName());
|
||||
}
|
||||
|
||||
broadcastPacket(ns);
|
||||
setCanTalk(false);
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleTalkTask(), 10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
super.addDamage(attacker, damage, skill);
|
||||
}
|
||||
|
||||
private class ScheduleTalkTask implements Runnable
|
||||
{
|
||||
|
||||
public ScheduleTalkTask()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
setCanTalk(true);
|
||||
}
|
||||
}
|
||||
|
||||
void setCanTalk(boolean val)
|
||||
{
|
||||
_canTalk = val;
|
||||
}
|
||||
|
||||
private boolean canTalk()
|
||||
{
|
||||
return _canTalk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRandomAnimation()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
|
||||
public class L2FortDoormenInstance extends L2DoormenInstance
|
||||
{
|
||||
public L2FortDoormenInstance(int objectID, L2NpcTemplate template)
|
||||
{
|
||||
super(objectID, template);
|
||||
setInstanceType(InstanceType.L2FortDoormenInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showChatWindow(L2PcInstance player)
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
|
||||
if (!isOwnerClan(player))
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/doormen/" + getTemplate().getId() + "-no.htm");
|
||||
}
|
||||
else if (isUnderSiege())
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/doormen/" + getTemplate().getId() + "-busy.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/doormen/" + getTemplate().getId() + ".htm");
|
||||
}
|
||||
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void openDoors(L2PcInstance player, String command)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(command.substring(10), ", ");
|
||||
st.nextToken();
|
||||
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
getFort().openDoor(player, Integer.parseInt(st.nextToken()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void closeDoors(L2PcInstance player, String command)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(command.substring(11), ", ");
|
||||
st.nextToken();
|
||||
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
getFort().closeDoor(player, Integer.parseInt(st.nextToken()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean isOwnerClan(L2PcInstance player)
|
||||
{
|
||||
if ((player.getClan() != null) && (getFort() != null) && (getFort().getOwnerClan() != null))
|
||||
{
|
||||
if (player.getClanId() == getFort().getOwnerClan().getId())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean isUnderSiege()
|
||||
{
|
||||
return getFort().getZone().isActive();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jserver.gameserver.datatables.NpcData;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
|
||||
/**
|
||||
* @author Vice, Zoey76
|
||||
*/
|
||||
public class L2FortLogisticsInstance extends L2MerchantInstance
|
||||
{
|
||||
private static final int[] SUPPLY_BOX_IDS =
|
||||
{
|
||||
35665,
|
||||
35697,
|
||||
35734,
|
||||
35766,
|
||||
35803,
|
||||
35834,
|
||||
35866,
|
||||
35903,
|
||||
35935,
|
||||
35973,
|
||||
36010,
|
||||
36042,
|
||||
36080,
|
||||
36117,
|
||||
36148,
|
||||
36180,
|
||||
36218,
|
||||
36256,
|
||||
36293,
|
||||
36325,
|
||||
36363
|
||||
};
|
||||
|
||||
public L2FortLogisticsInstance(int objectID, L2NpcTemplate template)
|
||||
{
|
||||
super(objectID, template);
|
||||
setInstanceType(InstanceType.L2FortLogisticsInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
if (player.getLastFolkNPC().getObjectId() != getObjectId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StringTokenizer st = new StringTokenizer(command, " ");
|
||||
String actualCommand = st.nextToken(); // Get actual command
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
if (actualCommand.equalsIgnoreCase("rewards"))
|
||||
{
|
||||
if (isMyLord(player))
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/fortress/logistics-rewards.htm");
|
||||
html.replace("%bloodoath%", String.valueOf(player.getClan().getBloodOathCount()));
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/fortress/logistics-noprivs.htm");
|
||||
}
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("blood"))
|
||||
{
|
||||
if (isMyLord(player))
|
||||
{
|
||||
final int blood = player.getClan().getBloodOathCount();
|
||||
if (blood > 0)
|
||||
{
|
||||
player.addItem("Quest", 9910, blood, this, true);
|
||||
player.getClan().resetBloodOathCount();
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/fortress/logistics-blood.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/fortress/logistics-noblood.htm");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/fortress/logistics-noprivs.htm");
|
||||
}
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("supplylvl"))
|
||||
{
|
||||
if (getFort().getFortState() == 2)
|
||||
{
|
||||
if (player.isClanLeader())
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/fortress/logistics-supplylvl.htm");
|
||||
html.replace("%supplylvl%", String.valueOf(getFort().getSupplyLvL()));
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/fortress/logistics-noprivs.htm");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/fortress/logistics-1.htm"); // TODO: Missing HTML?
|
||||
}
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("supply"))
|
||||
{
|
||||
if (isMyLord(player))
|
||||
{
|
||||
if (getFort().getSiege().isInProgress())
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/fortress/logistics-siege.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
final int level = getFort().getSupplyLvL();
|
||||
if (level > 0)
|
||||
{
|
||||
// spawn box
|
||||
L2NpcTemplate BoxTemplate = NpcData.getInstance().getTemplate(SUPPLY_BOX_IDS[level - 1]);
|
||||
L2MonsterInstance box = new L2MonsterInstance(IdFactory.getInstance().getNextId(), BoxTemplate);
|
||||
box.setCurrentHp(box.getMaxHp());
|
||||
box.setCurrentMp(box.getMaxMp());
|
||||
box.setHeading(0);
|
||||
box.spawnMe(getX() - 23, getY() + 41, getZ());
|
||||
|
||||
getFort().setSupplyLvL(0);
|
||||
getFort().saveFortVariables();
|
||||
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/fortress/logistics-supply.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/fortress/logistics-nosupply.htm");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/fortress/logistics-noprivs.htm");
|
||||
}
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onBypassFeedback(player, command);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showChatWindow(L2PcInstance player)
|
||||
{
|
||||
showMessageWindow(player, 0);
|
||||
}
|
||||
|
||||
private void showMessageWindow(L2PcInstance player, int val)
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
|
||||
String filename;
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
filename = "data/html/fortress/logistics.htm";
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = "data/html/fortress/logistics-" + val + ".htm";
|
||||
}
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
html.replace("%npcId%", String.valueOf(getId()));
|
||||
if (getFort().getOwnerClan() != null)
|
||||
{
|
||||
html.replace("%clanname%", getFort().getOwnerClan().getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
html.replace("%clanname%", "NPC");
|
||||
}
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "logistics";
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = "logistics-" + val;
|
||||
}
|
||||
|
||||
return "data/html/fortress/" + pom + ".htm";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRandomAnimation()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.knownlist.FriendlyMobKnownList;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
/**
|
||||
* This class represents Friendly Mobs lying over the world.<br>
|
||||
* These friendly mobs should only attack players with karma > 0 and it is always aggro, since it just attacks players with karma.
|
||||
*/
|
||||
public class L2FriendlyMobInstance extends L2Attackable
|
||||
{
|
||||
public L2FriendlyMobInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2FriendlyMobInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final FriendlyMobKnownList getKnownList()
|
||||
{
|
||||
return (FriendlyMobKnownList) super.getKnownList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initKnownList()
|
||||
{
|
||||
setKnownList(new FriendlyMobKnownList(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
if (attacker instanceof L2PcInstance)
|
||||
{
|
||||
return ((L2PcInstance) attacker).getKarma() > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAggressive()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.RaidBossPointsManager;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.entity.Hero;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jserver.util.Rnd;
|
||||
|
||||
/**
|
||||
* This class manages all Grand Bosses.
|
||||
* @version $Revision: 1.0.0.0 $ $Date: 2006/06/16 $
|
||||
*/
|
||||
public final class L2GrandBossInstance extends L2MonsterInstance
|
||||
{
|
||||
private static final int BOSS_MAINTENANCE_INTERVAL = 10000;
|
||||
private boolean _useRaidCurse = true;
|
||||
|
||||
/**
|
||||
* Constructor for L2GrandBossInstance. This represent all grandbosses.
|
||||
* @param objectId ID of the instance
|
||||
* @param template L2NpcTemplate of the instance
|
||||
*/
|
||||
public L2GrandBossInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2GrandBossInstance);
|
||||
setIsRaid(true);
|
||||
setLethalable(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaintenanceInterval()
|
||||
{
|
||||
return BOSS_MAINTENANCE_INTERVAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
setIsNoRndWalk(true);
|
||||
super.onSpawn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
L2PcInstance player = null;
|
||||
|
||||
if (killer instanceof L2PcInstance)
|
||||
{
|
||||
player = (L2PcInstance) killer;
|
||||
}
|
||||
else if (killer instanceof L2Summon)
|
||||
{
|
||||
player = ((L2Summon) killer).getOwner();
|
||||
}
|
||||
|
||||
if (player != null)
|
||||
{
|
||||
broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_YOUR_RAID_WAS_SUCCESSFUL));
|
||||
if (player.getParty() != null)
|
||||
{
|
||||
for (L2PcInstance member : player.getParty().getMembers())
|
||||
{
|
||||
RaidBossPointsManager.getInstance().addPoints(member, getId(), (getLevel() / 2) + Rnd.get(-5, 5));
|
||||
if (member.isNoble())
|
||||
{
|
||||
Hero.getInstance().setRBkilled(member.getObjectId(), getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RaidBossPointsManager.getInstance().addPoints(player, getId(), (getLevel() / 2) + Rnd.get(-5, 5));
|
||||
if (player.isNoble())
|
||||
{
|
||||
Hero.getInstance().setRBkilled(player.getObjectId(), getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getVitalityPoints(int damage)
|
||||
{
|
||||
return -super.getVitalityPoints(damage) / 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useVitalityRate()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setUseRaidCurse(boolean val)
|
||||
{
|
||||
_useRaidCurse = val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean giveRaidCurse()
|
||||
{
|
||||
return _useRaidCurse;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.L2World;
|
||||
import com.l2jserver.gameserver.model.L2WorldRegion;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.knownlist.GuardKnownList;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jserver.gameserver.model.events.EventType;
|
||||
import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcFirstTalk;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jserver.util.Rnd;
|
||||
|
||||
/**
|
||||
* This class manages all Guards in the world. It inherits all methods from L2Attackable and adds some more such as tracking PK and aggressive L2MonsterInstance.
|
||||
*/
|
||||
public class L2GuardInstance extends L2Attackable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(L2GuardInstance.class.getName());
|
||||
|
||||
/**
|
||||
* Constructor of L2GuardInstance (use L2Character and L2NpcInstance constructor).<br>
|
||||
* <B><U> Actions</U> :</B>
|
||||
* <ul>
|
||||
* <li>Call the L2Character constructor to set the _template of the L2GuardInstance (copy skills from template to object and link _calculators to NPC_STD_CALCULATOR)</li>
|
||||
* <li>Set the name of the L2GuardInstance</li>
|
||||
* <li>Create a RandomAnimation Task that will be launched after the calculated delay if the server allow it</li>
|
||||
* </ul>
|
||||
* @param objectId the identifier of the object to initialized
|
||||
* @param template to apply to the NPC
|
||||
*/
|
||||
public L2GuardInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2GuardInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final GuardKnownList getKnownList()
|
||||
{
|
||||
return (GuardKnownList) super.getKnownList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initKnownList()
|
||||
{
|
||||
setKnownList(new GuardKnownList(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return True if hte attacker is a L2MonsterInstance.
|
||||
*/
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
return attacker instanceof L2MonsterInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the home location of its L2GuardInstance.
|
||||
*/
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
setIsNoRndWalk(true);
|
||||
super.onSpawn();
|
||||
|
||||
// check the region where this mob is, do not activate the AI if region is inactive.
|
||||
L2WorldRegion region = L2World.getInstance().getRegion(getX(), getY());
|
||||
if ((region != null) && (!region.isActive()))
|
||||
{
|
||||
getAI().stopAITask();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the pathfile of the selected HTML file in function of the L2GuardInstance Identifier and of the page number.<br>
|
||||
* <B><U> Format of the pathfile </U> :</B>
|
||||
* <ul>
|
||||
* <li>if page number = 0 : <B>data/html/guard/12006.htm</B> (npcId-page number)</li>
|
||||
* <li>if page number > 0 : <B>data/html/guard/12006-1.htm</B> (npcId-page number)</li>
|
||||
* </ul>
|
||||
* @param npcId The Identifier of the L2NpcInstance whose text must be display
|
||||
* @param val The number of the page to display
|
||||
*/
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
return "data/html/guard/" + pom + ".htm";
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage actions when a player click on the L2GuardInstance.<br>
|
||||
* <B><U> Actions on first click on the L2GuardInstance (Select it)</U> :</B>
|
||||
* <ul>
|
||||
* <li>Set the L2GuardInstance as target of the L2PcInstance player (if necessary)</li>
|
||||
* <li>Send a Server->Client packet MyTargetSelected to the L2PcInstance player (display the select window)</li>
|
||||
* <li>Set the L2PcInstance Intention to AI_INTENTION_IDLE</li>
|
||||
* <li>Send a Server->Client packet ValidateLocation to correct the L2GuardInstance position and heading on the client</li>
|
||||
* </ul>
|
||||
* <B><U> Actions on second click on the L2GuardInstance (Attack it/Interact with it)</U> :</B>
|
||||
* <ul>
|
||||
* <li>If L2PcInstance is in the _aggroList of the L2GuardInstance, set the L2PcInstance Intention to AI_INTENTION_ATTACK</li>
|
||||
* <li>If L2PcInstance is NOT in the _aggroList of the L2GuardInstance, set the L2PcInstance Intention to AI_INTENTION_INTERACT (after a distance verification) and show message</li>
|
||||
* </ul>
|
||||
* <B><U> Example of use </U> :</B>
|
||||
* <ul>
|
||||
* <li>Client packet : Action, AttackRequest</li>
|
||||
* </ul>
|
||||
* @param player The L2PcInstance that start an action on the L2GuardInstance
|
||||
*/
|
||||
@Override
|
||||
public void onAction(L2PcInstance player, boolean interact)
|
||||
{
|
||||
if (!canTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the L2PcInstance already target the L2GuardInstance
|
||||
if (getObjectId() != player.getTargetId())
|
||||
{
|
||||
// Set the target of the L2PcInstance player
|
||||
player.setTarget(this);
|
||||
}
|
||||
else if (interact)
|
||||
{
|
||||
// Check if the L2PcInstance is in the _aggroList of the L2GuardInstance
|
||||
if (containsTarget(player))
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.fine(player.getObjectId() + ": Attacked guard " + getObjectId());
|
||||
}
|
||||
|
||||
// Set the L2PcInstance Intention to AI_INTENTION_ATTACK
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate the distance between the L2PcInstance and the L2NpcInstance
|
||||
if (!canInteract(player))
|
||||
{
|
||||
// Set the L2PcInstance Intention to AI_INTENTION_INTERACT
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send a Server->Client packet SocialAction to the all L2PcInstance on the _knownPlayer of the L2NpcInstance
|
||||
// to display a social action of the L2GuardInstance on their client
|
||||
broadcastPacket(new SocialAction(getObjectId(), Rnd.nextInt(8)));
|
||||
|
||||
player.setLastFolkNPC(this);
|
||||
|
||||
// Open a chat window on client with the text of the L2GuardInstance
|
||||
if (hasListener(EventType.ON_NPC_QUEST_START))
|
||||
{
|
||||
player.setLastQuestNpcObject(getObjectId());
|
||||
}
|
||||
|
||||
if (hasListener(EventType.ON_NPC_FIRST_TALK))
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnNpcFirstTalk(this, player), this);
|
||||
}
|
||||
else
|
||||
{
|
||||
showChatWindow(player, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.datatables.BuyListData;
|
||||
import com.l2jserver.gameserver.datatables.MerchantPriceConfigTable;
|
||||
import com.l2jserver.gameserver.datatables.MerchantPriceConfigTable.MerchantPriceConfig;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jserver.gameserver.network.serverpackets.BuyList;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExBuySellList;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision: 1.10.4.9 $ $Date: 2005/04/11 10:06:08 $
|
||||
*/
|
||||
public class L2MerchantInstance extends L2NpcInstance
|
||||
{
|
||||
private MerchantPriceConfig _mpc;
|
||||
|
||||
/**
|
||||
* @param objectId
|
||||
* @param template
|
||||
*/
|
||||
public L2MerchantInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2MerchantInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
super.onSpawn();
|
||||
_mpc = MerchantPriceConfigTable.getInstance().getMerchantPriceConfig(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "data/html/merchant/" + pom + ".htm";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the mpc.
|
||||
*/
|
||||
public MerchantPriceConfig getMpc()
|
||||
{
|
||||
return _mpc;
|
||||
}
|
||||
|
||||
public final void showBuyWindow(L2PcInstance player, int val)
|
||||
{
|
||||
showBuyWindow(player, val, true);
|
||||
}
|
||||
|
||||
public final void showBuyWindow(L2PcInstance player, int val, boolean applyTax)
|
||||
{
|
||||
final L2BuyList buyList = BuyListData.getInstance().getBuyList(val);
|
||||
if (buyList == null)
|
||||
{
|
||||
_log.warning("BuyList not found! BuyListId:" + val);
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!buyList.isNpcAllowed(getId()))
|
||||
{
|
||||
_log.warning("Npc not allowed in BuyList! BuyListId:" + val + " NpcId:" + getId());
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
final double taxRate = (applyTax) ? getMpc().getTotalTaxRate() : 0;
|
||||
|
||||
player.setInventoryBlockingStatus(true);
|
||||
|
||||
player.sendPacket(new BuyList(buyList, player.getAdena(), taxRate));
|
||||
player.sendPacket(new ExBuySellList(player, false));
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.knownlist.MonsterKnownList;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.util.MinionList;
|
||||
|
||||
/**
|
||||
* This class manages all Monsters. L2MonsterInstance:
|
||||
* <ul>
|
||||
* <li>L2MinionInstance</li>
|
||||
* <li>L2RaidBossInstance</li>
|
||||
* <li>L2GrandBossInstance</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class L2MonsterInstance extends L2Attackable
|
||||
{
|
||||
protected boolean _enableMinions = true;
|
||||
|
||||
private L2MonsterInstance _master = null;
|
||||
private volatile MinionList _minionList = null;
|
||||
|
||||
protected ScheduledFuture<?> _maintenanceTask = null;
|
||||
|
||||
private static final int MONSTER_MAINTENANCE_INTERVAL = 1000;
|
||||
|
||||
/**
|
||||
* Constructor of L2MonsterInstance (use L2Character and L2NpcInstance constructor).<br>
|
||||
* <B><U> Actions</U> :</B>
|
||||
* <ul>
|
||||
* <li>Call the L2Character constructor to set the _template of the L2MonsterInstance (copy skills from template to object and link _calculators to NPC_STD_CALCULATOR)</li>
|
||||
* <li>Set the name of the L2MonsterInstance</li>
|
||||
* <li>Create a RandomAnimation Task that will be launched after the calculated delay if the server allow it</li>
|
||||
* </ul>
|
||||
* @param objectId the identifier of the object to initialized
|
||||
* @param template to apply to the NPC
|
||||
*/
|
||||
public L2MonsterInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2MonsterInstance);
|
||||
setAutoAttackable(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final MonsterKnownList getKnownList()
|
||||
{
|
||||
return (MonsterKnownList) super.getKnownList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initKnownList()
|
||||
{
|
||||
setKnownList(new MonsterKnownList(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return True if the attacker is not another L2MonsterInstance.
|
||||
*/
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
return super.isAutoAttackable(attacker) && !isEventMob();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return True if the L2MonsterInstance is Aggressive (aggroRange > 0).
|
||||
*/
|
||||
@Override
|
||||
public boolean isAggressive()
|
||||
{
|
||||
return getTemplate().isAggressive() && !isEventMob();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
if (!isTeleporting())
|
||||
{
|
||||
if (getLeader() != null)
|
||||
{
|
||||
setIsNoRndWalk(true);
|
||||
setIsRaidMinion(getLeader().isRaid());
|
||||
getLeader().getMinionList().onMinionSpawn(this);
|
||||
}
|
||||
|
||||
// delete spawned minions before dynamic minions spawned by script
|
||||
if (hasMinions())
|
||||
{
|
||||
getMinionList().onMasterSpawn();
|
||||
}
|
||||
|
||||
startMaintenanceTask();
|
||||
}
|
||||
|
||||
// dynamic script-based minions spawned here, after all preparations.
|
||||
super.onSpawn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTeleported()
|
||||
{
|
||||
super.onTeleported();
|
||||
|
||||
if (hasMinions())
|
||||
{
|
||||
getMinionList().onMasterTeleported();
|
||||
}
|
||||
}
|
||||
|
||||
protected int getMaintenanceInterval()
|
||||
{
|
||||
return MONSTER_MAINTENANCE_INTERVAL;
|
||||
}
|
||||
|
||||
protected void startMaintenanceTask()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_maintenanceTask != null)
|
||||
{
|
||||
_maintenanceTask.cancel(false); // doesn't do it?
|
||||
_maintenanceTask = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteMe()
|
||||
{
|
||||
if (_maintenanceTask != null)
|
||||
{
|
||||
_maintenanceTask.cancel(false);
|
||||
_maintenanceTask = null;
|
||||
}
|
||||
|
||||
if (hasMinions())
|
||||
{
|
||||
getMinionList().onMasterDie(true);
|
||||
}
|
||||
|
||||
if (getLeader() != null)
|
||||
{
|
||||
getLeader().getMinionList().onMinionDie(this, 0);
|
||||
}
|
||||
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2MonsterInstance getLeader()
|
||||
{
|
||||
return _master;
|
||||
}
|
||||
|
||||
public void setLeader(L2MonsterInstance leader)
|
||||
{
|
||||
_master = leader;
|
||||
}
|
||||
|
||||
public void enableMinions(boolean b)
|
||||
{
|
||||
_enableMinions = b;
|
||||
}
|
||||
|
||||
public boolean hasMinions()
|
||||
{
|
||||
return _minionList != null;
|
||||
}
|
||||
|
||||
public MinionList getMinionList()
|
||||
{
|
||||
if (_minionList == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_minionList == null)
|
||||
{
|
||||
_minionList = new MinionList(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _minionList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMonster()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this L2MonsterInstance (or its master) is registered in WalkingManager
|
||||
*/
|
||||
@Override
|
||||
public boolean isWalker()
|
||||
{
|
||||
return ((getLeader() == null) ? super.isWalker() : getLeader().isWalker());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if this L2MonsterInstance is not raid minion, master state otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean giveRaidCurse()
|
||||
{
|
||||
return (isRaidMinion() && (getLeader() != null)) ? getLeader().giveRaidCurse() : super.giveRaidCurse();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.datatables.SkillTreesData;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.L2SkillLearn;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.status.FolkStatus;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.base.AcquireSkillType;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExAcquirableSkillListByClass;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jserver.util.StringUtil;
|
||||
|
||||
public class L2NpcInstance extends L2Npc
|
||||
{
|
||||
public L2NpcInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2NpcInstance);
|
||||
setIsInvul(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FolkStatus getStatus()
|
||||
{
|
||||
return (FolkStatus) super.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initCharStatus()
|
||||
{
|
||||
setStatus(new FolkStatus(this));
|
||||
}
|
||||
|
||||
public List<ClassId> getClassesToTeach()
|
||||
{
|
||||
return getTemplate().getTeachInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays Skill Tree for a given player, npc and class Id.
|
||||
* @param player the active character.
|
||||
* @param npc the last folk.
|
||||
* @param classId player's active class id.
|
||||
*/
|
||||
public static void showSkillList(L2PcInstance player, L2Npc npc, ClassId classId)
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.fine("SkillList activated on: " + npc.getObjectId());
|
||||
}
|
||||
|
||||
final int npcId = npc.getTemplate().getId();
|
||||
if (npcId == 32611) // Tolonis (Officer)
|
||||
{
|
||||
final List<L2SkillLearn> skills = SkillTreesData.getInstance().getAvailableCollectSkills(player);
|
||||
|
||||
if (skills.isEmpty()) // No more skills to learn, come back when you level.
|
||||
{
|
||||
final int minLevel = SkillTreesData.getInstance().getMinLevelForNewSkill(player, SkillTreesData.getInstance().getCollectSkillTree());
|
||||
if (minLevel > 0)
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_DO_NOT_HAVE_ANY_FURTHER_SKILLS_TO_LEARN_COME_BACK_WHEN_YOU_HAVE_REACHED_LEVEL_S1);
|
||||
sm.addInt(minLevel);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THERE_ARE_NO_OTHER_SKILLS_TO_LEARN);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(new ExAcquirableSkillListByClass(skills, AcquireSkillType.COLLECT));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!npc.getTemplate().canTeach(classId))
|
||||
{
|
||||
npc.showNoTeachHtml(player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (((L2NpcInstance) npc).getClassesToTeach().isEmpty())
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(npc.getObjectId());
|
||||
final String sb = StringUtil.concat("<html><body>I cannot teach you. My class list is empty.<br>Ask admin to fix it. Need add my npcid and classes to skill_learn.sql.<br>NpcId:", String.valueOf(npcId), ", Your classId:", String.valueOf(player.getClassId().getId()), "</body></html>");
|
||||
html.setHtml(sb);
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
|
||||
// Normal skills, No LearnedByFS, no AutoGet skills.
|
||||
final List<L2SkillLearn> skills = SkillTreesData.getInstance().getAvailableSkills(player, classId, false, false);
|
||||
player.setLearningClass(classId);
|
||||
|
||||
if (skills.isEmpty())
|
||||
{
|
||||
final Map<Integer, L2SkillLearn> skillTree = SkillTreesData.getInstance().getCompleteClassSkillTree(classId);
|
||||
final int minLevel = SkillTreesData.getInstance().getMinLevelForNewSkill(player, skillTree);
|
||||
if (minLevel > 0)
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_DO_NOT_HAVE_ANY_FURTHER_SKILLS_TO_LEARN_COME_BACK_WHEN_YOU_HAVE_REACHED_LEVEL_S1);
|
||||
sm.addInt(minLevel);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player.getClassId().level() == 1)
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.THERE_ARE_NO_OTHER_SKILLS_TO_LEARN_PLEASE_COME_BACK_AFTER_S1ND_CLASS_CHANGE);
|
||||
sm.addInt(2);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THERE_ARE_NO_OTHER_SKILLS_TO_LEARN);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(new ExAcquirableSkillListByClass(skills, AcquireSkillType.CLASS));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
|
||||
/**
|
||||
* @author NightMarez
|
||||
* @version $Revision: 1.3.2.2.2.5 $ $Date: 2005/03/27 15:29:32 $
|
||||
*/
|
||||
public final class L2ObservationInstance extends L2Npc
|
||||
{
|
||||
public L2ObservationInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2ObservationInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showChatWindow(L2PcInstance player, int val)
|
||||
{
|
||||
String filename = null;
|
||||
|
||||
if (isInsideRadius(-79884, 86529, 0, 50, false, true) || isInsideRadius(-78858, 111358, 0, 50, false, true) || isInsideRadius(-76973, 87136, 0, 50, false, true) || isInsideRadius(-75850, 111968, 0, 50, false, true))
|
||||
{
|
||||
if (val == 0)
|
||||
{
|
||||
filename = "data/html/observation/" + getId() + "-Oracle.htm";
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = "data/html/observation/" + getId() + "-Oracle-" + val + ".htm";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (val == 0)
|
||||
{
|
||||
filename = "data/html/observation/" + getId() + ".htm";
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = "data/html/observation/" + getId() + "-" + val + ".htm";
|
||||
}
|
||||
}
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.olympiad.Olympiad;
|
||||
|
||||
/**
|
||||
* Olympiad Npc's Instance
|
||||
* @author godson
|
||||
*/
|
||||
public class L2OlympiadManagerInstance extends L2Npc
|
||||
{
|
||||
public L2OlympiadManagerInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2OlympiadManagerInstance);
|
||||
}
|
||||
|
||||
public void showChatWindow(L2PcInstance player, int val, String suffix)
|
||||
{
|
||||
String filename = Olympiad.OLYMPIAD_HTML_PATH;
|
||||
|
||||
filename += "noble_desc" + val;
|
||||
filename += (suffix != null) ? suffix + ".htm" : ".htm";
|
||||
|
||||
if (filename.equals(Olympiad.OLYMPIAD_HTML_PATH + "noble_desc0.htm"))
|
||||
{
|
||||
filename = Olympiad.OLYMPIAD_HTML_PATH + "noble_main.htm";
|
||||
}
|
||||
|
||||
showChatWindow(player, filename);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jserver.gameserver.util.Evolve;
|
||||
|
||||
public class L2PetManagerInstance extends L2MerchantInstance
|
||||
{
|
||||
public L2PetManagerInstance(int objectID, L2NpcTemplate template)
|
||||
{
|
||||
super(objectID, template);
|
||||
setInstanceType(InstanceType.L2PetManagerInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "data/html/petmanager/" + pom + ".htm";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showChatWindow(L2PcInstance player)
|
||||
{
|
||||
String filename = "data/html/petmanager/" + getId() + ".htm";
|
||||
if ((getId() == 36478) && player.hasSummon())
|
||||
{
|
||||
filename = "data/html/petmanager/restore-unsummonpet.htm";
|
||||
}
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
if (Config.ALLOW_RENTPET && Config.LIST_PET_RENT_NPC.contains(getId()))
|
||||
{
|
||||
html.replace("_Quest", "_RentPet\">Rent Pet</a><br><a action=\"bypass -h npc_%objectId%_Quest");
|
||||
}
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
html.replace("%npcname%", getName());
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
if (command.startsWith("exchange"))
|
||||
{
|
||||
String[] params = command.split(" ");
|
||||
int val = Integer.parseInt(params[1]);
|
||||
switch (val)
|
||||
{
|
||||
case 1:
|
||||
exchange(player, 7585, 6650);
|
||||
break;
|
||||
case 2:
|
||||
exchange(player, 7583, 6648);
|
||||
break;
|
||||
case 3:
|
||||
exchange(player, 7584, 6649);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (command.startsWith("evolve"))
|
||||
{
|
||||
String[] params = command.split(" ");
|
||||
int val = Integer.parseInt(params[1]);
|
||||
boolean ok = false;
|
||||
switch (val)
|
||||
{
|
||||
// Info evolve(player, "curent pet summon item", "new pet summon item", "lvl required to evolve")
|
||||
// To ignore evolve just put value 0 where do you like example: evolve(player, 0, 9882, 55);
|
||||
case 1:
|
||||
ok = Evolve.doEvolve(player, this, 2375, 9882, 55);
|
||||
break;
|
||||
case 2:
|
||||
ok = Evolve.doEvolve(player, this, 9882, 10426, 70);
|
||||
break;
|
||||
case 3:
|
||||
ok = Evolve.doEvolve(player, this, 6648, 10311, 55);
|
||||
break;
|
||||
case 4:
|
||||
ok = Evolve.doEvolve(player, this, 6650, 10313, 55);
|
||||
break;
|
||||
case 5:
|
||||
ok = Evolve.doEvolve(player, this, 6649, 10312, 55);
|
||||
break;
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/petmanager/evolve_no.htm");
|
||||
player.sendPacket(html);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (command.startsWith("restore"))
|
||||
{
|
||||
String[] params = command.split(" ");
|
||||
int val = Integer.parseInt(params[1]);
|
||||
boolean ok = false;
|
||||
switch (val)
|
||||
{
|
||||
// Info evolve(player, "curent pet summon item", "new pet summon item", "lvl required to evolve")
|
||||
case 1:
|
||||
ok = Evolve.doRestore(player, this, 10307, 9882, 55);
|
||||
break;
|
||||
case 2:
|
||||
ok = Evolve.doRestore(player, this, 10611, 10426, 70);
|
||||
break;
|
||||
case 3:
|
||||
ok = Evolve.doRestore(player, this, 10308, 4422, 55);
|
||||
break;
|
||||
case 4:
|
||||
ok = Evolve.doRestore(player, this, 10309, 4423, 55);
|
||||
break;
|
||||
case 5:
|
||||
ok = Evolve.doRestore(player, this, 10310, 4424, 55);
|
||||
break;
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/petmanager/restore_no.htm");
|
||||
player.sendPacket(html);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onBypassFeedback(player, command);
|
||||
}
|
||||
}
|
||||
|
||||
public final void exchange(L2PcInstance player, int itemIdtake, int itemIdgive)
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
if (player.destroyItemByItemId("Consume", itemIdtake, 1, this, true))
|
||||
{
|
||||
player.addItem("", itemIdgive, 1, this, true);
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/petmanager/" + getId() + ".htm");
|
||||
player.sendPacket(html);
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/petmanager/exchange_no.htm");
|
||||
player.sendPacket(html);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableAttack;
|
||||
import com.l2jserver.gameserver.model.events.impl.character.npc.attackable.OnAttackableKill;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* This class extends Guard class for quests, that require tracking of onAttack and onKill events from monsters' attacks.
|
||||
* @author GKR
|
||||
*/
|
||||
public final class L2QuestGuardInstance extends L2GuardInstance
|
||||
{
|
||||
private boolean _isAutoAttackable = true;
|
||||
private boolean _isPassive = false;
|
||||
|
||||
public L2QuestGuardInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2QuestGuardInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDamage(L2Character attacker, int damage, Skill skill)
|
||||
{
|
||||
super.addDamage(attacker, damage, skill);
|
||||
|
||||
if (attacker instanceof L2Attackable)
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnAttackableAttack(null, this, damage, skill, false), this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
// Kill the L2NpcInstance (the corpse disappeared after 7 seconds)
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (killer instanceof L2Attackable)
|
||||
{
|
||||
// Delayed notification
|
||||
EventDispatcher.getInstance().notifyEventAsyncDelayed(new OnAttackableKill(null, this, false), this, _onKillDelay);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDamageHate(L2Character attacker, int damage, int aggro)
|
||||
{
|
||||
if (!_isPassive && !(attacker instanceof L2PcInstance))
|
||||
{
|
||||
super.addDamageHate(attacker, damage, aggro);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPassive(boolean state)
|
||||
{
|
||||
_isPassive = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
return _isAutoAttackable && !(attacker instanceof L2PcInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAutoAttackable(boolean state)
|
||||
{
|
||||
_isAutoAttackable = state;
|
||||
}
|
||||
|
||||
public boolean isPassive()
|
||||
{
|
||||
return _isPassive;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,546 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import com.l2jserver.gameserver.MonsterRace;
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.knownlist.RaceManagerKnownList;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jserver.gameserver.network.serverpackets.DeleteObject;
|
||||
import com.l2jserver.gameserver.network.serverpackets.InventoryUpdate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
|
||||
import com.l2jserver.gameserver.network.serverpackets.MonRaceInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jserver.gameserver.util.Broadcast;
|
||||
|
||||
public class L2RaceManagerInstance extends L2Npc
|
||||
{
|
||||
public static final int LANES = 8;
|
||||
public static final int WINDOW_START = 0;
|
||||
|
||||
// private static List<Race> _history;
|
||||
private static List<L2RaceManagerInstance> _managers;
|
||||
protected static int _raceNumber = 4;
|
||||
|
||||
// Time Constants
|
||||
private static final long SECOND = 1000;
|
||||
private static final long MINUTE = 60 * SECOND;
|
||||
|
||||
private static int _minutes = 5;
|
||||
|
||||
// States
|
||||
private static final int ACCEPTING_BETS = 0;
|
||||
private static final int WAITING = 1;
|
||||
private static final int STARTING_RACE = 2;
|
||||
private static final int RACE_END = 3;
|
||||
private static int _state = RACE_END;
|
||||
|
||||
protected static final int[][] _codes =
|
||||
{
|
||||
{
|
||||
-1,
|
||||
0
|
||||
},
|
||||
{
|
||||
0,
|
||||
15322
|
||||
},
|
||||
{
|
||||
13765,
|
||||
-1
|
||||
}
|
||||
};
|
||||
private static boolean _notInitialized = true;
|
||||
protected static MonRaceInfo _packet;
|
||||
protected static final int _cost[] =
|
||||
{
|
||||
100,
|
||||
500,
|
||||
1000,
|
||||
5000,
|
||||
10000,
|
||||
20000,
|
||||
50000,
|
||||
100000
|
||||
};
|
||||
|
||||
public L2RaceManagerInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2RaceManagerInstance);
|
||||
if (_notInitialized)
|
||||
{
|
||||
_notInitialized = false;
|
||||
|
||||
// _history = new FastList<>();
|
||||
_managers = new FastList<>();
|
||||
|
||||
ThreadPoolManager s = ThreadPoolManager.getInstance();
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.TICKETS_ARE_NOW_AVAILABLE_FOR_MONSTER_RACE_S1), 0, 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.NOW_SELLING_TICKETS_FOR_MONSTER_RACE_S1), 30 * SECOND, 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.TICKETS_ARE_NOW_AVAILABLE_FOR_MONSTER_RACE_S1), MINUTE, 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.NOW_SELLING_TICKETS_FOR_MONSTER_RACE_S1), MINUTE + (30 * SECOND), 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.TICKET_SALES_FOR_THE_MONSTER_RACE_WILL_END_IN_S1_MINUTE_S), 2 * MINUTE, 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.TICKET_SALES_FOR_THE_MONSTER_RACE_WILL_END_IN_S1_MINUTE_S), 3 * MINUTE, 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.TICKET_SALES_FOR_THE_MONSTER_RACE_WILL_END_IN_S1_MINUTE_S), 4 * MINUTE, 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.TICKET_SALES_FOR_THE_MONSTER_RACE_WILL_END_IN_S1_MINUTE_S), 5 * MINUTE, 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.TICKET_SALES_FOR_THE_MONSTER_RACE_WILL_END_IN_S1_MINUTE_S), 6 * MINUTE, 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.TICKETS_SALES_ARE_CLOSED_FOR_MONSTER_RACE_S1_ODDS_ARE_POSTED), 7 * MINUTE, 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.MONSTER_RACE_S2_WILL_BEGIN_IN_S1_MINUTE_S), 7 * MINUTE, 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.MONSTER_RACE_S2_WILL_BEGIN_IN_S1_MINUTE_S), 8 * MINUTE, 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.MONSTER_RACE_S1_WILL_BEGIN_IN_30_SECONDS), (8 * MINUTE) + (30 * SECOND), 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.MONSTER_RACE_S1_IS_ABOUT_TO_BEGIN_COUNTDOWN_IN_FIVE_SECONDS), (8 * MINUTE) + (50 * SECOND), 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.THE_RACE_WILL_BEGIN_IN_S1_SECOND_S), (8 * MINUTE) + (55 * SECOND), 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.THE_RACE_WILL_BEGIN_IN_S1_SECOND_S), (8 * MINUTE) + (56 * SECOND), 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.THE_RACE_WILL_BEGIN_IN_S1_SECOND_S), (8 * MINUTE) + (57 * SECOND), 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.THE_RACE_WILL_BEGIN_IN_S1_SECOND_S), (8 * MINUTE) + (58 * SECOND), 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.THE_RACE_WILL_BEGIN_IN_S1_SECOND_S), (8 * MINUTE) + (59 * SECOND), 10 * MINUTE);
|
||||
s.scheduleGeneralAtFixedRate(new Announcement(SystemMessageId.THEY_RE_OFF), 9 * MINUTE, 10 * MINUTE);
|
||||
// */
|
||||
}
|
||||
_managers.add(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RaceManagerKnownList getKnownList()
|
||||
{
|
||||
return (RaceManagerKnownList) super.getKnownList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initKnownList()
|
||||
{
|
||||
setKnownList(new RaceManagerKnownList(this));
|
||||
}
|
||||
|
||||
class Announcement implements Runnable
|
||||
{
|
||||
private final SystemMessageId _type;
|
||||
|
||||
public Announcement(SystemMessageId pType)
|
||||
{
|
||||
_type = pType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
makeAnnouncement(_type);
|
||||
}
|
||||
}
|
||||
|
||||
public void makeAnnouncement(SystemMessageId type)
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(type);
|
||||
switch (type.getId())
|
||||
{
|
||||
case 816: // SystemMessageId.TICKETS_ARE_NOW_AVAILABLE_FOR_MONSTER_RACE_S1
|
||||
case 817: // SystemMessageId.NOW_SELLING_TICKETS_FOR_MONSTER_RACE_S1
|
||||
if (_state != ACCEPTING_BETS)
|
||||
{// _log.info("Race Initializing");
|
||||
_state = ACCEPTING_BETS;
|
||||
startRace();
|
||||
}// else{_log.info("Race open");}
|
||||
sm.addInt(_raceNumber);
|
||||
break;
|
||||
case 818: // SystemMessageId.TICKET_SALES_FOR_THE_MONSTER_RACE_WILL_END_IN_S1_MINUTE_S
|
||||
case 820: // SystemMessageId.MONSTER_RACE_S2_WILL_BEGIN_IN_S1_MINUTE_S
|
||||
case 823: // SystemMessageId.THE_RACE_WILL_BEGIN_IN_S1_SECOND_S
|
||||
sm.addInt(_minutes);
|
||||
if (type.getId() == 820)
|
||||
{
|
||||
sm.addInt(_raceNumber);
|
||||
}
|
||||
_minutes--;
|
||||
break;
|
||||
case 819: // SystemMessageId.TICKETS_SALES_ARE_CLOSED_FOR_MONSTER_RACE_S1_ODDS_ARE_POSTED
|
||||
// _log.info("Sales closed");
|
||||
sm.addInt(_raceNumber);
|
||||
_state = WAITING;
|
||||
_minutes = 2;
|
||||
break;
|
||||
case 821: // SystemMessageId.MONSTER_RACE_S1_WILL_BEGIN_IN_30_SECONDS
|
||||
case 822: // SystemMessageId.MONSTER_RACE_S1_IS_ABOUT_TO_BEGIN_COUNTDOWN_IN_FIVE_SECONDS
|
||||
case 825: // SystemMessageId.MONSTER_RACE_S1_IS_FINISHED
|
||||
sm.addInt(_raceNumber);
|
||||
_minutes = 5;
|
||||
break;
|
||||
case 826: // SystemMessageId.FIRST_PRIZE_GOES_TO_THE_PLAYER_IN_LANE_S1_SECOND_PRIZE_GOES_TO_THE_PLAYER_IN_LANE_S2
|
||||
// _log.info("Placing");
|
||||
_state = RACE_END;
|
||||
sm.addInt(MonsterRace.getInstance().getFirstPlace());
|
||||
sm.addInt(MonsterRace.getInstance().getSecondPlace());
|
||||
break;
|
||||
}
|
||||
// _logn.info("Counter: "+minutes);
|
||||
// _log.info("State: "+state);
|
||||
broadcast(sm);
|
||||
// _log.info("Player's known: "+getKnownPlayers().size());
|
||||
|
||||
if (type == SystemMessageId.THEY_RE_OFF)
|
||||
{
|
||||
// _log.info("Starting race");
|
||||
_state = STARTING_RACE;
|
||||
startRace();
|
||||
_minutes = 5;
|
||||
}
|
||||
}
|
||||
|
||||
protected void broadcast(L2GameServerPacket pkt)
|
||||
{
|
||||
for (L2RaceManagerInstance manager : _managers)
|
||||
{
|
||||
if (!manager.isDead())
|
||||
{
|
||||
Broadcast.toKnownPlayers(manager, pkt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMonsterInfo()
|
||||
{
|
||||
broadcast(_packet);
|
||||
}
|
||||
|
||||
private void startRace()
|
||||
{
|
||||
MonsterRace race = MonsterRace.getInstance();
|
||||
if (_state == STARTING_RACE)
|
||||
{
|
||||
// state++;
|
||||
PlaySound SRace = new PlaySound(1, "S_Race", 0, 0, 0, 0, 0);
|
||||
broadcast(SRace);
|
||||
PlaySound SRace2 = new PlaySound(0, "ItemSound2.race_start", 1, 121209259, 12125, 182487, -3559);
|
||||
broadcast(SRace2);
|
||||
_packet = new MonRaceInfo(_codes[1][0], _codes[1][1], race.getMonsters(), race.getSpeeds());
|
||||
sendMonsterInfo();
|
||||
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new RunRace(), 5000);
|
||||
}
|
||||
else
|
||||
{
|
||||
// state++;
|
||||
race.newRace();
|
||||
race.newSpeeds();
|
||||
_packet = new MonRaceInfo(_codes[0][0], _codes[0][1], race.getMonsters(), race.getSpeeds());
|
||||
sendMonsterInfo();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
if (command.startsWith("BuyTicket") && (_state != ACCEPTING_BETS))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.MONSTER_RACE_TICKETS_ARE_NO_LONGER_AVAILABLE);
|
||||
command = "Chat 0";
|
||||
}
|
||||
if (command.startsWith("ShowOdds") && (_state == ACCEPTING_BETS))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.MONSTER_RACE_PAYOUT_INFORMATION_IS_NOT_AVAILABLE_WHILE_TICKETS_ARE_BEING_SOLD);
|
||||
command = "Chat 0";
|
||||
}
|
||||
|
||||
if (command.startsWith("BuyTicket"))
|
||||
{
|
||||
int val = Integer.parseInt(command.substring(10));
|
||||
if (val == 0)
|
||||
{
|
||||
player.setRace(0, 0);
|
||||
player.setRace(1, 0);
|
||||
}
|
||||
if (((val == 10) && (player.getRace(0) == 0)) || ((val == 20) && (player.getRace(0) == 0) && (player.getRace(1) == 0)))
|
||||
{
|
||||
val = 0;
|
||||
}
|
||||
showBuyTicket(player, val);
|
||||
}
|
||||
else if (command.equals("ShowOdds"))
|
||||
{
|
||||
showOdds(player);
|
||||
}
|
||||
else if (command.equals("ShowInfo"))
|
||||
{
|
||||
showMonsterInfo(player);
|
||||
}
|
||||
else if (command.equals("calculateWin"))
|
||||
{
|
||||
// displayCalculateWinnings(player);
|
||||
}
|
||||
else if (command.equals("viewHistory"))
|
||||
{
|
||||
// displayHistory(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
// getKnownList().removeKnownObject(player);
|
||||
super.onBypassFeedback(player, command);
|
||||
}
|
||||
}
|
||||
|
||||
public void showOdds(L2PcInstance player)
|
||||
{
|
||||
if (_state == ACCEPTING_BETS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int npcId = getTemplate().getId();
|
||||
String filename, search;
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
filename = getHtmlPath(npcId, 5);
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
int n = i + 1;
|
||||
search = "Mob" + n;
|
||||
html.replace(search, MonsterRace.getInstance().getMonsters()[i].getTemplate().getName());
|
||||
}
|
||||
html.replace("1race", String.valueOf(_raceNumber));
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
public void showMonsterInfo(L2PcInstance player)
|
||||
{
|
||||
int npcId = getTemplate().getId();
|
||||
String filename, search;
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
filename = getHtmlPath(npcId, 6);
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
int n = i + 1;
|
||||
search = "Mob" + n;
|
||||
html.replace(search, MonsterRace.getInstance().getMonsters()[i].getTemplate().getName());
|
||||
}
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
public void showBuyTicket(L2PcInstance player, int val)
|
||||
{
|
||||
if (_state != ACCEPTING_BETS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int npcId = getTemplate().getId();
|
||||
SystemMessage sm;
|
||||
String filename, search, replace;
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
if (val < 10)
|
||||
{
|
||||
filename = getHtmlPath(npcId, 2);
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
int n = i + 1;
|
||||
search = "Mob" + n;
|
||||
html.replace(search, MonsterRace.getInstance().getMonsters()[i].getTemplate().getName());
|
||||
}
|
||||
search = "No1";
|
||||
if (val == 0)
|
||||
{
|
||||
html.replace(search, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
html.replace(search, "" + val);
|
||||
player.setRace(0, val);
|
||||
}
|
||||
}
|
||||
else if (val < 20)
|
||||
{
|
||||
if (player.getRace(0) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
filename = getHtmlPath(npcId, 3);
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("0place", "" + player.getRace(0));
|
||||
search = "Mob1";
|
||||
replace = MonsterRace.getInstance().getMonsters()[player.getRace(0) - 1].getTemplate().getName();
|
||||
html.replace(search, replace);
|
||||
search = "0adena";
|
||||
if (val == 10)
|
||||
{
|
||||
html.replace(search, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
html.replace(search, "" + _cost[val - 11]);
|
||||
player.setRace(1, val - 10);
|
||||
}
|
||||
}
|
||||
else if (val == 20)
|
||||
{
|
||||
if ((player.getRace(0) == 0) || (player.getRace(1) == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
filename = getHtmlPath(npcId, 4);
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("0place", "" + player.getRace(0));
|
||||
search = "Mob1";
|
||||
replace = MonsterRace.getInstance().getMonsters()[player.getRace(0) - 1].getTemplate().getName();
|
||||
html.replace(search, replace);
|
||||
search = "0adena";
|
||||
int price = _cost[player.getRace(1) - 1];
|
||||
html.replace(search, "" + price);
|
||||
search = "0tax";
|
||||
int tax = 0;
|
||||
html.replace(search, "" + tax);
|
||||
search = "0total";
|
||||
int total = price + tax;
|
||||
html.replace(search, "" + total);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((player.getRace(0) == 0) || (player.getRace(1) == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
int ticket = player.getRace(0);
|
||||
int priceId = player.getRace(1);
|
||||
if (!player.reduceAdena("Race", _cost[priceId - 1], this, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
player.setRace(0, 0);
|
||||
player.setRace(1, 0);
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.ACQUIRED_S1_S2);
|
||||
sm.addInt(_raceNumber);
|
||||
sm.addItemName(4443);
|
||||
player.sendPacket(sm);
|
||||
L2ItemInstance item = new L2ItemInstance(IdFactory.getInstance().getNextId(), 4443);
|
||||
item.setCount(1);
|
||||
item.setEnchantLevel(_raceNumber);
|
||||
item.setCustomType1(ticket);
|
||||
item.setCustomType2(_cost[priceId - 1] / 100);
|
||||
player.getInventory().addItem("Race", item, player, this);
|
||||
InventoryUpdate iu = new InventoryUpdate();
|
||||
iu.addItem(item);
|
||||
L2ItemInstance adenaupdate = player.getInventory().getItemByItemId(Inventory.ADENA_ID);
|
||||
iu.addModifiedItem(adenaupdate);
|
||||
player.sendPacket(iu);
|
||||
return;
|
||||
}
|
||||
html.replace("1race", String.valueOf(_raceNumber));
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
public static class Race
|
||||
{
|
||||
private final Info[] _info;
|
||||
|
||||
public Race(Info[] pInfo)
|
||||
{
|
||||
_info = pInfo;
|
||||
}
|
||||
|
||||
public Info getLaneInfo(int lane)
|
||||
{
|
||||
return _info[lane];
|
||||
}
|
||||
|
||||
public class Info
|
||||
{
|
||||
private final int _id;
|
||||
private final int _place;
|
||||
private final int _odds;
|
||||
private final int _payout;
|
||||
|
||||
public Info(int pId, int pPlace, int pOdds, int pPayout)
|
||||
{
|
||||
_id = pId;
|
||||
_place = pPlace;
|
||||
_odds = pOdds;
|
||||
_payout = pPayout;
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
public int getOdds()
|
||||
{
|
||||
return _odds;
|
||||
}
|
||||
|
||||
public int getPayout()
|
||||
{
|
||||
return _payout;
|
||||
}
|
||||
|
||||
public int getPlace()
|
||||
{
|
||||
return _place;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RunRace implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
_packet = new MonRaceInfo(_codes[2][0], _codes[2][1], MonsterRace.getInstance().getMonsters(), MonsterRace.getInstance().getSpeeds());
|
||||
sendMonsterInfo();
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new RunEnd(), 30000);
|
||||
}
|
||||
}
|
||||
|
||||
class RunEnd implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
makeAnnouncement(SystemMessageId.FIRST_PRIZE_GOES_TO_THE_PLAYER_IN_LANE_S1_SECOND_PRIZE_GOES_TO_THE_PLAYER_IN_LANE_S2);
|
||||
makeAnnouncement(SystemMessageId.MONSTER_RACE_S1_IS_FINISHED);
|
||||
_raceNumber++;
|
||||
|
||||
DeleteObject obj = null;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
obj = new DeleteObject(MonsterRace.getInstance().getMonsters()[i]);
|
||||
broadcast(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.RaidBossPointsManager;
|
||||
import com.l2jserver.gameserver.instancemanager.RaidBossSpawnManager;
|
||||
import com.l2jserver.gameserver.model.L2Spawn;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.entity.Hero;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jserver.util.Rnd;
|
||||
|
||||
/**
|
||||
* This class manages all RaidBoss.<br>
|
||||
* In a group mob, there are one master called RaidBoss and several slaves called Minions.
|
||||
*/
|
||||
public class L2RaidBossInstance extends L2MonsterInstance
|
||||
{
|
||||
private static final int RAIDBOSS_MAINTENANCE_INTERVAL = 30000; // 30 sec
|
||||
|
||||
private RaidBossSpawnManager.StatusEnum _raidStatus;
|
||||
private boolean _useRaidCurse = true;
|
||||
|
||||
/**
|
||||
* Constructor of L2RaidBossInstance (use L2Character and L2NpcInstance constructor).<br>
|
||||
* <B><U>Actions</U>:</B>
|
||||
* <ul>
|
||||
* <li>Call the L2Character constructor to set the _template of the L2RaidBossInstance (copy skills from template to object and link _calculators to NPC_STD_CALCULATOR)</li>
|
||||
* <li>Set the name of the L2RaidBossInstance</li>
|
||||
* <li>Create a RandomAnimation Task that will be launched after the calculated delay if the server allow it</li>
|
||||
* </ul>
|
||||
* @param objectId the identifier of the object to initialized
|
||||
* @param template to apply to the NPC
|
||||
*/
|
||||
public L2RaidBossInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2RaidBossInstance);
|
||||
setIsRaid(true);
|
||||
setLethalable(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
setIsNoRndWalk(true);
|
||||
super.onSpawn();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaintenanceInterval()
|
||||
{
|
||||
return RAIDBOSS_MAINTENANCE_INTERVAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final L2PcInstance player = killer.getActingPlayer();
|
||||
if (player != null)
|
||||
{
|
||||
broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_YOUR_RAID_WAS_SUCCESSFUL));
|
||||
if (player.getParty() != null)
|
||||
{
|
||||
for (L2PcInstance member : player.getParty().getMembers())
|
||||
{
|
||||
RaidBossPointsManager.getInstance().addPoints(member, getId(), (getLevel() / 2) + Rnd.get(-5, 5));
|
||||
if (member.isNoble())
|
||||
{
|
||||
Hero.getInstance().setRBkilled(member.getObjectId(), getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RaidBossPointsManager.getInstance().addPoints(player, getId(), (getLevel() / 2) + Rnd.get(-5, 5));
|
||||
if (player.isNoble())
|
||||
{
|
||||
Hero.getInstance().setRBkilled(player.getObjectId(), getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RaidBossSpawnManager.getInstance().updateStatus(this, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn all minions at a regular interval Also if boss is too far from home location at the time of this check, teleport it home.
|
||||
*/
|
||||
@Override
|
||||
protected void startMaintenanceTask()
|
||||
{
|
||||
_maintenanceTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(() -> checkAndReturnToSpawn(), 60000, getMaintenanceInterval() + Rnd.get(5000));
|
||||
}
|
||||
|
||||
protected void checkAndReturnToSpawn()
|
||||
{
|
||||
if (isDead() || isMovementDisabled() || !canReturnToSpawnPoint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final L2Spawn spawn = getSpawn();
|
||||
if (spawn == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int spawnX = spawn.getX();
|
||||
final int spawnY = spawn.getY();
|
||||
final int spawnZ = spawn.getZ();
|
||||
|
||||
if (!isInCombat() && !isMovementDisabled())
|
||||
{
|
||||
if (!isInsideRadius(spawnX, spawnY, spawnZ, Math.max(Config.MAX_DRIFT_RANGE, 200), true, false))
|
||||
{
|
||||
teleToLocation(spawnX, spawnY, spawnZ, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setRaidStatus(RaidBossSpawnManager.StatusEnum status)
|
||||
{
|
||||
_raidStatus = status;
|
||||
}
|
||||
|
||||
public RaidBossSpawnManager.StatusEnum getRaidStatus()
|
||||
{
|
||||
return _raidStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getVitalityPoints(int damage)
|
||||
{
|
||||
return -super.getVitalityPoints(damage) / 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useVitalityRate()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setUseRaidCurse(boolean val)
|
||||
{
|
||||
_useRaidCurse = val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean giveRaidCurse()
|
||||
{
|
||||
return _useRaidCurse;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,524 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.FourSepulchersManager;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.quest.QuestState;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
|
||||
/**
|
||||
* @author sandman
|
||||
*/
|
||||
public class L2SepulcherMonsterInstance extends L2MonsterInstance
|
||||
{
|
||||
protected static final SkillHolder FAKE_PETRIFICATION = new SkillHolder(4616, 1);
|
||||
|
||||
public int mysteriousBoxId = 0;
|
||||
|
||||
protected Future<?> _victimSpawnKeyBoxTask = null;
|
||||
protected Future<?> _victimShout = null;
|
||||
protected Future<?> _changeImmortalTask = null;
|
||||
protected Future<?> _onDeadEventTask = null;
|
||||
|
||||
public L2SepulcherMonsterInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2SepulcherMonsterInstance);
|
||||
setShowSummonAnimation(true);
|
||||
switch (template.getId())
|
||||
{
|
||||
case 25339:
|
||||
case 25342:
|
||||
case 25346:
|
||||
case 25349:
|
||||
setIsRaid(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
setShowSummonAnimation(false);
|
||||
switch (getId())
|
||||
{
|
||||
case 18150:
|
||||
case 18151:
|
||||
case 18152:
|
||||
case 18153:
|
||||
case 18154:
|
||||
case 18155:
|
||||
case 18156:
|
||||
case 18157:
|
||||
if (_victimSpawnKeyBoxTask != null)
|
||||
{
|
||||
_victimSpawnKeyBoxTask.cancel(true);
|
||||
}
|
||||
_victimSpawnKeyBoxTask = ThreadPoolManager.getInstance().scheduleEffect(new VictimSpawnKeyBox(this), 300000);
|
||||
if (_victimShout != null)
|
||||
{
|
||||
_victimShout.cancel(true);
|
||||
}
|
||||
_victimShout = ThreadPoolManager.getInstance().scheduleEffect(new VictimShout(this), 5000);
|
||||
break;
|
||||
case 18196:
|
||||
case 18197:
|
||||
case 18198:
|
||||
case 18199:
|
||||
case 18200:
|
||||
case 18201:
|
||||
case 18202:
|
||||
case 18203:
|
||||
case 18204:
|
||||
case 18205:
|
||||
case 18206:
|
||||
case 18207:
|
||||
case 18208:
|
||||
case 18209:
|
||||
case 18210:
|
||||
case 18211:
|
||||
break;
|
||||
|
||||
case 18231:
|
||||
case 18232:
|
||||
case 18233:
|
||||
case 18234:
|
||||
case 18235:
|
||||
case 18236:
|
||||
case 18237:
|
||||
case 18238:
|
||||
case 18239:
|
||||
case 18240:
|
||||
case 18241:
|
||||
case 18242:
|
||||
case 18243:
|
||||
if (_changeImmortalTask != null)
|
||||
{
|
||||
_changeImmortalTask.cancel(true);
|
||||
}
|
||||
_changeImmortalTask = ThreadPoolManager.getInstance().scheduleEffect(new ChangeImmortal(this), 1600);
|
||||
|
||||
break;
|
||||
case 18256:
|
||||
break;
|
||||
case 25339:
|
||||
case 25342:
|
||||
case 25346:
|
||||
case 25349:
|
||||
setIsRaid(true);
|
||||
break;
|
||||
}
|
||||
super.onSpawn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (getId())
|
||||
{
|
||||
case 18120:
|
||||
case 18121:
|
||||
case 18122:
|
||||
case 18123:
|
||||
case 18124:
|
||||
case 18125:
|
||||
case 18126:
|
||||
case 18127:
|
||||
case 18128:
|
||||
case 18129:
|
||||
case 18130:
|
||||
case 18131:
|
||||
case 18149:
|
||||
case 18158:
|
||||
case 18159:
|
||||
case 18160:
|
||||
case 18161:
|
||||
case 18162:
|
||||
case 18163:
|
||||
case 18164:
|
||||
case 18165:
|
||||
case 18183:
|
||||
case 18184:
|
||||
case 18212:
|
||||
case 18213:
|
||||
case 18214:
|
||||
case 18215:
|
||||
case 18216:
|
||||
case 18217:
|
||||
case 18218:
|
||||
case 18219:
|
||||
if (_onDeadEventTask != null)
|
||||
{
|
||||
_onDeadEventTask.cancel(true);
|
||||
}
|
||||
_onDeadEventTask = ThreadPoolManager.getInstance().scheduleEffect(new OnDeadEvent(this), 3500);
|
||||
break;
|
||||
|
||||
case 18150:
|
||||
case 18151:
|
||||
case 18152:
|
||||
case 18153:
|
||||
case 18154:
|
||||
case 18155:
|
||||
case 18156:
|
||||
case 18157:
|
||||
if (_victimSpawnKeyBoxTask != null)
|
||||
{
|
||||
_victimSpawnKeyBoxTask.cancel(true);
|
||||
_victimSpawnKeyBoxTask = null;
|
||||
}
|
||||
if (_victimShout != null)
|
||||
{
|
||||
_victimShout.cancel(true);
|
||||
_victimShout = null;
|
||||
}
|
||||
if (_onDeadEventTask != null)
|
||||
{
|
||||
_onDeadEventTask.cancel(true);
|
||||
}
|
||||
_onDeadEventTask = ThreadPoolManager.getInstance().scheduleEffect(new OnDeadEvent(this), 3500);
|
||||
break;
|
||||
|
||||
case 18141:
|
||||
case 18142:
|
||||
case 18143:
|
||||
case 18144:
|
||||
case 18145:
|
||||
case 18146:
|
||||
case 18147:
|
||||
case 18148:
|
||||
if (FourSepulchersManager.getInstance().isViscountMobsAnnihilated(mysteriousBoxId))
|
||||
{
|
||||
if (_onDeadEventTask != null)
|
||||
{
|
||||
_onDeadEventTask.cancel(true);
|
||||
}
|
||||
_onDeadEventTask = ThreadPoolManager.getInstance().scheduleEffect(new OnDeadEvent(this), 3500);
|
||||
}
|
||||
break;
|
||||
|
||||
case 18220:
|
||||
case 18221:
|
||||
case 18222:
|
||||
case 18223:
|
||||
case 18224:
|
||||
case 18225:
|
||||
case 18226:
|
||||
case 18227:
|
||||
case 18228:
|
||||
case 18229:
|
||||
case 18230:
|
||||
case 18231:
|
||||
case 18232:
|
||||
case 18233:
|
||||
case 18234:
|
||||
case 18235:
|
||||
case 18236:
|
||||
case 18237:
|
||||
case 18238:
|
||||
case 18239:
|
||||
case 18240:
|
||||
if (FourSepulchersManager.getInstance().isDukeMobsAnnihilated(mysteriousBoxId))
|
||||
{
|
||||
if (_onDeadEventTask != null)
|
||||
{
|
||||
_onDeadEventTask.cancel(true);
|
||||
}
|
||||
_onDeadEventTask = ThreadPoolManager.getInstance().scheduleEffect(new OnDeadEvent(this), 3500);
|
||||
}
|
||||
break;
|
||||
|
||||
case 25339:
|
||||
case 25342:
|
||||
case 25346:
|
||||
case 25349:
|
||||
giveCup(killer);
|
||||
if (_onDeadEventTask != null)
|
||||
{
|
||||
_onDeadEventTask.cancel(true);
|
||||
}
|
||||
_onDeadEventTask = ThreadPoolManager.getInstance().scheduleEffect(new OnDeadEvent(this), 8500);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteMe()
|
||||
{
|
||||
if (_victimSpawnKeyBoxTask != null)
|
||||
{
|
||||
_victimSpawnKeyBoxTask.cancel(true);
|
||||
_victimSpawnKeyBoxTask = null;
|
||||
}
|
||||
if (_onDeadEventTask != null)
|
||||
{
|
||||
_onDeadEventTask.cancel(true);
|
||||
_onDeadEventTask = null;
|
||||
}
|
||||
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
private void giveCup(L2Character killer)
|
||||
{
|
||||
String questId = "620_FourGoblets";
|
||||
int cupId = 0;
|
||||
int oldBrooch = 7262;
|
||||
|
||||
switch (getId())
|
||||
{
|
||||
case 25339:
|
||||
cupId = 7256;
|
||||
break;
|
||||
case 25342:
|
||||
cupId = 7257;
|
||||
break;
|
||||
case 25346:
|
||||
cupId = 7258;
|
||||
break;
|
||||
case 25349:
|
||||
cupId = 7259;
|
||||
break;
|
||||
}
|
||||
|
||||
L2PcInstance player = killer.getActingPlayer();
|
||||
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getParty() != null)
|
||||
{
|
||||
for (L2PcInstance mem : player.getParty().getMembers())
|
||||
{
|
||||
QuestState qs = mem.getQuestState(questId);
|
||||
if ((qs != null) && (qs.isStarted() || qs.isCompleted()) && (mem.getInventory().getItemByItemId(oldBrooch) == null))
|
||||
{
|
||||
mem.addItem("Quest", cupId, 1, mem, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QuestState qs = player.getQuestState(questId);
|
||||
if ((qs != null) && (qs.isStarted() || qs.isCompleted()) && (player.getInventory().getItemByItemId(oldBrooch) == null))
|
||||
{
|
||||
player.addItem("Quest", cupId, 1, player, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class VictimShout implements Runnable
|
||||
{
|
||||
private final L2SepulcherMonsterInstance _activeChar;
|
||||
|
||||
public VictimShout(L2SepulcherMonsterInstance activeChar)
|
||||
{
|
||||
_activeChar = activeChar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (_activeChar.isDead())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_activeChar.isVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
broadcastPacket(new NpcSay(getObjectId(), 0, getId(), "forgive me!!"));
|
||||
}
|
||||
}
|
||||
|
||||
private class VictimSpawnKeyBox implements Runnable
|
||||
{
|
||||
private final L2SepulcherMonsterInstance _activeChar;
|
||||
|
||||
public VictimSpawnKeyBox(L2SepulcherMonsterInstance activeChar)
|
||||
{
|
||||
_activeChar = activeChar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (_activeChar.isDead())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_activeChar.isVisible())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FourSepulchersManager.getInstance().spawnKeyBox(_activeChar);
|
||||
broadcastPacket(new NpcSay(getObjectId(), 0, getId(), "Many thanks for rescue me."));
|
||||
if (_victimShout != null)
|
||||
{
|
||||
_victimShout.cancel(true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static class OnDeadEvent implements Runnable
|
||||
{
|
||||
L2SepulcherMonsterInstance _activeChar;
|
||||
|
||||
public OnDeadEvent(L2SepulcherMonsterInstance activeChar)
|
||||
{
|
||||
_activeChar = activeChar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
switch (_activeChar.getId())
|
||||
{
|
||||
case 18120:
|
||||
case 18121:
|
||||
case 18122:
|
||||
case 18123:
|
||||
case 18124:
|
||||
case 18125:
|
||||
case 18126:
|
||||
case 18127:
|
||||
case 18128:
|
||||
case 18129:
|
||||
case 18130:
|
||||
case 18131:
|
||||
case 18149:
|
||||
case 18158:
|
||||
case 18159:
|
||||
case 18160:
|
||||
case 18161:
|
||||
case 18162:
|
||||
case 18163:
|
||||
case 18164:
|
||||
case 18165:
|
||||
case 18183:
|
||||
case 18184:
|
||||
case 18212:
|
||||
case 18213:
|
||||
case 18214:
|
||||
case 18215:
|
||||
case 18216:
|
||||
case 18217:
|
||||
case 18218:
|
||||
case 18219:
|
||||
FourSepulchersManager.getInstance().spawnKeyBox(_activeChar);
|
||||
break;
|
||||
|
||||
case 18150:
|
||||
case 18151:
|
||||
case 18152:
|
||||
case 18153:
|
||||
case 18154:
|
||||
case 18155:
|
||||
case 18156:
|
||||
case 18157:
|
||||
FourSepulchersManager.getInstance().spawnExecutionerOfHalisha(_activeChar);
|
||||
break;
|
||||
|
||||
case 18141:
|
||||
case 18142:
|
||||
case 18143:
|
||||
case 18144:
|
||||
case 18145:
|
||||
case 18146:
|
||||
case 18147:
|
||||
case 18148:
|
||||
FourSepulchersManager.getInstance().spawnMonster(_activeChar.mysteriousBoxId);
|
||||
break;
|
||||
|
||||
case 18220:
|
||||
case 18221:
|
||||
case 18222:
|
||||
case 18223:
|
||||
case 18224:
|
||||
case 18225:
|
||||
case 18226:
|
||||
case 18227:
|
||||
case 18228:
|
||||
case 18229:
|
||||
case 18230:
|
||||
case 18231:
|
||||
case 18232:
|
||||
case 18233:
|
||||
case 18234:
|
||||
case 18235:
|
||||
case 18236:
|
||||
case 18237:
|
||||
case 18238:
|
||||
case 18239:
|
||||
case 18240:
|
||||
FourSepulchersManager.getInstance().spawnArchonOfHalisha(_activeChar.mysteriousBoxId);
|
||||
break;
|
||||
|
||||
case 25339:
|
||||
case 25342:
|
||||
case 25346:
|
||||
case 25349:
|
||||
FourSepulchersManager.getInstance().spawnEmperorsGraveNpc(_activeChar.mysteriousBoxId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ChangeImmortal implements Runnable
|
||||
{
|
||||
L2SepulcherMonsterInstance activeChar;
|
||||
|
||||
public ChangeImmortal(L2SepulcherMonsterInstance mob)
|
||||
{
|
||||
activeChar = mob;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
// Invulnerable by petrification
|
||||
FAKE_PETRIFICATION.getSkill().applyEffects(activeChar, activeChar);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,453 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.DoorTable;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.FourSepulchersManager;
|
||||
import com.l2jserver.gameserver.model.L2World;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jserver.gameserver.model.events.EventType;
|
||||
import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcFirstTalk;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
import com.l2jserver.util.Rnd;
|
||||
|
||||
/**
|
||||
* @author sandman
|
||||
*/
|
||||
public class L2SepulcherNpcInstance extends L2Npc
|
||||
{
|
||||
protected Future<?> _closeTask = null;
|
||||
protected Future<?> _spawnNextMysteriousBoxTask = null;
|
||||
protected Future<?> _spawnMonsterTask = null;
|
||||
|
||||
private static final String HTML_FILE_PATH = "data/html/SepulcherNpc/";
|
||||
private static final int HALLS_KEY = 7260;
|
||||
|
||||
public L2SepulcherNpcInstance(int objectID, L2NpcTemplate template)
|
||||
{
|
||||
super(objectID, template);
|
||||
setInstanceType(InstanceType.L2SepulcherNpcInstance);
|
||||
setShowSummonAnimation(true);
|
||||
|
||||
if (_closeTask != null)
|
||||
{
|
||||
_closeTask.cancel(true);
|
||||
}
|
||||
if (_spawnNextMysteriousBoxTask != null)
|
||||
{
|
||||
_spawnNextMysteriousBoxTask.cancel(true);
|
||||
}
|
||||
if (_spawnMonsterTask != null)
|
||||
{
|
||||
_spawnMonsterTask.cancel(true);
|
||||
}
|
||||
_closeTask = null;
|
||||
_spawnNextMysteriousBoxTask = null;
|
||||
_spawnMonsterTask = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
super.onSpawn();
|
||||
setShowSummonAnimation(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteMe()
|
||||
{
|
||||
if (_closeTask != null)
|
||||
{
|
||||
_closeTask.cancel(true);
|
||||
_closeTask = null;
|
||||
}
|
||||
if (_spawnNextMysteriousBoxTask != null)
|
||||
{
|
||||
_spawnNextMysteriousBoxTask.cancel(true);
|
||||
_spawnNextMysteriousBoxTask = null;
|
||||
}
|
||||
if (_spawnMonsterTask != null)
|
||||
{
|
||||
_spawnMonsterTask.cancel(true);
|
||||
_spawnMonsterTask = null;
|
||||
}
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAction(L2PcInstance player, boolean interact)
|
||||
{
|
||||
if (!canTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the L2PcInstance already target the L2NpcInstance
|
||||
if (this != player.getTarget())
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("new target selected:" + getObjectId());
|
||||
}
|
||||
|
||||
// Set the target of the L2PcInstance player
|
||||
player.setTarget(this);
|
||||
}
|
||||
else if (interact)
|
||||
{
|
||||
// Check if the player is attackable (without a forced attack) and
|
||||
// isn't dead
|
||||
if (isAutoAttackable(player) && !isAlikeDead())
|
||||
{
|
||||
// Check the height difference
|
||||
if (Math.abs(player.getZ() - getZ()) < 400) // this max heigth
|
||||
// difference might
|
||||
// need some tweaking
|
||||
{
|
||||
// Set the L2PcInstance Intention to AI_INTENTION_ATTACK
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send a Server->Client packet ActionFailed (target is out
|
||||
// of attack range) to the L2PcInstance player
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAutoAttackable(player))
|
||||
{
|
||||
// Calculate the distance between the L2PcInstance and the
|
||||
// L2NpcInstance
|
||||
if (!canInteract(player))
|
||||
{
|
||||
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send a Server->Client packet SocialAction to the all
|
||||
// L2PcInstance on the _knownPlayer of the L2NpcInstance
|
||||
// to display a social action of the L2NpcInstance on their
|
||||
// client
|
||||
SocialAction sa = new SocialAction(getObjectId(), Rnd.get(8));
|
||||
broadcastPacket(sa);
|
||||
|
||||
doAction(player);
|
||||
}
|
||||
}
|
||||
// Send a Server->Client ActionFailed to the L2PcInstance in order
|
||||
// to avoid that the client wait another packet
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
|
||||
private void doAction(L2PcInstance player)
|
||||
{
|
||||
if (isDead())
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (getId())
|
||||
{
|
||||
case 31468:
|
||||
case 31469:
|
||||
case 31470:
|
||||
case 31471:
|
||||
case 31472:
|
||||
case 31473:
|
||||
case 31474:
|
||||
case 31475:
|
||||
case 31476:
|
||||
case 31477:
|
||||
case 31478:
|
||||
case 31479:
|
||||
case 31480:
|
||||
case 31481:
|
||||
case 31482:
|
||||
case 31483:
|
||||
case 31484:
|
||||
case 31485:
|
||||
case 31486:
|
||||
case 31487:
|
||||
setIsInvul(false);
|
||||
reduceCurrentHp(getMaxHp() + 1, player, null);
|
||||
if (_spawnMonsterTask != null)
|
||||
{
|
||||
_spawnMonsterTask.cancel(true);
|
||||
}
|
||||
_spawnMonsterTask = ThreadPoolManager.getInstance().scheduleEffect(new SpawnMonster(getId()), 3500);
|
||||
break;
|
||||
|
||||
case 31455:
|
||||
case 31456:
|
||||
case 31457:
|
||||
case 31458:
|
||||
case 31459:
|
||||
case 31460:
|
||||
case 31461:
|
||||
case 31462:
|
||||
case 31463:
|
||||
case 31464:
|
||||
case 31465:
|
||||
case 31466:
|
||||
case 31467:
|
||||
setIsInvul(false);
|
||||
reduceCurrentHp(getMaxHp() + 1, player, null);
|
||||
if ((player.getParty() != null) && !player.getParty().isLeader(player))
|
||||
{
|
||||
player = player.getParty().getLeader();
|
||||
}
|
||||
player.addItem("Quest", HALLS_KEY, 1, player, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
if (hasListener(EventType.ON_NPC_QUEST_START))
|
||||
{
|
||||
player.setLastQuestNpcObject(getObjectId());
|
||||
}
|
||||
|
||||
if (hasListener(EventType.ON_NPC_FIRST_TALK))
|
||||
{
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnNpcFirstTalk(this, player), this);
|
||||
}
|
||||
else
|
||||
{
|
||||
showChatWindow(player, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return HTML_FILE_PATH + pom + ".htm";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showChatWindow(L2PcInstance player, int val)
|
||||
{
|
||||
String filename = getHtmlPath(getId(), val);
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
if (isBusy())
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/npcbusy.htm");
|
||||
html.replace("%busymessage%", getBusyMessage());
|
||||
html.replace("%npcname%", getName());
|
||||
html.replace("%playername%", player.getName());
|
||||
player.sendPacket(html);
|
||||
}
|
||||
else if (command.startsWith("Chat"))
|
||||
{
|
||||
int val = 0;
|
||||
try
|
||||
{
|
||||
val = Integer.parseInt(command.substring(5));
|
||||
}
|
||||
catch (IndexOutOfBoundsException ioobe)
|
||||
{
|
||||
}
|
||||
catch (NumberFormatException nfe)
|
||||
{
|
||||
}
|
||||
showChatWindow(player, val);
|
||||
}
|
||||
else if (command.startsWith("open_gate"))
|
||||
{
|
||||
L2ItemInstance hallsKey = player.getInventory().getItemByItemId(HALLS_KEY);
|
||||
if (hallsKey == null)
|
||||
{
|
||||
showHtmlFile(player, "Gatekeeper-no.htm");
|
||||
}
|
||||
else if (FourSepulchersManager.getInstance().isAttackTime())
|
||||
{
|
||||
switch (getId())
|
||||
{
|
||||
case 31929:
|
||||
case 31934:
|
||||
case 31939:
|
||||
case 31944:
|
||||
FourSepulchersManager.getInstance().spawnShadow(getId());
|
||||
default:
|
||||
{
|
||||
openNextDoor(getId());
|
||||
if (player.getParty() != null)
|
||||
{
|
||||
for (L2PcInstance mem : player.getParty().getMembers())
|
||||
{
|
||||
if ((mem != null) && (mem.getInventory().getItemByItemId(HALLS_KEY) != null))
|
||||
{
|
||||
mem.destroyItemByItemId("Quest", HALLS_KEY, mem.getInventory().getItemByItemId(HALLS_KEY).getCount(), mem, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.destroyItemByItemId("Quest", HALLS_KEY, hallsKey.getCount(), player, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onBypassFeedback(player, command);
|
||||
}
|
||||
}
|
||||
|
||||
public void openNextDoor(int npcId)
|
||||
{
|
||||
int doorId = FourSepulchersManager.getInstance().getHallGateKeepers().get(npcId);
|
||||
DoorTable _doorTable = DoorTable.getInstance();
|
||||
_doorTable.getDoor(doorId).openMe();
|
||||
|
||||
if (_closeTask != null)
|
||||
{
|
||||
_closeTask.cancel(true);
|
||||
}
|
||||
_closeTask = ThreadPoolManager.getInstance().scheduleEffect(new CloseNextDoor(doorId), 10000);
|
||||
if (_spawnNextMysteriousBoxTask != null)
|
||||
{
|
||||
_spawnNextMysteriousBoxTask.cancel(true);
|
||||
}
|
||||
_spawnNextMysteriousBoxTask = ThreadPoolManager.getInstance().scheduleEffect(new SpawnNextMysteriousBox(npcId), 0);
|
||||
}
|
||||
|
||||
private static class CloseNextDoor implements Runnable
|
||||
{
|
||||
final DoorTable _DoorTable = DoorTable.getInstance();
|
||||
|
||||
private final int _DoorId;
|
||||
|
||||
public CloseNextDoor(int doorId)
|
||||
{
|
||||
_DoorId = doorId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
_DoorTable.getDoor(_DoorId).closeMe();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.warning(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class SpawnNextMysteriousBox implements Runnable
|
||||
{
|
||||
private final int _NpcId;
|
||||
|
||||
public SpawnNextMysteriousBox(int npcId)
|
||||
{
|
||||
_NpcId = npcId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
FourSepulchersManager.getInstance().spawnMysteriousBox(_NpcId);
|
||||
}
|
||||
}
|
||||
|
||||
private static class SpawnMonster implements Runnable
|
||||
{
|
||||
private final int _NpcId;
|
||||
|
||||
public SpawnMonster(int npcId)
|
||||
{
|
||||
_NpcId = npcId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
FourSepulchersManager.getInstance().spawnMonster(_NpcId);
|
||||
}
|
||||
}
|
||||
|
||||
public void sayInShout(NpcStringId msg)
|
||||
{
|
||||
if (msg == null)
|
||||
{
|
||||
return;// wrong usage
|
||||
}
|
||||
|
||||
final CreatureSay creatureSay = new CreatureSay(0, Say2.NPC_SHOUT, getName(), msg);
|
||||
for (L2PcInstance player : L2World.getInstance().getPlayers())
|
||||
{
|
||||
if (Util.checkIfInRange(15000, player, this, true))
|
||||
{
|
||||
player.sendPacket(creatureSay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void showHtmlFile(L2PcInstance player, String file)
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "data/html/SepulcherNpc/" + file);
|
||||
html.replace("%npcname%", getName());
|
||||
player.sendPacket(html);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,570 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.datatables.CharSummonTable;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.datatables.SummonEffectsTable;
|
||||
import com.l2jserver.gameserver.datatables.SummonEffectsTable.SummonEffect;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jserver.gameserver.model.skills.AbnormalType;
|
||||
import com.l2jserver.gameserver.model.skills.BuffInfo;
|
||||
import com.l2jserver.gameserver.model.skills.EffectScope;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SetSummonRemainTime;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class L2ServitorInstance extends L2Summon implements Runnable
|
||||
{
|
||||
protected static final Logger log = Logger.getLogger(L2ServitorInstance.class.getName());
|
||||
|
||||
private static final String ADD_SKILL_SAVE = "INSERT INTO character_summon_skills_save (ownerId,ownerClassIndex,summonSkillId,skill_id,skill_level,remaining_time,buff_index) VALUES (?,?,?,?,?,?,?)";
|
||||
private static final String RESTORE_SKILL_SAVE = "SELECT skill_id,skill_level,remaining_time,buff_index FROM character_summon_skills_save WHERE ownerId=? AND ownerClassIndex=? AND summonSkillId=? ORDER BY buff_index ASC";
|
||||
private static final String DELETE_SKILL_SAVE = "DELETE FROM character_summon_skills_save WHERE ownerId=? AND ownerClassIndex=? AND summonSkillId=?";
|
||||
|
||||
private float _expMultiplier = 0;
|
||||
private ItemHolder _itemConsume;
|
||||
private int _lifeTime;
|
||||
private int _lifeTimeRemaining;
|
||||
private int _consumeItemInterval;
|
||||
private int _consumeItemIntervalRemaining;
|
||||
protected Future<?> _summonLifeTask;
|
||||
|
||||
private int _referenceSkill;
|
||||
|
||||
public L2ServitorInstance(int objectId, L2NpcTemplate template, L2PcInstance owner)
|
||||
{
|
||||
super(objectId, template, owner);
|
||||
setInstanceType(InstanceType.L2ServitorInstance);
|
||||
setShowSummonAnimation(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
super.onSpawn();
|
||||
if (_summonLifeTask == null)
|
||||
{
|
||||
_summonLifeTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(this, 0, 5000);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getLevel()
|
||||
{
|
||||
return (getTemplate() != null ? getTemplate().getLevel() : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSummonType()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ************************************/
|
||||
|
||||
public void setExpMultiplier(float expMultiplier)
|
||||
{
|
||||
_expMultiplier = expMultiplier;
|
||||
}
|
||||
|
||||
public float getExpMultiplier()
|
||||
{
|
||||
return _expMultiplier;
|
||||
}
|
||||
|
||||
// ************************************/
|
||||
|
||||
public void setItemConsume(ItemHolder item)
|
||||
{
|
||||
_itemConsume = item;
|
||||
}
|
||||
|
||||
public ItemHolder getItemConsume()
|
||||
{
|
||||
return _itemConsume;
|
||||
}
|
||||
|
||||
// ************************************/
|
||||
|
||||
public void setItemConsumeInterval(int interval)
|
||||
{
|
||||
_consumeItemInterval = interval;
|
||||
_consumeItemIntervalRemaining = interval;
|
||||
}
|
||||
|
||||
public int getItemConsumeInterval()
|
||||
{
|
||||
return _consumeItemInterval;
|
||||
}
|
||||
|
||||
// ************************************/
|
||||
|
||||
public void setLifeTime(int lifeTime)
|
||||
{
|
||||
_lifeTime = lifeTime;
|
||||
_lifeTimeRemaining = lifeTime;
|
||||
}
|
||||
|
||||
public int getLifeTime()
|
||||
{
|
||||
return _lifeTime;
|
||||
}
|
||||
|
||||
// ************************************/
|
||||
|
||||
public void setLifeTimeRemaining(int time)
|
||||
{
|
||||
_lifeTimeRemaining = time;
|
||||
}
|
||||
|
||||
public int getLifeTimeRemaining()
|
||||
{
|
||||
return _lifeTimeRemaining;
|
||||
}
|
||||
|
||||
// ************************************/
|
||||
|
||||
public void setReferenceSkill(int skillId)
|
||||
{
|
||||
_referenceSkill = skillId;
|
||||
}
|
||||
|
||||
public int getReferenceSkill()
|
||||
{
|
||||
return _referenceSkill;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_summonLifeTask != null)
|
||||
{
|
||||
_summonLifeTask.cancel(false);
|
||||
}
|
||||
|
||||
CharSummonTable.getInstance().removeServitor(getOwner());
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Servitors' skills automatically change their level based on the servitor's level.<br>
|
||||
* Until level 70, the servitor gets 1 lv of skill per 10 levels.<br>
|
||||
* After that, it is 1 skill level per 5 servitor levels.<br>
|
||||
* If the resulting skill level doesn't exist use the max that does exist!
|
||||
*/
|
||||
@Override
|
||||
public void doCast(Skill skill)
|
||||
{
|
||||
final int petLevel = getLevel();
|
||||
int skillLevel = petLevel / 10;
|
||||
if (petLevel >= 70)
|
||||
{
|
||||
skillLevel += (petLevel - 65) / 10;
|
||||
}
|
||||
|
||||
// Adjust the level for servitors less than level 1.
|
||||
if (skillLevel < 1)
|
||||
{
|
||||
skillLevel = 1;
|
||||
}
|
||||
|
||||
final Skill skillToCast = SkillData.getInstance().getSkill(skill.getId(), skillLevel);
|
||||
|
||||
if (skillToCast != null)
|
||||
{
|
||||
super.doCast(skillToCast);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.doCast(skill);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRestoreSummon(boolean val)
|
||||
{
|
||||
_restoreSummon = val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void stopSkillEffects(boolean removed, int skillId)
|
||||
{
|
||||
super.stopSkillEffects(removed, skillId);
|
||||
final Map<Integer, List<SummonEffect>> servitorEffects = SummonEffectsTable.getInstance().getServitorEffects(getOwner());
|
||||
if (servitorEffects != null)
|
||||
{
|
||||
final List<SummonEffect> effects = servitorEffects.get(getReferenceSkill());
|
||||
if ((effects != null) && !effects.isEmpty())
|
||||
{
|
||||
for (SummonEffect effect : effects)
|
||||
{
|
||||
final Skill skill = effect.getSkill();
|
||||
if ((skill != null) && (skill.getId() == skillId))
|
||||
{
|
||||
effects.remove(effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeMe()
|
||||
{
|
||||
if ((_referenceSkill == 0) || isDead())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.RESTORE_SERVITOR_ON_RECONNECT)
|
||||
{
|
||||
CharSummonTable.getInstance().saveSummon(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeEffect(boolean storeEffects)
|
||||
{
|
||||
if (!Config.SUMMON_STORE_SKILL_COOLTIME)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ((getOwner() == null) || getOwner().isInOlympiadMode())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear list for overwrite
|
||||
if (SummonEffectsTable.getInstance().getServitorEffectsOwner().containsKey(getOwner().getObjectId()) && SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).containsKey(getOwner().getClassIndex()) && SummonEffectsTable.getInstance().getServitorEffects(getOwner()).containsKey(getReferenceSkill()))
|
||||
{
|
||||
SummonEffectsTable.getInstance().getServitorEffects(getOwner()).get(getReferenceSkill()).clear();
|
||||
}
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(DELETE_SKILL_SAVE))
|
||||
{
|
||||
// Delete all current stored effects for summon to avoid dupe
|
||||
statement.setInt(1, getOwner().getObjectId());
|
||||
statement.setInt(2, getOwner().getClassIndex());
|
||||
statement.setInt(3, getReferenceSkill());
|
||||
statement.execute();
|
||||
|
||||
int buff_index = 0;
|
||||
|
||||
final List<Integer> storedSkills = new FastList<>();
|
||||
|
||||
// Store all effect data along with calculated remaining
|
||||
if (storeEffects)
|
||||
{
|
||||
try (PreparedStatement ps2 = con.prepareStatement(ADD_SKILL_SAVE))
|
||||
{
|
||||
for (BuffInfo info : getEffectList().getEffects())
|
||||
{
|
||||
if (info == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final Skill skill = info.getSkill();
|
||||
// Do not save heals.
|
||||
if (skill.getAbnormalType() == AbnormalType.LIFE_FORCE_OTHERS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skill.isToggle())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Dances and songs are not kept in retail.
|
||||
if (skill.isDance() && !Config.ALT_STORE_DANCES)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (storedSkills.contains(skill.getReuseHashCode()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
storedSkills.add(skill.getReuseHashCode());
|
||||
|
||||
ps2.setInt(1, getOwner().getObjectId());
|
||||
ps2.setInt(2, getOwner().getClassIndex());
|
||||
ps2.setInt(3, getReferenceSkill());
|
||||
ps2.setInt(4, skill.getId());
|
||||
ps2.setInt(5, skill.getLevel());
|
||||
ps2.setInt(6, info.getTime());
|
||||
ps2.setInt(7, ++buff_index);
|
||||
ps2.execute();
|
||||
|
||||
// XXX: Rework me!
|
||||
if (!SummonEffectsTable.getInstance().getServitorEffectsOwner().containsKey(getOwner().getObjectId()))
|
||||
{
|
||||
SummonEffectsTable.getInstance().getServitorEffectsOwner().put(getOwner().getObjectId(), new HashMap<Integer, Map<Integer, List<SummonEffect>>>());
|
||||
}
|
||||
if (!SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).containsKey(getOwner().getClassIndex()))
|
||||
{
|
||||
SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).put(getOwner().getClassIndex(), new HashMap<Integer, List<SummonEffect>>());
|
||||
}
|
||||
if (!SummonEffectsTable.getInstance().getServitorEffects(getOwner()).containsKey(getReferenceSkill()))
|
||||
{
|
||||
SummonEffectsTable.getInstance().getServitorEffects(getOwner()).put(getReferenceSkill(), new FastList<SummonEffect>());
|
||||
}
|
||||
|
||||
SummonEffectsTable.getInstance().getServitorEffects(getOwner()).get(getReferenceSkill()).add(SummonEffectsTable.getInstance().new SummonEffect(skill, info.getTime()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Could not store summon effect data: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreEffects()
|
||||
{
|
||||
if (getOwner().isInOlympiadMode())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection())
|
||||
{
|
||||
if (!SummonEffectsTable.getInstance().getServitorEffectsOwner().containsKey(getOwner().getObjectId()) || !SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).containsKey(getOwner().getClassIndex()) || !SummonEffectsTable.getInstance().getServitorEffects(getOwner()).containsKey(getReferenceSkill()))
|
||||
{
|
||||
try (PreparedStatement statement = con.prepareStatement(RESTORE_SKILL_SAVE))
|
||||
{
|
||||
statement.setInt(1, getOwner().getObjectId());
|
||||
statement.setInt(2, getOwner().getClassIndex());
|
||||
statement.setInt(3, getReferenceSkill());
|
||||
try (ResultSet rset = statement.executeQuery())
|
||||
{
|
||||
while (rset.next())
|
||||
{
|
||||
int effectCurTime = rset.getInt("remaining_time");
|
||||
|
||||
final Skill skill = SkillData.getInstance().getSkill(rset.getInt("skill_id"), rset.getInt("skill_level"));
|
||||
if (skill == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// XXX: Rework me!
|
||||
if (skill.hasEffects(EffectScope.GENERAL))
|
||||
{
|
||||
if (!SummonEffectsTable.getInstance().getServitorEffectsOwner().containsKey(getOwner().getObjectId()))
|
||||
{
|
||||
SummonEffectsTable.getInstance().getServitorEffectsOwner().put(getOwner().getObjectId(), new HashMap<Integer, Map<Integer, List<SummonEffect>>>());
|
||||
}
|
||||
if (!SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).containsKey(getOwner().getClassIndex()))
|
||||
{
|
||||
SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).put(getOwner().getClassIndex(), new HashMap<Integer, List<SummonEffect>>());
|
||||
}
|
||||
if (!SummonEffectsTable.getInstance().getServitorEffects(getOwner()).containsKey(getReferenceSkill()))
|
||||
{
|
||||
SummonEffectsTable.getInstance().getServitorEffects(getOwner()).put(getReferenceSkill(), new FastList<SummonEffect>());
|
||||
}
|
||||
|
||||
SummonEffectsTable.getInstance().getServitorEffects(getOwner()).get(getReferenceSkill()).add(SummonEffectsTable.getInstance().new SummonEffect(skill, effectCurTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try (PreparedStatement statement = con.prepareStatement(DELETE_SKILL_SAVE))
|
||||
{
|
||||
statement.setInt(1, getOwner().getObjectId());
|
||||
statement.setInt(2, getOwner().getClassIndex());
|
||||
statement.setInt(3, getReferenceSkill());
|
||||
statement.executeUpdate();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Could not restore " + this + " active effect data: " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!SummonEffectsTable.getInstance().getServitorEffectsOwner().containsKey(getOwner().getObjectId()) || !SummonEffectsTable.getInstance().getServitorEffectsOwner().get(getOwner().getObjectId()).containsKey(getOwner().getClassIndex()) || !SummonEffectsTable.getInstance().getServitorEffects(getOwner()).containsKey(getReferenceSkill()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (SummonEffect se : SummonEffectsTable.getInstance().getServitorEffects(getOwner()).get(getReferenceSkill()))
|
||||
{
|
||||
if (se != null)
|
||||
{
|
||||
se.getSkill().applyEffects(this, this, false, se.getEffectCurTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unSummon(L2PcInstance owner)
|
||||
{
|
||||
if (_summonLifeTask != null)
|
||||
{
|
||||
_summonLifeTask.cancel(false);
|
||||
}
|
||||
|
||||
super.unSummon(owner);
|
||||
|
||||
if (!_restoreSummon)
|
||||
{
|
||||
CharSummonTable.getInstance().removeServitor(owner);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean destroyItem(String process, int objectId, long count, L2Object reference, boolean sendMessage)
|
||||
{
|
||||
return getOwner().destroyItem(process, objectId, count, reference, sendMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean destroyItemByItemId(String process, int itemId, long count, L2Object reference, boolean sendMessage)
|
||||
{
|
||||
return getOwner().destroyItemByItemId(process, itemId, count, reference, sendMessage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getAttackElement()
|
||||
{
|
||||
if (getOwner() != null)
|
||||
{
|
||||
return getOwner().getAttackElement();
|
||||
}
|
||||
return super.getAttackElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAttackElementValue(byte attackAttribute)
|
||||
{
|
||||
if (getOwner() != null)
|
||||
{
|
||||
return (getOwner().getAttackElementValue(attackAttribute));
|
||||
}
|
||||
return super.getAttackElementValue(attackAttribute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDefenseElementValue(byte defenseAttribute)
|
||||
{
|
||||
if (getOwner() != null)
|
||||
{
|
||||
return (getOwner().getDefenseElementValue(defenseAttribute));
|
||||
}
|
||||
return super.getDefenseElementValue(defenseAttribute);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isServitor()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
int usedtime = 5000;
|
||||
_lifeTimeRemaining -= usedtime;
|
||||
|
||||
if (isDead() || !isVisible())
|
||||
{
|
||||
if (_summonLifeTask != null)
|
||||
{
|
||||
_summonLifeTask.cancel(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// check if the summon's lifetime has ran out
|
||||
if (_lifeTimeRemaining < 0)
|
||||
{
|
||||
sendPacket(SystemMessageId.YOUR_SERVITOR_PASSED_AWAY);
|
||||
unSummon(getOwner());
|
||||
return;
|
||||
}
|
||||
|
||||
if (_consumeItemInterval > 0)
|
||||
{
|
||||
_consumeItemIntervalRemaining -= usedtime;
|
||||
|
||||
// check if it is time to consume another item
|
||||
if ((_consumeItemIntervalRemaining <= 0) && (getItemConsume().getCount() > 0) && (getItemConsume().getId() > 0) && !isDead())
|
||||
{
|
||||
if (destroyItemByItemId("Consume", getItemConsume().getId(), getItemConsume().getCount(), this, false))
|
||||
{
|
||||
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.A_SUMMONED_MONSTER_USES_S1);
|
||||
msg.addItemName(getItemConsume().getId());
|
||||
sendPacket(msg);
|
||||
|
||||
// Reset
|
||||
_consumeItemIntervalRemaining = _consumeItemInterval;
|
||||
}
|
||||
else
|
||||
{
|
||||
sendPacket(SystemMessageId.SINCE_YOU_DO_NOT_HAVE_ENOUGH_ITEMS_TO_MAINTAIN_THE_SERVITOR_S_STAY_THE_SERVITOR_HAS_DISAPPEARED);
|
||||
unSummon(getOwner());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendPacket(new SetSummonRemainTime(getLifeTime(), _lifeTimeRemaining));
|
||||
updateEffectIcons();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jserver.gameserver.ai.L2ShuttleAI;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Vehicle;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jserver.gameserver.model.shuttle.L2ShuttleData;
|
||||
import com.l2jserver.gameserver.model.shuttle.L2ShuttleStop;
|
||||
import com.l2jserver.gameserver.network.serverpackets.shuttle.ExShuttleGetOff;
|
||||
import com.l2jserver.gameserver.network.serverpackets.shuttle.ExShuttleGetOn;
|
||||
import com.l2jserver.gameserver.network.serverpackets.shuttle.ExShuttleInfo;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class L2ShuttleInstance extends L2Vehicle
|
||||
{
|
||||
private L2ShuttleData _shuttleData;
|
||||
|
||||
public L2ShuttleInstance(int objectId, L2CharTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2ShuttleInstance);
|
||||
setAI(new L2ShuttleAI(new AIAccessor()));
|
||||
}
|
||||
|
||||
public List<L2ShuttleStop> getStops()
|
||||
{
|
||||
return _shuttleData.getStops();
|
||||
}
|
||||
|
||||
public void closeDoor(int id)
|
||||
{
|
||||
for (L2ShuttleStop stop : getStops())
|
||||
{
|
||||
if (stop.getId() == id)
|
||||
{
|
||||
stop.closeDoor();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void openDoor(int id)
|
||||
{
|
||||
for (L2ShuttleStop stop : getStops())
|
||||
{
|
||||
if (stop.getId() == id)
|
||||
{
|
||||
stop.openDoor();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId()
|
||||
{
|
||||
return _shuttleData.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addPassenger(L2PcInstance player)
|
||||
{
|
||||
if (!super.addPassenger(player))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
player.setVehicle(this);
|
||||
player.setInVehiclePosition(new Location(0, 0, 0));
|
||||
player.broadcastPacket(new ExShuttleGetOn(player, this));
|
||||
player.getKnownList().removeAllKnownObjects();
|
||||
player.setXYZ(getX(), getY(), getZ());
|
||||
player.revalidateZone(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void removePassenger(L2PcInstance player, int x, int y, int z)
|
||||
{
|
||||
oustPlayer(player);
|
||||
if (player.isOnline())
|
||||
{
|
||||
player.broadcastPacket(new ExShuttleGetOff(player, this, x, y, z));
|
||||
player.getKnownList().removeAllKnownObjects();
|
||||
player.setXYZ(x, y, z);
|
||||
player.revalidateZone(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setXYZInvisible(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void oustPlayers()
|
||||
{
|
||||
L2PcInstance player;
|
||||
|
||||
// Use iterator because oustPlayer will try to remove player from _passengers
|
||||
final Iterator<L2PcInstance> iter = _passengers.iterator();
|
||||
while (iter.hasNext())
|
||||
{
|
||||
player = iter.next();
|
||||
iter.remove();
|
||||
if (player != null)
|
||||
{
|
||||
oustPlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendInfo(L2PcInstance activeChar)
|
||||
{
|
||||
activeChar.sendPacket(new ExShuttleInfo(this));
|
||||
}
|
||||
|
||||
public void broadcastShuttleInfo()
|
||||
{
|
||||
broadcastPacket(new ExShuttleInfo(this));
|
||||
}
|
||||
|
||||
public void setData(L2ShuttleData data)
|
||||
{
|
||||
_shuttleData = data;
|
||||
}
|
||||
|
||||
public L2ShuttleData getShuttleData()
|
||||
{
|
||||
return _shuttleData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.CHSiegeManager;
|
||||
import com.l2jserver.gameserver.instancemanager.FortSiegeManager;
|
||||
import com.l2jserver.gameserver.instancemanager.SiegeManager;
|
||||
import com.l2jserver.gameserver.model.L2Clan;
|
||||
import com.l2jserver.gameserver.model.L2SiegeClan;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.status.SiegeFlagStatus;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.entity.Siegable;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
public class L2SiegeFlagInstance extends L2Npc
|
||||
{
|
||||
private final L2Clan _clan;
|
||||
private Siegable _siege;
|
||||
private final boolean _isAdvanced;
|
||||
private boolean _canTalk;
|
||||
|
||||
public L2SiegeFlagInstance(L2PcInstance player, int objectId, L2NpcTemplate template, boolean advanced, boolean outPost)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2SiegeFlagInstance);
|
||||
|
||||
_clan = player.getClan();
|
||||
_canTalk = true;
|
||||
_siege = SiegeManager.getInstance().getSiege(player.getX(), player.getY(), player.getZ());
|
||||
if (_siege == null)
|
||||
{
|
||||
_siege = FortSiegeManager.getInstance().getSiege(player.getX(), player.getY(), player.getZ());
|
||||
}
|
||||
if (_siege == null)
|
||||
{
|
||||
_siege = CHSiegeManager.getInstance().getSiege(player);
|
||||
}
|
||||
if ((_clan == null) || (_siege == null))
|
||||
{
|
||||
throw new NullPointerException(getClass().getSimpleName() + ": Initialization failed.");
|
||||
}
|
||||
|
||||
L2SiegeClan sc = _siege.getAttackerClan(_clan);
|
||||
if (sc == null)
|
||||
{
|
||||
throw new NullPointerException(getClass().getSimpleName() + ": Cannot find siege clan.");
|
||||
}
|
||||
|
||||
sc.addFlag(this);
|
||||
_isAdvanced = advanced;
|
||||
getStatus();
|
||||
setIsInvul(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeAttacked()
|
||||
{
|
||||
return !isInvul();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
return !isInvul();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ((_siege != null) && (_clan != null))
|
||||
{
|
||||
L2SiegeClan sc = _siege.getAttackerClan(_clan);
|
||||
if (sc != null)
|
||||
{
|
||||
sc.removeFlag(this);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onForcedAttack(L2PcInstance player)
|
||||
{
|
||||
onAction(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAction(L2PcInstance player, boolean interact)
|
||||
{
|
||||
if ((player == null) || !canTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the L2PcInstance already target the L2NpcInstance
|
||||
if (this != player.getTarget())
|
||||
{
|
||||
// Set the target of the L2PcInstance player
|
||||
player.setTarget(this);
|
||||
}
|
||||
else if (interact)
|
||||
{
|
||||
if (isAutoAttackable(player) && (Math.abs(player.getZ() - getZ()) < 100))
|
||||
{
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAdvancedHeadquarter()
|
||||
{
|
||||
return _isAdvanced;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SiegeFlagStatus getStatus()
|
||||
{
|
||||
return (SiegeFlagStatus) super.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initCharStatus()
|
||||
{
|
||||
setStatus(new SiegeFlagStatus(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reduceCurrentHp(double damage, L2Character attacker, Skill skill)
|
||||
{
|
||||
super.reduceCurrentHp(damage, attacker, skill);
|
||||
if (canTalk())
|
||||
{
|
||||
if (((getCastle() != null) && getCastle().getSiege().isInProgress()) || ((getFort() != null) && getFort().getSiege().isInProgress()) || ((getConquerableHall() != null) && getConquerableHall().isInSiege()))
|
||||
{
|
||||
if (_clan != null)
|
||||
{
|
||||
// send warning to owners of headquarters that theirs base is under attack
|
||||
_clan.broadcastToOnlineMembers(SystemMessage.getSystemMessage(SystemMessageId.YOUR_BASE_IS_BEING_ATTACKED));
|
||||
setCanTalk(false);
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new ScheduleTalkTask(), 20000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ScheduleTalkTask implements Runnable
|
||||
{
|
||||
|
||||
public ScheduleTalkTask()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
setCanTalk(true);
|
||||
}
|
||||
}
|
||||
|
||||
void setCanTalk(boolean val)
|
||||
{
|
||||
_canTalk = val;
|
||||
}
|
||||
|
||||
private boolean canTalk()
|
||||
{
|
||||
return _canTalk;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.ai.L2CharacterAI;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.knownlist.StaticObjectKnownList;
|
||||
import com.l2jserver.gameserver.model.actor.stat.StaticObjStat;
|
||||
import com.l2jserver.gameserver.model.actor.status.StaticObjStatus;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jserver.gameserver.model.items.L2Weapon;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ShowTownMap;
|
||||
import com.l2jserver.gameserver.network.serverpackets.StaticObject;
|
||||
|
||||
/**
|
||||
* Static Object instance.
|
||||
* @author godson
|
||||
*/
|
||||
public final class L2StaticObjectInstance extends L2Character
|
||||
{
|
||||
/** The interaction distance of the L2StaticObjectInstance */
|
||||
public static final int INTERACTION_DISTANCE = 150;
|
||||
|
||||
private final int _staticObjectId;
|
||||
private int _meshIndex = 0; // 0 - static objects, alternate static objects
|
||||
private int _type = -1; // 0 - map signs, 1 - throne , 2 - arena signs
|
||||
private ShowTownMap _map;
|
||||
|
||||
/** This class may be created only by L2Character and only for AI */
|
||||
public class AIAccessor extends L2Character.AIAccessor
|
||||
{
|
||||
@Override
|
||||
public L2StaticObjectInstance getActor()
|
||||
{
|
||||
return L2StaticObjectInstance.this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveTo(int x, int y, int z, int offset)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveTo(int x, int y, int z)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopMove(Location loc)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAttack(L2Character target)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCast(Skill skill)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected L2CharacterAI initAI()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the static object ID.
|
||||
* @return the static object ID
|
||||
*/
|
||||
@Override
|
||||
public int getId()
|
||||
{
|
||||
return _staticObjectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param objectId
|
||||
* @param template
|
||||
* @param staticId
|
||||
*/
|
||||
public L2StaticObjectInstance(int objectId, L2CharTemplate template, int staticId)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2StaticObjectInstance);
|
||||
_staticObjectId = staticId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final StaticObjectKnownList getKnownList()
|
||||
{
|
||||
return (StaticObjectKnownList) super.getKnownList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initKnownList()
|
||||
{
|
||||
setKnownList(new StaticObjectKnownList(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final StaticObjStat getStat()
|
||||
{
|
||||
return (StaticObjStat) super.getStat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initCharStat()
|
||||
{
|
||||
setStat(new StaticObjStat(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final StaticObjStatus getStatus()
|
||||
{
|
||||
return (StaticObjStatus) super.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initCharStatus()
|
||||
{
|
||||
setStatus(new StaticObjStatus(this));
|
||||
}
|
||||
|
||||
public int getType()
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
public void setType(int type)
|
||||
{
|
||||
_type = type;
|
||||
}
|
||||
|
||||
public void setMap(String texture, int x, int y)
|
||||
{
|
||||
_map = new ShowTownMap("town_map." + texture, x, y);
|
||||
}
|
||||
|
||||
public ShowTownMap getMap()
|
||||
{
|
||||
return _map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getLevel()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2ItemInstance getActiveWeaponInstance()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Weapon getActiveWeaponItem()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2ItemInstance getSecondaryWeaponInstance()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Weapon getSecondaryWeaponItem()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the meshIndex of the object.<br>
|
||||
* <B><U> Values </U> :</B>
|
||||
* <ul>
|
||||
* <li>default textures : 0</li>
|
||||
* <li>alternate textures : 1</li>
|
||||
* </ul>
|
||||
* @param meshIndex
|
||||
*/
|
||||
public void setMeshIndex(int meshIndex)
|
||||
{
|
||||
_meshIndex = meshIndex;
|
||||
this.broadcastPacket(new StaticObject(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* <B><U> Values </U> :</B>
|
||||
* <ul>
|
||||
* <li>default textures : 0</li>
|
||||
* <li>alternate textures : 1</li>
|
||||
* </ul>
|
||||
* @return the meshIndex of the object
|
||||
*/
|
||||
public int getMeshIndex()
|
||||
{
|
||||
return _meshIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAbnormalEffect()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendInfo(L2PcInstance activeChar)
|
||||
{
|
||||
activeChar.sendPacket(new StaticObject(this));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,590 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import static com.l2jserver.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jserver.gameserver.network.serverpackets.StopMove;
|
||||
import com.l2jserver.util.Rnd;
|
||||
|
||||
// While a tamed beast behaves a lot like a pet (ingame) and does have
|
||||
// an owner, in all other aspects, it acts like a mob.
|
||||
// In addition, it can be fed in order to increase its duration.
|
||||
// This class handles the running tasks, AI, and feed of the mob.
|
||||
// The (mostly optional) AI on feeding the spawn is handled by the datapack ai script
|
||||
public final class L2TamedBeastInstance extends L2FeedableBeastInstance
|
||||
{
|
||||
private int _foodSkillId;
|
||||
private static final int MAX_DISTANCE_FROM_HOME = 30000;
|
||||
private static final int MAX_DISTANCE_FROM_OWNER = 2000;
|
||||
private static final int MAX_DURATION = 1200000; // 20 minutes
|
||||
private static final int DURATION_CHECK_INTERVAL = 60000; // 1 minute
|
||||
private static final int DURATION_INCREASE_INTERVAL = 20000; // 20 secs (gained upon feeding)
|
||||
private static final int BUFF_INTERVAL = 5000; // 5 seconds
|
||||
private int _remainingTime = MAX_DURATION;
|
||||
private int _homeX, _homeY, _homeZ;
|
||||
protected L2PcInstance _owner;
|
||||
private Future<?> _buffTask = null;
|
||||
private Future<?> _durationCheckTask = null;
|
||||
protected boolean _isFreyaBeast;
|
||||
private List<Skill> _beastSkills = null;
|
||||
|
||||
public L2TamedBeastInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2TamedBeastInstance);
|
||||
setHome(this);
|
||||
}
|
||||
|
||||
public L2TamedBeastInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, int foodSkillId, int x, int y, int z)
|
||||
{
|
||||
super(objectId, template);
|
||||
_isFreyaBeast = false;
|
||||
setInstanceType(InstanceType.L2TamedBeastInstance);
|
||||
setCurrentHp(getMaxHp());
|
||||
setCurrentMp(getMaxMp());
|
||||
setOwner(owner);
|
||||
setFoodType(foodSkillId);
|
||||
setHome(x, y, z);
|
||||
this.spawnMe(x, y, z);
|
||||
}
|
||||
|
||||
public L2TamedBeastInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, int food, int x, int y, int z, boolean isFreyaBeast)
|
||||
{
|
||||
super(objectId, template);
|
||||
_isFreyaBeast = isFreyaBeast;
|
||||
setInstanceType(InstanceType.L2TamedBeastInstance);
|
||||
setCurrentHp(getMaxHp());
|
||||
setCurrentMp(getMaxMp());
|
||||
setFoodType(food);
|
||||
setHome(x, y, z);
|
||||
spawnMe(x, y, z);
|
||||
setOwner(owner);
|
||||
if (isFreyaBeast)
|
||||
{
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _owner);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void onReceiveFood()
|
||||
{
|
||||
// Eating food extends the duration by 20secs, to a max of 20minutes
|
||||
_remainingTime = _remainingTime + DURATION_INCREASE_INTERVAL;
|
||||
if (_remainingTime > MAX_DURATION)
|
||||
{
|
||||
_remainingTime = MAX_DURATION;
|
||||
}
|
||||
}
|
||||
|
||||
public Location getHome()
|
||||
{
|
||||
return new Location(_homeX, _homeY, _homeZ);
|
||||
}
|
||||
|
||||
public void setHome(int x, int y, int z)
|
||||
{
|
||||
_homeX = x;
|
||||
_homeY = y;
|
||||
_homeZ = z;
|
||||
}
|
||||
|
||||
public void setHome(L2Character c)
|
||||
{
|
||||
setHome(c.getX(), c.getY(), c.getZ());
|
||||
}
|
||||
|
||||
public int getRemainingTime()
|
||||
{
|
||||
return _remainingTime;
|
||||
}
|
||||
|
||||
public void setRemainingTime(int duration)
|
||||
{
|
||||
_remainingTime = duration;
|
||||
}
|
||||
|
||||
public int getFoodType()
|
||||
{
|
||||
return _foodSkillId;
|
||||
}
|
||||
|
||||
public void setFoodType(int foodItemId)
|
||||
{
|
||||
if (foodItemId > 0)
|
||||
{
|
||||
_foodSkillId = foodItemId;
|
||||
|
||||
// start the duration checks
|
||||
// start the buff tasks
|
||||
if (_durationCheckTask != null)
|
||||
{
|
||||
_durationCheckTask.cancel(true);
|
||||
}
|
||||
_durationCheckTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new CheckDuration(this), DURATION_CHECK_INTERVAL, DURATION_CHECK_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
getAI().stopFollow();
|
||||
if (_buffTask != null)
|
||||
{
|
||||
_buffTask.cancel(true);
|
||||
}
|
||||
if (_durationCheckTask != null)
|
||||
{
|
||||
_durationCheckTask.cancel(true);
|
||||
}
|
||||
|
||||
// clean up variables
|
||||
if ((_owner != null) && (_owner.getTrainedBeasts() != null))
|
||||
{
|
||||
_owner.getTrainedBeasts().remove(this);
|
||||
}
|
||||
_buffTask = null;
|
||||
_durationCheckTask = null;
|
||||
_owner = null;
|
||||
_foodSkillId = 0;
|
||||
_remainingTime = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
return !_isFreyaBeast;
|
||||
}
|
||||
|
||||
public boolean isFreyaBeast()
|
||||
{
|
||||
return _isFreyaBeast;
|
||||
}
|
||||
|
||||
public void addBeastSkill(Skill skill)
|
||||
{
|
||||
if (_beastSkills == null)
|
||||
{
|
||||
_beastSkills = new FastList<>();
|
||||
}
|
||||
_beastSkills.add(skill);
|
||||
}
|
||||
|
||||
public void castBeastSkills()
|
||||
{
|
||||
if ((_owner == null) || (_beastSkills == null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
int delay = 100;
|
||||
for (Skill skill : _beastSkills)
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new buffCast(skill), delay);
|
||||
delay += (100 + skill.getHitTime());
|
||||
}
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new buffCast(null), delay);
|
||||
}
|
||||
|
||||
private class buffCast implements Runnable
|
||||
{
|
||||
private final Skill _skill;
|
||||
|
||||
public buffCast(Skill skill)
|
||||
{
|
||||
_skill = skill;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (_skill == null)
|
||||
{
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _owner);
|
||||
}
|
||||
else
|
||||
{
|
||||
sitCastAndFollow(_skill, _owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public L2PcInstance getOwner()
|
||||
{
|
||||
return _owner;
|
||||
}
|
||||
|
||||
public void setOwner(L2PcInstance owner)
|
||||
{
|
||||
if (owner != null)
|
||||
{
|
||||
_owner = owner;
|
||||
setTitle(owner.getName());
|
||||
// broadcast the new title
|
||||
setShowSummonAnimation(true);
|
||||
broadcastPacket(new NpcInfo(this));
|
||||
|
||||
owner.addTrainedBeast(this);
|
||||
|
||||
// always and automatically follow the owner.
|
||||
getAI().startFollow(_owner, 100);
|
||||
|
||||
if (!_isFreyaBeast)
|
||||
{
|
||||
// instead of calculating this value each time, let's get this now and pass it on
|
||||
int totalBuffsAvailable = 0;
|
||||
for (Skill skill : getTemplate().getSkills().values())
|
||||
{
|
||||
// if the skill is a buff, check if the owner has it already [ owner.getEffect(L2Skill skill) ]
|
||||
if (skill.isContinuous() && !skill.isDebuff())
|
||||
{
|
||||
totalBuffsAvailable++;
|
||||
}
|
||||
}
|
||||
|
||||
// start the buff tasks
|
||||
if (_buffTask != null)
|
||||
{
|
||||
_buffTask.cancel(true);
|
||||
}
|
||||
_buffTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new CheckOwnerBuffs(this, totalBuffsAvailable), BUFF_INTERVAL, BUFF_INTERVAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
deleteMe(); // despawn if no owner
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTooFarFromHome()
|
||||
{
|
||||
return !isInsideRadius(_homeX, _homeY, _homeZ, MAX_DISTANCE_FROM_HOME, true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteMe()
|
||||
{
|
||||
if (_buffTask != null)
|
||||
{
|
||||
_buffTask.cancel(true);
|
||||
}
|
||||
_durationCheckTask.cancel(true);
|
||||
stopHpMpRegeneration();
|
||||
|
||||
// clean up variables
|
||||
if ((_owner != null) && (_owner.getTrainedBeasts() != null))
|
||||
{
|
||||
_owner.getTrainedBeasts().remove(this);
|
||||
}
|
||||
setTarget(null);
|
||||
_buffTask = null;
|
||||
_durationCheckTask = null;
|
||||
_owner = null;
|
||||
_foodSkillId = 0;
|
||||
_remainingTime = 0;
|
||||
|
||||
// remove the spawn
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
// notification triggered by the owner when the owner is attacked.
|
||||
// tamed mobs will heal/recharge or debuff the enemy according to their skills
|
||||
public void onOwnerGotAttacked(L2Character attacker)
|
||||
{
|
||||
// check if the owner is no longer around...if so, despawn
|
||||
if ((_owner == null) || !_owner.isOnline())
|
||||
{
|
||||
deleteMe();
|
||||
return;
|
||||
}
|
||||
// if the owner is too far away, stop anything else and immediately run towards the owner.
|
||||
if (!_owner.isInsideRadius(this, MAX_DISTANCE_FROM_OWNER, true, true))
|
||||
{
|
||||
getAI().startFollow(_owner);
|
||||
return;
|
||||
}
|
||||
// if the owner is dead, do nothing...
|
||||
if (_owner.isDead() || _isFreyaBeast)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if the tamed beast is currently in the middle of casting, let it complete its skill...
|
||||
if (isCastingNow())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float HPRatio = ((float) _owner.getCurrentHp()) / _owner.getMaxHp();
|
||||
|
||||
// if the owner has a lot of HP, then debuff the enemy with a random debuff among the available skills
|
||||
// use of more than one debuff at this moment is acceptable
|
||||
if (HPRatio >= 0.8)
|
||||
{
|
||||
for (Skill skill : getTemplate().getSkills().values())
|
||||
{
|
||||
// if the skill is a debuff, check if the attacker has it already [ attacker.getEffect(L2Skill skill) ]
|
||||
if (skill.isDebuff() && (Rnd.get(3) < 1) && ((attacker != null) && attacker.isAffectedBySkill(skill.getId())))
|
||||
{
|
||||
sitCastAndFollow(skill, attacker);
|
||||
}
|
||||
}
|
||||
}
|
||||
// for HP levels between 80% and 50%, do not react to attack events (so that MP can regenerate a bit)
|
||||
// for lower HP ranges, heal or recharge the owner with 1 skill use per attack.
|
||||
else if (HPRatio < 0.5)
|
||||
{
|
||||
int chance = 1;
|
||||
if (HPRatio < 0.25)
|
||||
{
|
||||
chance = 2;
|
||||
}
|
||||
|
||||
// if the owner has a lot of HP, then debuff the enemy with a random debuff among the available skills
|
||||
for (Skill skill : getTemplate().getSkills().values())
|
||||
{
|
||||
// if the skill is a buff, check if the owner has it already [ owner.getEffect(L2Skill skill) ]
|
||||
if ((Rnd.get(5) < chance) && skill.hasEffectType(L2EffectType.CPHEAL, L2EffectType.HEAL, L2EffectType.MANAHEAL_BY_LEVEL, L2EffectType.MANAHEAL_PERCENT))
|
||||
{
|
||||
sitCastAndFollow(skill, _owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare and cast a skill:<br>
|
||||
* First smoothly prepare the beast for casting, by abandoning other actions.<br>
|
||||
* Next, call super.doCast(skill) in order to actually cast the spell.<br>
|
||||
* Finally, return to auto-following the owner.
|
||||
* @param skill
|
||||
* @param target
|
||||
*/
|
||||
protected void sitCastAndFollow(Skill skill, L2Character target)
|
||||
{
|
||||
stopMove(null);
|
||||
broadcastPacket(new StopMove(this));
|
||||
getAI().setIntention(AI_INTENTION_IDLE);
|
||||
|
||||
setTarget(target);
|
||||
doCast(skill);
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _owner);
|
||||
}
|
||||
|
||||
private static class CheckDuration implements Runnable
|
||||
{
|
||||
private final L2TamedBeastInstance _tamedBeast;
|
||||
|
||||
CheckDuration(L2TamedBeastInstance tamedBeast)
|
||||
{
|
||||
_tamedBeast = tamedBeast;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
int foodTypeSkillId = _tamedBeast.getFoodType();
|
||||
L2PcInstance owner = _tamedBeast.getOwner();
|
||||
|
||||
L2ItemInstance item = null;
|
||||
if (_tamedBeast._isFreyaBeast)
|
||||
{
|
||||
item = owner.getInventory().getItemByItemId(foodTypeSkillId);
|
||||
if ((item != null) && (item.getCount() >= 1))
|
||||
{
|
||||
owner.destroyItem("BeastMob", item, 1, _tamedBeast, true);
|
||||
_tamedBeast.broadcastPacket(new SocialAction(_tamedBeast.getObjectId(), 3));
|
||||
}
|
||||
else
|
||||
{
|
||||
_tamedBeast.deleteMe();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_tamedBeast.setRemainingTime(_tamedBeast.getRemainingTime() - DURATION_CHECK_INTERVAL);
|
||||
// I tried to avoid this as much as possible...but it seems I can't avoid hardcoding
|
||||
// ids further, except by carrying an additional variable just for these two lines...
|
||||
// Find which food item needs to be consumed.
|
||||
if (foodTypeSkillId == 2188)
|
||||
{
|
||||
item = owner.getInventory().getItemByItemId(6643);
|
||||
}
|
||||
else if (foodTypeSkillId == 2189)
|
||||
{
|
||||
item = owner.getInventory().getItemByItemId(6644);
|
||||
}
|
||||
|
||||
// if the owner has enough food, call the item handler (use the food and triffer all necessary actions)
|
||||
if ((item != null) && (item.getCount() >= 1))
|
||||
{
|
||||
L2Object oldTarget = owner.getTarget();
|
||||
owner.setTarget(_tamedBeast);
|
||||
L2Object[] targets =
|
||||
{
|
||||
_tamedBeast
|
||||
};
|
||||
|
||||
// emulate a call to the owner using food, but bypass all checks for range, etc
|
||||
// this also causes a call to the AI tasks handling feeding, which may call onReceiveFood as required.
|
||||
owner.callSkill(SkillData.getInstance().getSkill(foodTypeSkillId, 1), targets);
|
||||
owner.setTarget(oldTarget);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if the owner has no food, the beast immediately despawns, except when it was only
|
||||
// newly spawned. Newly spawned beasts can last up to 5 minutes
|
||||
if (_tamedBeast.getRemainingTime() < (MAX_DURATION - 300000))
|
||||
{
|
||||
_tamedBeast.setRemainingTime(-1);
|
||||
}
|
||||
}
|
||||
// There are too many conflicting reports about whether distance from home should be taken into consideration. Disabled for now.
|
||||
// if (_tamedBeast.isTooFarFromHome())
|
||||
// _tamedBeast.setRemainingTime(-1);
|
||||
|
||||
if (_tamedBeast.getRemainingTime() <= 0)
|
||||
{
|
||||
_tamedBeast.deleteMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CheckOwnerBuffs implements Runnable
|
||||
{
|
||||
private final L2TamedBeastInstance _tamedBeast;
|
||||
private final int _numBuffs;
|
||||
|
||||
CheckOwnerBuffs(L2TamedBeastInstance tamedBeast, int numBuffs)
|
||||
{
|
||||
_tamedBeast = tamedBeast;
|
||||
_numBuffs = numBuffs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
L2PcInstance owner = _tamedBeast.getOwner();
|
||||
|
||||
// check if the owner is no longer around...if so, despawn
|
||||
if ((owner == null) || !owner.isOnline())
|
||||
{
|
||||
deleteMe();
|
||||
return;
|
||||
}
|
||||
// if the owner is too far away, stop anything else and immediately run towards the owner.
|
||||
if (!isInsideRadius(owner, MAX_DISTANCE_FROM_OWNER, true, true))
|
||||
{
|
||||
getAI().startFollow(owner);
|
||||
return;
|
||||
}
|
||||
// if the owner is dead, do nothing...
|
||||
if (owner.isDead())
|
||||
{
|
||||
return;
|
||||
}
|
||||
// if the tamed beast is currently casting a spell, do not interfere (do not attempt to cast anything new yet).
|
||||
if (isCastingNow())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int totalBuffsOnOwner = 0;
|
||||
int i = 0;
|
||||
int rand = Rnd.get(_numBuffs);
|
||||
Skill buffToGive = null;
|
||||
|
||||
// get this npc's skills: getSkills()
|
||||
for (Skill skill : _tamedBeast.getTemplate().getSkills().values())
|
||||
{
|
||||
// if the skill is a buff, check if the owner has it already [ owner.getEffect(L2Skill skill) ]
|
||||
if (skill.isContinuous() && !skill.isDebuff())
|
||||
{
|
||||
if (i++ == rand)
|
||||
{
|
||||
buffToGive = skill;
|
||||
}
|
||||
if (owner.isAffectedBySkill(skill.getId()))
|
||||
{
|
||||
totalBuffsOnOwner++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if the owner has less than 60% of this beast's available buff, cast a random buff
|
||||
if (((_numBuffs * 2) / 3) > totalBuffsOnOwner)
|
||||
{
|
||||
_tamedBeast.sitCastAndFollow(buffToGive, owner);
|
||||
}
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _tamedBeast.getOwner());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAction(L2PcInstance player, boolean interact)
|
||||
{
|
||||
if ((player == null) || !canTarget(player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the L2PcInstance already target the L2NpcInstance
|
||||
if (this != player.getTarget())
|
||||
{
|
||||
// Set the target of the L2PcInstance player
|
||||
player.setTarget(this);
|
||||
}
|
||||
else if (interact)
|
||||
{
|
||||
if (isAutoAttackable(player) && (Math.abs(player.getZ() - getZ()) < 100))
|
||||
{
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,576 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.cache.HtmCache;
|
||||
import com.l2jserver.gameserver.datatables.ItemTable;
|
||||
import com.l2jserver.gameserver.datatables.MultisellData;
|
||||
import com.l2jserver.gameserver.datatables.TeleportLocationTable;
|
||||
import com.l2jserver.gameserver.datatables.TeleportersData;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jserver.gameserver.instancemanager.SiegeManager;
|
||||
import com.l2jserver.gameserver.instancemanager.TownManager;
|
||||
import com.l2jserver.gameserver.model.L2TeleportLocation;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
|
||||
import com.l2jserver.gameserver.model.items.L2Item;
|
||||
import com.l2jserver.gameserver.model.quest.QuestState;
|
||||
import com.l2jserver.gameserver.model.teleporter.TeleportHolder;
|
||||
import com.l2jserver.gameserver.model.teleporter.TeleportLocation;
|
||||
import com.l2jserver.gameserver.model.teleporter.TeleportType;
|
||||
import com.l2jserver.gameserver.model.zone.ZoneId;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* @author NightMarez
|
||||
*/
|
||||
public final class L2TeleporterInstance extends L2Npc
|
||||
{
|
||||
private static final int COND_ALL_FALSE = 0;
|
||||
private static final int COND_BUSY_BECAUSE_OF_SIEGE = 1;
|
||||
private static final int COND_OWNER = 2;
|
||||
private static final int COND_REGULAR = 3;
|
||||
|
||||
/**
|
||||
* @param objectId
|
||||
* @param template
|
||||
*/
|
||||
public L2TeleporterInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2TeleporterInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
final StringTokenizer st = new StringTokenizer(command, " ");
|
||||
final String cmd = st.nextToken();
|
||||
switch (cmd)
|
||||
{
|
||||
case "showNoblesSelect":
|
||||
{
|
||||
final NpcHtmlMessage msg = new NpcHtmlMessage(getObjectId());
|
||||
msg.setFile(player.getHtmlPrefix(), "data/html/teleporter/" + (player.isNoble() ? "nobles_select" : "not_nobles") + ".htm");
|
||||
msg.replace("%objectId%", getObjectId());
|
||||
player.sendPacket(msg);
|
||||
break;
|
||||
}
|
||||
case "showTeleports":
|
||||
{
|
||||
final TeleportType type = parseTeleportType(st);
|
||||
if (((type == TeleportType.NOBLES_TOKEN) || (type == TeleportType.NOBLES_ADENA)) && !player.isNoble())
|
||||
{
|
||||
_log.log(Level.WARNING, player + " attempted to use nobles teleport without being nobles!");
|
||||
break;
|
||||
}
|
||||
|
||||
final TeleportHolder holder = TeleportersData.getInstance().getHolder(getId());
|
||||
if (holder == null)
|
||||
{
|
||||
_log.log(Level.WARNING, player + " requested show teleports for npc with no teleport data " + toString());
|
||||
break;
|
||||
}
|
||||
|
||||
final NpcHtmlMessage msg = new NpcHtmlMessage(getObjectId());
|
||||
msg.setFile(player.getHtmlPrefix(), "data/html/teleporter/teleports.htm");
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final Collection<TeleportLocation> locs = holder.getLocations(type);
|
||||
final List<NpcStringId> questLocations = new ArrayList<>();
|
||||
for (QuestState qs : player.getAllQuestStates())
|
||||
{
|
||||
final NpcStringId npcString = qs.getQuestLocation();
|
||||
if ((npcString != null) && !questLocations.contains(npcString))
|
||||
{
|
||||
questLocations.add(npcString);
|
||||
}
|
||||
}
|
||||
|
||||
final Stream<TeleportLocation> stream = !questLocations.isEmpty() ? locs.stream().sorted((o1, o2) -> questLocations.contains(o1.getNpcStringId()) ? 1 : questLocations.contains(o2.getNpcStringId()) ? -1 : 0) : locs.stream();
|
||||
stream.forEach(loc ->
|
||||
{
|
||||
final int id = loc.getId();
|
||||
|
||||
String finalName = loc.getName();
|
||||
String confirmDesc = loc.getName();
|
||||
if (loc.getNpcStringId() != null)
|
||||
{
|
||||
finalName = "<fstring>" + loc.getNpcStringId().getId() + "</fstring>";
|
||||
confirmDesc = "F;" + loc.getNpcStringId().getId();
|
||||
}
|
||||
if (shouldPayFee(player, loc))
|
||||
{
|
||||
finalName += " - " + loc.getFeeCount() + " " + getItemName(loc.getFeeId(), true);
|
||||
}
|
||||
sb.append("<button align=left icon=" + (!questLocations.contains(loc.getNpcStringId()) ? "teleport" : "quest") + " action=\"bypass -h npc_" + getObjectId() + "_teleport " + type.ordinal() + " " + id + "\" msg=\"811;" + confirmDesc + "\">" + finalName + "</button>");
|
||||
});
|
||||
msg.replace("%locations%", sb.toString());
|
||||
player.sendPacket(msg);
|
||||
break;
|
||||
}
|
||||
case "teleport":
|
||||
{
|
||||
final int typeId = parseNextInt(st, -1);
|
||||
if ((typeId < 0) || (typeId > TeleportType.values().length))
|
||||
{
|
||||
_log.log(Level.WARNING, player + " attempted to use incorrect teleport type: " + typeId);
|
||||
return;
|
||||
}
|
||||
|
||||
final TeleportType type = TeleportType.values()[typeId];
|
||||
if (((type == TeleportType.NOBLES_TOKEN) || (type == TeleportType.NOBLES_ADENA)) && !player.isNoble())
|
||||
{
|
||||
_log.log(Level.WARNING, player + " attempted to use nobles teleport without being nobles!");
|
||||
break;
|
||||
}
|
||||
|
||||
final int locId = parseNextInt(st, -1);
|
||||
final TeleportHolder holder = TeleportersData.getInstance().getHolder(getId());
|
||||
if (holder == null)
|
||||
{
|
||||
_log.log(Level.WARNING, player + " requested show teleports for npc with no teleport data " + toString());
|
||||
break;
|
||||
}
|
||||
final TeleportLocation loc = holder.getLocation(type, locId);
|
||||
if (loc == null)
|
||||
{
|
||||
_log.log(Level.WARNING, player + " attempted to use not existing teleport location id: " + locId);
|
||||
return;
|
||||
}
|
||||
|
||||
// you cannot teleport to village that is in siege
|
||||
if (SiegeManager.getInstance().getSiege(loc.getX(), loc.getY(), loc.getZ()) != null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_TO_A_VILLAGE_THAT_IS_IN_A_SIEGE);
|
||||
}
|
||||
else if (TownManager.townHasCastleInSiege(loc.getX(), loc.getY()) && isInsideZone(ZoneId.TOWN))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_TO_A_VILLAGE_THAT_IS_IN_A_SIEGE);
|
||||
}
|
||||
else if (getCastle().getSiege().isInProgress())
|
||||
{
|
||||
final NpcHtmlMessage msg = new NpcHtmlMessage(getObjectId());
|
||||
msg.setFile(player.getHtmlPrefix(), "data/html/teleporter/castleteleporter-busy.htm");
|
||||
player.sendPacket(msg);
|
||||
}
|
||||
else if (!Config.ALT_GAME_KARMA_PLAYER_CAN_USE_GK && (player.getKarma() != 0)) // TODO: Update me when Karma is replaced with Reputation system!
|
||||
{
|
||||
player.sendMessage("Go away, you're not welcome here.");
|
||||
}
|
||||
else if (player.isCombatFlagEquipped())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_WHILE_IN_POSSESSION_OF_A_WARD);
|
||||
}
|
||||
else if (shouldPayFee(player, loc) && !player.destroyItemByItemId("Teleport", loc.getFeeId(), loc.getFeeCount(), this, true))
|
||||
{
|
||||
if (loc.getFeeId() == Inventory.ADENA_ID)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_DO_NOT_HAVE_ENOUGH_ADENA);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage("You do not have enough " + getItemName(loc.getFeeId(), false));
|
||||
}
|
||||
}
|
||||
else if (!player.isAlikeDead())
|
||||
{
|
||||
player.teleToLocation(loc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
processLegacyBypass(player, command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean shouldPayFee(L2PcInstance player, TeleportLocation loc)
|
||||
{
|
||||
return Config.ALT_GAME_FREE_TELEPORT || ((player.getLevel() >= 76) && ((loc.getFeeId() != 0) && (loc.getFeeCount() > 0)));
|
||||
}
|
||||
|
||||
protected int parseNextInt(StringTokenizer st, int defaultVal)
|
||||
{
|
||||
if (st.hasMoreTokens())
|
||||
{
|
||||
final String token = st.nextToken();
|
||||
if (Util.isDigit(token))
|
||||
{
|
||||
return Integer.valueOf(token);
|
||||
}
|
||||
}
|
||||
return defaultVal;
|
||||
}
|
||||
|
||||
protected TeleportType parseTeleportType(StringTokenizer st)
|
||||
{
|
||||
TeleportType type = TeleportType.NORMAL;
|
||||
if (st.hasMoreTokens())
|
||||
{
|
||||
final String typeToken = st.nextToken();
|
||||
for (TeleportType teleportType : TeleportType.values())
|
||||
{
|
||||
if (teleportType.name().equalsIgnoreCase(typeToken))
|
||||
{
|
||||
type = teleportType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
protected String getItemName(int itemId, boolean fstring)
|
||||
{
|
||||
if (fstring)
|
||||
{
|
||||
if (itemId == Inventory.ADENA_ID)
|
||||
{
|
||||
return "<fstring>1000308</fstring>";
|
||||
}
|
||||
else if (itemId == Inventory.ANCIENT_ADENA_ID)
|
||||
{
|
||||
return "<fstring>1000309</fstring>";
|
||||
}
|
||||
}
|
||||
final L2Item item = ItemTable.getInstance().getTemplate(itemId);
|
||||
if (item != null)
|
||||
{
|
||||
return item.getName();
|
||||
}
|
||||
switch (itemId)
|
||||
{
|
||||
case MultisellData.PC_BANG_POINTS:
|
||||
{
|
||||
return "Player Commendation Points";
|
||||
}
|
||||
case MultisellData.CLAN_REPUTATION:
|
||||
{
|
||||
return "Clan Reputation Points";
|
||||
}
|
||||
case MultisellData.FAME:
|
||||
{
|
||||
return "Fame";
|
||||
}
|
||||
}
|
||||
return "Unknown item: " + itemId;
|
||||
}
|
||||
|
||||
private void processLegacyBypass(L2PcInstance player, String command)
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
|
||||
int condition = validateCondition(player);
|
||||
|
||||
StringTokenizer st = new StringTokenizer(command, " ");
|
||||
String actualCommand = st.nextToken(); // Get actual command
|
||||
|
||||
if (player.isAffectedBySkill(6201) || player.isAffectedBySkill(6202) || player.isAffectedBySkill(6203))
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
|
||||
String filename = "data/html/teleporter/epictransformed.htm";
|
||||
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
html.replace("%npcname%", getName());
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("goto"))
|
||||
{
|
||||
int npcId = getId();
|
||||
|
||||
switch (npcId)
|
||||
{
|
||||
case 32534: // Seed of Infinity
|
||||
case 32539:
|
||||
if (player.isFlyingMounted())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_ENTER_A_SEED_WHILE_IN_A_FLYING_TRANSFORMATION_STATE);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (st.countTokens() <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int whereTo = Integer.parseInt(st.nextToken());
|
||||
if (condition == COND_REGULAR)
|
||||
{
|
||||
doTeleport(player, whereTo);
|
||||
return;
|
||||
}
|
||||
else if (condition == COND_OWNER)
|
||||
{
|
||||
// TODO: Replace 0 with highest level when privilege level is implemented
|
||||
int minPrivilegeLevel = 0;
|
||||
if (st.countTokens() >= 1)
|
||||
{
|
||||
minPrivilegeLevel = Integer.parseInt(st.nextToken());
|
||||
}
|
||||
|
||||
// TODO: Replace 10 with privilege level of player
|
||||
if (10 >= minPrivilegeLevel)
|
||||
{
|
||||
doTeleport(player, whereTo);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage("You don't have the sufficient access level to teleport there.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (command.startsWith("Chat"))
|
||||
{
|
||||
Calendar cal = Calendar.getInstance();
|
||||
int val = 0;
|
||||
try
|
||||
{
|
||||
val = Integer.parseInt(command.substring(5));
|
||||
}
|
||||
catch (IndexOutOfBoundsException ioobe)
|
||||
{
|
||||
}
|
||||
catch (NumberFormatException nfe)
|
||||
{
|
||||
}
|
||||
|
||||
if ((val == 1) && (player.getLevel() < 41))
|
||||
{
|
||||
showNewbieHtml(player);
|
||||
return;
|
||||
}
|
||||
else if ((val == 1) && (cal.get(Calendar.HOUR_OF_DAY) >= 20) && (cal.get(Calendar.HOUR_OF_DAY) <= 23) && ((cal.get(Calendar.DAY_OF_WEEK) == 1) || (cal.get(Calendar.DAY_OF_WEEK) == 7)))
|
||||
{
|
||||
showHalfPriceHtml(player);
|
||||
return;
|
||||
}
|
||||
showChatWindow(player, val);
|
||||
}
|
||||
super.onBypassFeedback(player, command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "data/html/teleporter/" + pom + ".htm";
|
||||
}
|
||||
|
||||
private void showNewbieHtml(L2PcInstance player)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
|
||||
String filename = "data/html/teleporter/free/" + getTemplate().getId() + ".htm";
|
||||
if (!HtmCache.getInstance().isLoadable(filename))
|
||||
{
|
||||
filename = "data/html/teleporter/" + getTemplate().getId() + "-1.htm";
|
||||
}
|
||||
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
html.replace("%npcname%", getName());
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
private void showHalfPriceHtml(L2PcInstance player)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
|
||||
String filename = "data/html/teleporter/half/" + getId() + ".htm";
|
||||
if (!HtmCache.getInstance().isLoadable(filename))
|
||||
{
|
||||
filename = "data/html/teleporter/" + getId() + "-1.htm";
|
||||
}
|
||||
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
html.replace("%npcname%", getName());
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showChatWindow(L2PcInstance player)
|
||||
{
|
||||
String filename = "data/html/teleporter/castleteleporter-no.htm";
|
||||
|
||||
int condition = validateCondition(player);
|
||||
if (condition == COND_REGULAR)
|
||||
{
|
||||
super.showChatWindow(player);
|
||||
return;
|
||||
}
|
||||
else if (condition > COND_ALL_FALSE)
|
||||
{
|
||||
if (condition == COND_BUSY_BECAUSE_OF_SIEGE)
|
||||
{
|
||||
filename = "data/html/teleporter/castleteleporter-busy.htm"; // Busy because of siege
|
||||
}
|
||||
else if (condition == COND_OWNER) // Clan owns castle
|
||||
{
|
||||
filename = getHtmlPath(getId(), 0); // Owner message window
|
||||
}
|
||||
}
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
html.replace("%npcname%", getName());
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
private void doTeleport(L2PcInstance player, int val)
|
||||
{
|
||||
L2TeleportLocation list = TeleportLocationTable.getInstance().getTemplate(val);
|
||||
if (list != null)
|
||||
{
|
||||
// you cannot teleport to village that is in siege
|
||||
if (SiegeManager.getInstance().getSiege(list.getLocX(), list.getLocY(), list.getLocZ()) != null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_TO_A_VILLAGE_THAT_IS_IN_A_SIEGE);
|
||||
return;
|
||||
}
|
||||
else if (TownManager.townHasCastleInSiege(list.getLocX(), list.getLocY()) && isInsideZone(ZoneId.TOWN))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_TO_A_VILLAGE_THAT_IS_IN_A_SIEGE);
|
||||
return;
|
||||
}
|
||||
else if (!Config.ALT_GAME_KARMA_PLAYER_CAN_USE_GK && (player.getKarma() > 0)) // karma
|
||||
{
|
||||
player.sendMessage("Go away, you're not welcome here.");
|
||||
return;
|
||||
}
|
||||
else if (player.isCombatFlagEquipped())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_TELEPORT_WHILE_IN_POSSESSION_OF_A_WARD);
|
||||
return;
|
||||
}
|
||||
else if (list.getIsForNoble() && !player.isNoble())
|
||||
{
|
||||
String filename = "data/html/teleporter/nobleteleporter-no.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
html.replace("%npcname%", getName());
|
||||
player.sendPacket(html);
|
||||
return;
|
||||
}
|
||||
else if (player.isAlikeDead())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
int price = list.getPrice();
|
||||
|
||||
if (player.getLevel() < 41)
|
||||
{
|
||||
price = 0;
|
||||
}
|
||||
else if (!list.getIsForNoble())
|
||||
{
|
||||
if ((cal.get(Calendar.HOUR_OF_DAY) >= 20) && (cal.get(Calendar.HOUR_OF_DAY) <= 23) && ((cal.get(Calendar.DAY_OF_WEEK) == 1) || (cal.get(Calendar.DAY_OF_WEEK) == 7)))
|
||||
{
|
||||
price /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.ALT_GAME_FREE_TELEPORT || player.destroyItemByItemId("Teleport " + (list.getIsForNoble() ? " nobless" : ""), list.getItemId(), price, this, true))
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Teleporting player " + player.getName() + " to new location: " + list.getLocX() + ":" + list.getLocY() + ":" + list.getLocZ());
|
||||
}
|
||||
|
||||
player.teleToLocation(list.getLocX(), list.getLocY(), list.getLocZ(), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("No teleport destination with id:" + val);
|
||||
}
|
||||
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
private int validateCondition(L2PcInstance player)
|
||||
{
|
||||
// Teleporter isn't on castle ground
|
||||
if (CastleManager.getInstance().getCastleIndex(this) < 0)
|
||||
{
|
||||
return COND_REGULAR; // Regular access
|
||||
}
|
||||
// Teleporter is on castle ground and siege is in progress
|
||||
else if (getCastle().getSiege().isInProgress())
|
||||
{
|
||||
return COND_BUSY_BECAUSE_OF_SIEGE; // Busy because of siege
|
||||
}
|
||||
// Teleporter is on castle ground and player is in a clan
|
||||
else if (player.getClan() != null)
|
||||
{
|
||||
if (getCastle().getOwnerId() == player.getClanId())
|
||||
{
|
||||
return COND_OWNER; // Owner
|
||||
}
|
||||
}
|
||||
|
||||
return COND_ALL_FALSE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
|
||||
|
||||
public final class L2TerrainObjectInstance extends L2Npc
|
||||
{
|
||||
public L2TerrainObjectInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2TerrainObjectInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAction(L2PcInstance player, boolean interact)
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionShift(L2PcInstance player)
|
||||
{
|
||||
if (player.isGM())
|
||||
{
|
||||
super.onActionShift(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
public class L2TrainerInstance extends L2NpcInstance
|
||||
{
|
||||
public L2TrainerInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2TrainerInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "data/html/trainer/" + pom + ".htm";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,460 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.enums.TrapAction;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.knownlist.TrapKnownList;
|
||||
import com.l2jserver.gameserver.model.actor.tasks.npc.trap.TrapTask;
|
||||
import com.l2jserver.gameserver.model.actor.tasks.npc.trap.TrapTriggerTask;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jserver.gameserver.model.events.impl.character.trap.OnTrapAction;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.items.L2Weapon;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.model.olympiad.OlympiadGameManager;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.zone.ZoneId;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.AbstractNpcInfo.TrapInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jserver.gameserver.taskmanager.DecayTaskManager;
|
||||
|
||||
/**
|
||||
* Trap instance.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public final class L2TrapInstance extends L2Npc
|
||||
{
|
||||
private static final int TICK = 1000; // 1s
|
||||
private boolean _hasLifeTime;
|
||||
private boolean _isInArena = false;
|
||||
private boolean _isTriggered;
|
||||
private final int _lifeTime;
|
||||
private L2PcInstance _owner;
|
||||
private final List<Integer> _playersWhoDetectedMe = new ArrayList<>();
|
||||
private final SkillHolder _skill;
|
||||
private int _remainingTime;
|
||||
// Tasks
|
||||
private ScheduledFuture<?> _trapTask = null;
|
||||
|
||||
public L2TrapInstance(int objectId, L2NpcTemplate template, int instanceId, int lifeTime)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2TrapInstance);
|
||||
setInstanceId(instanceId);
|
||||
setName(template.getName());
|
||||
setIsInvul(false);
|
||||
|
||||
_owner = null;
|
||||
_isTriggered = false;
|
||||
_skill = getTemplate().getParameters().getObject("trap_skill", SkillHolder.class);
|
||||
_hasLifeTime = lifeTime >= 0;
|
||||
_lifeTime = lifeTime != 0 ? lifeTime : 30000;
|
||||
_remainingTime = _lifeTime;
|
||||
if (_skill != null)
|
||||
{
|
||||
_trapTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new TrapTask(this), TICK, TICK);
|
||||
}
|
||||
}
|
||||
|
||||
public L2TrapInstance(int objectId, L2NpcTemplate template, L2PcInstance owner, int lifeTime)
|
||||
{
|
||||
this(objectId, template, owner.getInstanceId(), lifeTime);
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastPacket(L2GameServerPacket mov)
|
||||
{
|
||||
for (L2PcInstance player : getKnownList().getKnownPlayers().values())
|
||||
{
|
||||
if ((player != null) && (_isTriggered || canBeSeen(player)))
|
||||
{
|
||||
player.sendPacket(mov);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void broadcastPacket(L2GameServerPacket mov, int radiusInKnownlist)
|
||||
{
|
||||
for (L2PcInstance player : getKnownList().getKnownPlayers().values())
|
||||
{
|
||||
if ((player != null) && isInsideRadius(player, radiusInKnownlist, false, false) && (_isTriggered || canBeSeen(player)))
|
||||
{
|
||||
player.sendPacket(mov);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if the character can see the trap.
|
||||
* @param cha the character to verify
|
||||
* @return {@code true} if the character can see the trap, {@code false} otherwise
|
||||
*/
|
||||
public boolean canBeSeen(L2Character cha)
|
||||
{
|
||||
if ((cha != null) && _playersWhoDetectedMe.contains(cha.getObjectId()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((_owner == null) || (cha == null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (cha == _owner)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (cha instanceof L2PcInstance)
|
||||
{
|
||||
// observers can't see trap
|
||||
if (((L2PcInstance) cha).inObserverMode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// olympiad competitors can't see trap
|
||||
if (_owner.isInOlympiadMode() && ((L2PcInstance) cha).isInOlympiadMode() && (((L2PcInstance) cha).getOlympiadSide() != _owner.getOlympiadSide()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_isInArena)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_owner.isInParty() && cha.isInParty() && (_owner.getParty().getLeaderObjectId() == cha.getParty().getLeaderObjectId()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean checkTarget(L2Character target)
|
||||
{
|
||||
if (!Skill.checkForAreaOffensiveSkills(this, target, _skill.getSkill(), _isInArena))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!target.isInsideRadius(this, _skill.getSkill().getEffectRange(), false, false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// observers
|
||||
if ((target instanceof L2PcInstance) && ((L2PcInstance) target).inObserverMode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// olympiad own team and their summons not attacked
|
||||
if ((_owner != null) && _owner.isInOlympiadMode())
|
||||
{
|
||||
final L2PcInstance player = target.getActingPlayer();
|
||||
if ((player != null) && player.isInOlympiadMode() && (player.getOlympiadSide() == _owner.getOlympiadSide()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_isInArena)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// trap owned by players not attack non-flagged players
|
||||
if (_owner != null)
|
||||
{
|
||||
if (target instanceof L2Attackable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
final L2PcInstance player = target.getActingPlayer();
|
||||
if ((player == null) || ((player.getPvpFlag() == 0) && (player.getKarma() == 0)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteMe()
|
||||
{
|
||||
if (_owner != null)
|
||||
{
|
||||
_owner.setTrap(null);
|
||||
_owner = null;
|
||||
}
|
||||
return super.deleteMe();
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2PcInstance getActingPlayer()
|
||||
{
|
||||
return _owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Weapon getActiveWeaponItem()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getKarma()
|
||||
{
|
||||
return _owner != null ? _owner.getKarma() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrapKnownList getKnownList()
|
||||
{
|
||||
return (TrapKnownList) super.getKnownList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the owner of this trap.
|
||||
* @return the owner
|
||||
*/
|
||||
public L2PcInstance getOwner()
|
||||
{
|
||||
return _owner;
|
||||
}
|
||||
|
||||
public byte getPvpFlag()
|
||||
{
|
||||
return _owner != null ? _owner.getPvpFlag() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2ItemInstance getSecondaryWeaponInstance()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Weapon getSecondaryWeaponItem()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public Skill getSkill()
|
||||
{
|
||||
return _skill.getSkill();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initKnownList()
|
||||
{
|
||||
setKnownList(new TrapKnownList(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
return !canBeSeen(attacker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrap()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks is triggered
|
||||
* @return True if trap is triggered.
|
||||
*/
|
||||
public boolean isTriggered()
|
||||
{
|
||||
return _isTriggered;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
super.onSpawn();
|
||||
_isInArena = isInsideZone(ZoneId.PVP) && !isInsideZone(ZoneId.SIEGE);
|
||||
_playersWhoDetectedMe.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDamageMessage(L2Character target, int damage, boolean mcrit, boolean pcrit, boolean miss)
|
||||
{
|
||||
if (miss || (_owner == null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_owner.isInOlympiadMode() && (target instanceof L2PcInstance) && ((L2PcInstance) target).isInOlympiadMode() && (((L2PcInstance) target).getOlympiadGameId() == _owner.getOlympiadGameId()))
|
||||
{
|
||||
OlympiadGameManager.getInstance().notifyCompetitorDamage(getOwner(), damage);
|
||||
}
|
||||
|
||||
if (target.isInvul() && !(target instanceof L2NpcInstance))
|
||||
{
|
||||
_owner.sendPacket(SystemMessageId.THE_ATTACK_HAS_BEEN_BLOCKED);
|
||||
}
|
||||
else
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_INFLICTED_S3_DAMAGE_ON_C2_S4);
|
||||
sm.addCharName(this);
|
||||
sm.addCharName(target);
|
||||
sm.addInt(damage);
|
||||
sm.addPopup(target.getObjectId(), getObjectId(), (damage * -1));
|
||||
_owner.sendPacket(sm);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendInfo(L2PcInstance activeChar)
|
||||
{
|
||||
if (_isTriggered || canBeSeen(activeChar))
|
||||
{
|
||||
activeChar.sendPacket(new TrapInfo(this, activeChar));
|
||||
}
|
||||
}
|
||||
|
||||
public void setDetected(L2Character detector)
|
||||
{
|
||||
if (_isInArena)
|
||||
{
|
||||
if (detector.isPlayable())
|
||||
{
|
||||
sendInfo(detector.getActingPlayer());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((_owner != null) && (_owner.getPvpFlag() == 0) && (_owner.getKarma() == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_playersWhoDetectedMe.add(detector.getObjectId());
|
||||
|
||||
// Notify to scripts
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnTrapAction(this, detector, TrapAction.TRAP_DETECTED), this);
|
||||
|
||||
if (detector.isPlayable())
|
||||
{
|
||||
sendInfo(detector.getActingPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
public void stopDecay()
|
||||
{
|
||||
DecayTaskManager.getInstance().cancel(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger the trap.
|
||||
* @param target the target
|
||||
*/
|
||||
public void triggerTrap(L2Character target)
|
||||
{
|
||||
if (_trapTask != null)
|
||||
{
|
||||
_trapTask.cancel(true);
|
||||
_trapTask = null;
|
||||
}
|
||||
|
||||
_isTriggered = true;
|
||||
broadcastPacket(new TrapInfo(this, null));
|
||||
setTarget(target);
|
||||
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnTrapAction(this, target, TrapAction.TRAP_TRIGGERED), this);
|
||||
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new TrapTriggerTask(this), 300);
|
||||
}
|
||||
|
||||
public void unSummon()
|
||||
{
|
||||
if (_trapTask != null)
|
||||
{
|
||||
_trapTask.cancel(true);
|
||||
_trapTask = null;
|
||||
}
|
||||
|
||||
if (_owner != null)
|
||||
{
|
||||
_owner.setTrap(null);
|
||||
_owner = null;
|
||||
}
|
||||
|
||||
if (isVisible() && !isDead())
|
||||
{
|
||||
if (getWorldRegion() != null)
|
||||
{
|
||||
getWorldRegion().removeFromZones(this);
|
||||
}
|
||||
|
||||
deleteMe();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAbnormalEffect()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public boolean hasLifeTime()
|
||||
{
|
||||
return _hasLifeTime;
|
||||
}
|
||||
|
||||
public void setHasLifeTime(boolean val)
|
||||
{
|
||||
_hasLifeTime = val;
|
||||
}
|
||||
|
||||
public int getRemainingTime()
|
||||
{
|
||||
return _remainingTime;
|
||||
}
|
||||
|
||||
public void setRemainingTime(int time)
|
||||
{
|
||||
_remainingTime = time;
|
||||
}
|
||||
|
||||
public int getLifeTime()
|
||||
{
|
||||
return _lifeTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.Race;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.base.PlayerClass;
|
||||
|
||||
public final class L2VillageMasterDElfInstance extends L2VillageMasterInstance
|
||||
{
|
||||
public L2VillageMasterDElfInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterRace(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfRace(Race.DARK_ELF);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.Race;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.base.PlayerClass;
|
||||
|
||||
public final class L2VillageMasterDwarfInstance extends L2VillageMasterInstance
|
||||
{
|
||||
public L2VillageMasterDwarfInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterRace(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfRace(Race.DWARF);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.Race;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.base.ClassType;
|
||||
import com.l2jserver.gameserver.model.base.PlayerClass;
|
||||
|
||||
public final class L2VillageMasterFighterInstance extends L2VillageMasterInstance
|
||||
{
|
||||
public L2VillageMasterFighterInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterRace(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfRace(Race.HUMAN) || pclass.isOfRace(Race.ELF);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterTeachType(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfType(ClassType.Fighter);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.enums.Race;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.base.PlayerClass;
|
||||
import com.l2jserver.gameserver.model.quest.QuestState;
|
||||
|
||||
public final class L2VillageMasterKamaelInstance extends L2VillageMasterInstance
|
||||
{
|
||||
public L2VillageMasterKamaelInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final String getSubClassMenu(Race race)
|
||||
{
|
||||
if (Config.ALT_GAME_SUBCLASS_EVERYWHERE || (race == Race.KAMAEL))
|
||||
{
|
||||
return "data/html/villagemaster/SubClass.htm";
|
||||
}
|
||||
|
||||
return "data/html/villagemaster/SubClass_NoKamael.htm";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final String getSubClassFail()
|
||||
{
|
||||
return "data/html/villagemaster/SubClass_Fail_Kamael.htm";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkQuests(L2PcInstance player)
|
||||
{
|
||||
// Noble players can add subbclasses without quests
|
||||
if (player.isNoble())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
QuestState qs = player.getQuestState("234_FatesWhisper");
|
||||
if ((qs == null) || !qs.isCompleted())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qs = player.getQuestState("236_SeedsOfChaos");
|
||||
if ((qs == null) || !qs.isCompleted())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterRace(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfRace(Race.KAMAEL);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.Race;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.base.ClassType;
|
||||
import com.l2jserver.gameserver.model.base.PlayerClass;
|
||||
|
||||
public final class L2VillageMasterMysticInstance extends L2VillageMasterInstance
|
||||
{
|
||||
public L2VillageMasterMysticInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterRace(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfRace(Race.HUMAN) || pclass.isOfRace(Race.ELF);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterTeachType(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfType(ClassType.Mystic);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.Race;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.base.PlayerClass;
|
||||
|
||||
public final class L2VillageMasterOrcInstance extends L2VillageMasterInstance
|
||||
{
|
||||
public L2VillageMasterOrcInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterRace(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfRace(Race.ORC);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.Race;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.base.ClassType;
|
||||
import com.l2jserver.gameserver.model.base.PlayerClass;
|
||||
|
||||
public final class L2VillageMasterPriestInstance extends L2VillageMasterInstance
|
||||
{
|
||||
public L2VillageMasterPriestInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterRace(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfRace(Race.HUMAN) || pclass.isOfRace(Race.ELF);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterTeachType(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfType(ClassType.Priest);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
public class L2WarehouseInstance extends L2NpcInstance
|
||||
{
|
||||
/**
|
||||
* @param objectId
|
||||
* @param template
|
||||
*/
|
||||
public L2WarehouseInstance(int objectId, L2NpcTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2WarehouseInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWarehouse()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "data/html/warehouse/" + pom + ".htm";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
public class AttackableKnownList extends NpcKnownList
|
||||
{
|
||||
public AttackableKnownList(L2Attackable activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeKnownObject(L2Object object, boolean forget)
|
||||
{
|
||||
if (!super.removeKnownObject(object, forget))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the L2Object from the _aggrolist of the L2Attackable
|
||||
if (object instanceof L2Character)
|
||||
{
|
||||
getActiveChar().getAggroList().remove(object);
|
||||
}
|
||||
// Set the L2Attackable Intention to AI_INTENTION_IDLE
|
||||
final Collection<L2PcInstance> known = getKnownPlayers().values();
|
||||
|
||||
// FIXME: This is a temporary solution && support for Walking Manager
|
||||
if (getActiveChar().hasAI() && ((known == null) || known.isEmpty()) && !getActiveChar().isWalker())
|
||||
{
|
||||
getActiveChar().getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Attackable getActiveChar()
|
||||
{
|
||||
return (L2Attackable) super.getActiveChar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToForgetObject(L2Object object)
|
||||
{
|
||||
return (int) (getDistanceToWatchObject(object) * 1.5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToWatchObject(L2Object object)
|
||||
{
|
||||
if (!(object instanceof L2Character))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (object.isPlayable())
|
||||
{
|
||||
return object.getKnownList().getDistanceToWatchObject(getActiveObject());
|
||||
}
|
||||
|
||||
int max = Math.max(300, Math.max(getActiveChar().getAggroRange(), getActiveChar().getTemplate().getClanHelpRange()));
|
||||
|
||||
return max;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
public class CharKnownList extends ObjectKnownList
|
||||
{
|
||||
private Map<Integer, L2PcInstance> _knownPlayers;
|
||||
private Map<Integer, L2Summon> _knownSummons;
|
||||
private Map<Integer, Integer> _knownRelations;
|
||||
|
||||
public CharKnownList(L2Character activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addKnownObject(L2Object object)
|
||||
{
|
||||
if (!super.addKnownObject(object))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (object.isPlayer())
|
||||
{
|
||||
getKnownPlayers().put(object.getObjectId(), object.getActingPlayer());
|
||||
getKnownRelations().put(object.getObjectId(), -1);
|
||||
}
|
||||
else if (object.isSummon())
|
||||
{
|
||||
getKnownSummons().put(object.getObjectId(), (L2Summon) object);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param player The L2PcInstance to search in _knownPlayer
|
||||
* @return {@code true} if the player is in _knownPlayer of the character, {@code false} otherwise
|
||||
*/
|
||||
public final boolean knowsThePlayer(L2PcInstance player)
|
||||
{
|
||||
return (getActiveChar() == player) || getKnownPlayers().containsKey(player.getObjectId());
|
||||
}
|
||||
|
||||
/** Remove all L2Object from _knownObjects and _knownPlayer of the L2Character then cancel Attack or Cast and notify AI. */
|
||||
@Override
|
||||
public final void removeAllKnownObjects()
|
||||
{
|
||||
super.removeAllKnownObjects();
|
||||
getKnownPlayers().clear();
|
||||
getKnownRelations().clear();
|
||||
getKnownSummons().clear();
|
||||
|
||||
// Set _target of the L2Character to null
|
||||
// Cancel Attack or Cast
|
||||
getActiveChar().setTarget(null);
|
||||
|
||||
// Cancel AI Task
|
||||
if (getActiveChar().hasAI())
|
||||
{
|
||||
getActiveChar().setAI(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeKnownObject(L2Object object, boolean forget)
|
||||
{
|
||||
if (!super.removeKnownObject(object, forget))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!forget) // on forget objects removed by iterator
|
||||
{
|
||||
if (object.isPlayer())
|
||||
{
|
||||
getKnownPlayers().remove(object.getObjectId());
|
||||
getKnownRelations().remove(object.getObjectId());
|
||||
}
|
||||
else if (object.isSummon())
|
||||
{
|
||||
getKnownSummons().remove(object.getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
// If object is targeted by the L2Character, cancel Attack or Cast
|
||||
if (object == getActiveChar().getTarget())
|
||||
{
|
||||
getActiveChar().setTarget(null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forgetObjects(boolean fullCheck)
|
||||
{
|
||||
if (!fullCheck)
|
||||
{
|
||||
final Collection<L2PcInstance> plrs = getKnownPlayers().values();
|
||||
final Iterator<L2PcInstance> pIter = plrs.iterator();
|
||||
L2PcInstance player;
|
||||
while (pIter.hasNext())
|
||||
{
|
||||
player = pIter.next();
|
||||
if (player == null)
|
||||
{
|
||||
pIter.remove();
|
||||
}
|
||||
else if (!player.isVisible() || !Util.checkIfInShortRadius(getDistanceToForgetObject(player), getActiveObject(), player, true))
|
||||
{
|
||||
pIter.remove();
|
||||
removeKnownObject(player, true);
|
||||
getKnownRelations().remove(player.getObjectId());
|
||||
getKnownObjects().remove(player.getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
final Collection<L2Summon> sums = getKnownSummons().values();
|
||||
final Iterator<L2Summon> sIter = sums.iterator();
|
||||
L2Summon summon;
|
||||
|
||||
while (sIter.hasNext())
|
||||
{
|
||||
summon = sIter.next();
|
||||
if (summon == null)
|
||||
{
|
||||
sIter.remove();
|
||||
}
|
||||
else if (getActiveChar().isPlayer() && (summon.getOwner() == getActiveChar()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (!summon.isVisible() || !Util.checkIfInShortRadius(getDistanceToForgetObject(summon), getActiveObject(), summon, true))
|
||||
{
|
||||
sIter.remove();
|
||||
removeKnownObject(summon, true);
|
||||
getKnownObjects().remove(summon.getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
// Go through knownObjects
|
||||
final Collection<L2Object> objs = getKnownObjects().values();
|
||||
final Iterator<L2Object> oIter = objs.iterator();
|
||||
L2Object object;
|
||||
while (oIter.hasNext())
|
||||
{
|
||||
object = oIter.next();
|
||||
if (object == null)
|
||||
{
|
||||
oIter.remove();
|
||||
}
|
||||
else if (!object.isVisible() || !Util.checkIfInShortRadius(getDistanceToForgetObject(object), getActiveObject(), object, true))
|
||||
{
|
||||
oIter.remove();
|
||||
removeKnownObject(object, true);
|
||||
|
||||
if (object.isPlayer())
|
||||
{
|
||||
getKnownPlayers().remove(object.getObjectId());
|
||||
getKnownRelations().remove(object.getObjectId());
|
||||
}
|
||||
else if (object.isSummon())
|
||||
{
|
||||
getKnownSummons().remove(object.getObjectId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public L2Character getActiveChar()
|
||||
{
|
||||
return (L2Character) super.getActiveObject();
|
||||
}
|
||||
|
||||
public Collection<L2Character> getKnownCharacters()
|
||||
{
|
||||
FastList<L2Character> result = new FastList<>();
|
||||
|
||||
final Collection<L2Object> objs = getKnownObjects().values();
|
||||
for (L2Object obj : objs)
|
||||
{
|
||||
if (obj instanceof L2Character)
|
||||
{
|
||||
result.add((L2Character) obj);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection<L2Character> getKnownCharactersInRadius(long radius)
|
||||
{
|
||||
List<L2Character> result = new ArrayList<>();
|
||||
|
||||
final Collection<L2Object> objs = getKnownObjects().values();
|
||||
for (L2Object obj : objs)
|
||||
{
|
||||
if (obj instanceof L2Character)
|
||||
{
|
||||
if (Util.checkIfInRange((int) radius, getActiveChar(), obj, true))
|
||||
{
|
||||
result.add((L2Character) obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public final Map<Integer, L2PcInstance> getKnownPlayers()
|
||||
{
|
||||
if (_knownPlayers == null)
|
||||
{
|
||||
_knownPlayers = new ConcurrentHashMap<>();
|
||||
}
|
||||
return _knownPlayers;
|
||||
}
|
||||
|
||||
public final Map<Integer, Integer> getKnownRelations()
|
||||
{
|
||||
if (_knownRelations == null)
|
||||
{
|
||||
_knownRelations = new ConcurrentHashMap<>();
|
||||
}
|
||||
return _knownRelations;
|
||||
}
|
||||
|
||||
public final Map<Integer, L2Summon> getKnownSummons()
|
||||
{
|
||||
if (_knownSummons == null)
|
||||
{
|
||||
_knownSummons = new ConcurrentHashMap<>();
|
||||
}
|
||||
return _knownSummons;
|
||||
}
|
||||
|
||||
public final Collection<L2PcInstance> getKnownPlayersInRadius(long radius)
|
||||
{
|
||||
List<L2PcInstance> result = new ArrayList<>();
|
||||
|
||||
final Collection<L2PcInstance> plrs = getKnownPlayers().values();
|
||||
for (L2PcInstance player : plrs)
|
||||
{
|
||||
if (Util.checkIfInRange((int) radius, getActiveChar(), player, true))
|
||||
{
|
||||
result.add(player);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Decoy;
|
||||
|
||||
public class DecoyKnownList extends CharKnownList
|
||||
{
|
||||
public DecoyKnownList(L2Decoy activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final L2Decoy getActiveChar()
|
||||
{
|
||||
return (L2Decoy) super.getActiveChar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToForgetObject(L2Object object)
|
||||
{
|
||||
if ((object == getActiveChar().getOwner()) || (object == getActiveChar().getTarget()))
|
||||
{
|
||||
return 6000;
|
||||
}
|
||||
return 3000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToWatchObject(L2Object object)
|
||||
{
|
||||
return 1500;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2DefenderInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.entity.Castle;
|
||||
import com.l2jserver.gameserver.model.entity.Fort;
|
||||
import com.l2jserver.gameserver.model.entity.clanhall.SiegableHall;
|
||||
|
||||
public class DefenderKnownList extends AttackableKnownList
|
||||
{
|
||||
public DefenderKnownList(L2DefenderInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addKnownObject(L2Object object)
|
||||
{
|
||||
if (!super.addKnownObject(object))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Castle castle = getActiveChar().getCastle();
|
||||
Fort fortress = getActiveChar().getFort();
|
||||
SiegableHall hall = getActiveChar().getConquerableHall();
|
||||
// Check if siege is in progress
|
||||
if (((fortress != null) && fortress.getZone().isActive()) || ((castle != null) && castle.getZone().isActive()) || ((hall != null) && hall.getSiegeZone().isActive()))
|
||||
{
|
||||
L2PcInstance player = null;
|
||||
if (object.isPlayable())
|
||||
{
|
||||
player = object.getActingPlayer();
|
||||
}
|
||||
int activeSiegeId = (fortress != null ? fortress.getResidenceId() : (castle != null ? castle.getResidenceId() : hall != null ? hall.getId() : 0));
|
||||
|
||||
// Check if player is an enemy of this defender npc
|
||||
if ((player != null) && (((player.getSiegeState() == 2) && !player.isRegisteredOnThisSiegeField(activeSiegeId)) || ((player.getSiegeState() == 1)) || (player.getSiegeState() == 0)))
|
||||
{
|
||||
if (getActiveChar().getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)
|
||||
{
|
||||
getActiveChar().getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final L2DefenderInstance getActiveChar()
|
||||
{
|
||||
return (L2DefenderInstance) super.getActiveChar();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2DefenderInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
|
||||
|
||||
public class DoorKnownList extends CharKnownList
|
||||
{
|
||||
public DoorKnownList(L2DoorInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final L2DoorInstance getActiveChar()
|
||||
{
|
||||
return (L2DoorInstance) super.getActiveChar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToForgetObject(L2Object object)
|
||||
{
|
||||
if (object instanceof L2DefenderInstance)
|
||||
{
|
||||
return 800;
|
||||
}
|
||||
else if (!object.isPlayer())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 4000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToWatchObject(L2Object object)
|
||||
{
|
||||
if (object instanceof L2DefenderInstance)
|
||||
{
|
||||
return 600;
|
||||
}
|
||||
else if (!object.isPlayer())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 3500;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlEvent;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2FriendlyMobInstance;
|
||||
|
||||
public class FriendlyMobKnownList extends AttackableKnownList
|
||||
{
|
||||
public FriendlyMobKnownList(L2FriendlyMobInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addKnownObject(L2Object object)
|
||||
{
|
||||
if (!super.addKnownObject(object))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (object.isPlayer() && (getActiveChar().getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE))
|
||||
{
|
||||
getActiveChar().getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeKnownObject(L2Object object, boolean forget)
|
||||
{
|
||||
if (!super.removeKnownObject(object, forget))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(object instanceof L2Character))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (getActiveChar().hasAI())
|
||||
{
|
||||
getActiveChar().getAI().notifyEvent(CtrlEvent.EVT_FORGET_OBJECT, object);
|
||||
if (getActiveChar().getTarget() == object)
|
||||
{
|
||||
getActiveChar().setTarget(null);
|
||||
}
|
||||
}
|
||||
|
||||
if (getActiveChar().isVisible() && getKnownPlayers().isEmpty() && getKnownSummons().isEmpty())
|
||||
{
|
||||
getActiveChar().clearAggroList();
|
||||
if (getActiveChar().hasAI())
|
||||
{
|
||||
getActiveChar().getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final L2FriendlyMobInstance getActiveChar()
|
||||
{
|
||||
return (L2FriendlyMobInstance) super.getActiveChar();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2GuardInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
|
||||
public class GuardKnownList extends AttackableKnownList
|
||||
{
|
||||
private static final Logger _log = Logger.getLogger(GuardKnownList.class.getName());
|
||||
|
||||
public GuardKnownList(L2GuardInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addKnownObject(L2Object object)
|
||||
{
|
||||
if (!super.addKnownObject(object))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (object.isPlayer())
|
||||
{
|
||||
// Check if the object added is a L2PcInstance that owns Karma
|
||||
if (object.getActingPlayer().getKarma() > 0)
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.fine(getActiveChar().getObjectId() + ": PK " + object.getObjectId() + " entered scan range");
|
||||
}
|
||||
|
||||
// Set the L2GuardInstance Intention to AI_INTENTION_ACTIVE
|
||||
if (getActiveChar().getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)
|
||||
{
|
||||
getActiveChar().getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((Config.GUARD_ATTACK_AGGRO_MOB && getActiveChar().isInActiveRegion()) && object.isMonster())
|
||||
{
|
||||
// Check if the object added is an aggressive L2MonsterInstance
|
||||
if (((L2MonsterInstance) object).isAggressive())
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.fine(getActiveChar().getObjectId() + ": Aggressive mob " + object.getObjectId() + " entered scan range");
|
||||
}
|
||||
|
||||
// Set the L2GuardInstance Intention to AI_INTENTION_ACTIVE
|
||||
if (getActiveChar().getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)
|
||||
{
|
||||
getActiveChar().getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeKnownObject(L2Object object, boolean forget)
|
||||
{
|
||||
if (!super.removeKnownObject(object, forget))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the aggression list of this guard is empty.
|
||||
if (getActiveChar().getAggroList().isEmpty())
|
||||
{
|
||||
// Set the L2GuardInstance to AI_INTENTION_IDLE
|
||||
if (getActiveChar().hasAI() && !getActiveChar().isWalker())
|
||||
{
|
||||
getActiveChar().getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final L2GuardInstance getActiveChar()
|
||||
{
|
||||
return (L2GuardInstance) super.getActiveChar();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlEvent;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.ai.L2CharacterAI;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
public class MonsterKnownList extends AttackableKnownList
|
||||
{
|
||||
public MonsterKnownList(L2MonsterInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addKnownObject(L2Object object)
|
||||
{
|
||||
if (!super.addKnownObject(object))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final L2CharacterAI ai = getActiveChar().getAI(); // force AI creation
|
||||
|
||||
// Set the L2MonsterInstance Intention to AI_INTENTION_ACTIVE if the state was AI_INTENTION_IDLE
|
||||
if ((object instanceof L2PcInstance) && (ai != null) && (ai.getIntention() == CtrlIntention.AI_INTENTION_IDLE))
|
||||
{
|
||||
ai.setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeKnownObject(L2Object object, boolean forget)
|
||||
{
|
||||
if (!super.removeKnownObject(object, forget))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(object instanceof L2Character))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (getActiveChar().hasAI())
|
||||
{
|
||||
// Notify the L2MonsterInstance AI with EVT_FORGET_OBJECT
|
||||
getActiveChar().getAI().notifyEvent(CtrlEvent.EVT_FORGET_OBJECT, object);
|
||||
}
|
||||
|
||||
if (getActiveChar().isVisible() && getKnownPlayers().isEmpty() && getKnownSummons().isEmpty())
|
||||
{
|
||||
// Clear the _aggroList of the L2MonsterInstance
|
||||
getActiveChar().clearAggroList();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final L2MonsterInstance getActiveChar()
|
||||
{
|
||||
return (L2MonsterInstance) super.getActiveChar();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.enums.InstanceType;
|
||||
import com.l2jserver.gameserver.instancemanager.WalkingManager;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jserver.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
|
||||
|
||||
public class NpcKnownList extends CharKnownList
|
||||
{
|
||||
private ScheduledFuture<?> _trackingTask = null;
|
||||
|
||||
public NpcKnownList(L2Npc activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addKnownObject(L2Object object)
|
||||
{
|
||||
if (!super.addKnownObject(object))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getActiveObject().isNpc() && (object instanceof L2Character))
|
||||
{
|
||||
final L2Npc npc = (L2Npc) getActiveObject();
|
||||
|
||||
// Notify to scripts
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnNpcCreatureSee(npc, (L2Character) object, object.isSummon()), npc);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Npc getActiveChar()
|
||||
{
|
||||
return (L2Npc) super.getActiveChar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToForgetObject(L2Object object)
|
||||
{
|
||||
return 2 * getDistanceToWatchObject(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToWatchObject(L2Object object)
|
||||
{
|
||||
if (!(object instanceof L2Character))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (object.isPlayable())
|
||||
{
|
||||
return 1500;
|
||||
}
|
||||
|
||||
return 500;
|
||||
}
|
||||
|
||||
// Support for Walking monsters aggro
|
||||
public void startTrackingTask()
|
||||
{
|
||||
if ((_trackingTask == null) && (getActiveChar().getAggroRange() > 0))
|
||||
{
|
||||
_trackingTask = ThreadPoolManager.getInstance().scheduleAiAtFixedRate(new TrackingTask(), 2000, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
// Support for Walking monsters aggro
|
||||
public void stopTrackingTask()
|
||||
{
|
||||
if (_trackingTask != null)
|
||||
{
|
||||
_trackingTask.cancel(true);
|
||||
_trackingTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Support for Walking monsters aggro
|
||||
protected class TrackingTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (getActiveChar() instanceof L2Attackable)
|
||||
{
|
||||
final L2Attackable monster = (L2Attackable) getActiveChar();
|
||||
if (monster.getAI().getIntention() == CtrlIntention.AI_INTENTION_MOVE_TO)
|
||||
{
|
||||
final Collection<L2PcInstance> players = getKnownPlayers().values();
|
||||
if (players != null)
|
||||
{
|
||||
for (L2PcInstance pl : players)
|
||||
{
|
||||
if (!pl.isDead() && !pl.isInvul() && pl.isInsideRadius(monster, monster.getAggroRange(), true, false) && (monster.isMonster() || (monster.isInstanceTypes(InstanceType.L2GuardInstance) && (pl.getKarma() > 0))))
|
||||
{
|
||||
// Send aggroRangeEnter
|
||||
if (monster.getHating(pl) == 0)
|
||||
{
|
||||
monster.addDamageHate(pl, 0, 0);
|
||||
}
|
||||
|
||||
// Skip attack for other targets, if one is already chosen for attack
|
||||
if ((monster.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) && !monster.isCoreAIDisabled())
|
||||
{
|
||||
WalkingManager.getInstance().stopMoving(getActiveChar(), false, true);
|
||||
monster.addDamageHate(pl, 0, 100);
|
||||
monster.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, pl, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
|
||||
public class NullKnownList extends ObjectKnownList
|
||||
{
|
||||
public NullKnownList(L2Object activeObject)
|
||||
{
|
||||
super(activeObject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addKnownObject(L2Object object)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Object getActiveObject()
|
||||
{
|
||||
return super.getActiveObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToForgetObject(L2Object object)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToWatchObject(L2Object object)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllKnownObjects()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeKnownObject(L2Object object, boolean forget)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.L2WorldRegion;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
public class ObjectKnownList
|
||||
{
|
||||
private final L2Object _activeObject;
|
||||
private Map<Integer, L2Object> _knownObjects;
|
||||
|
||||
public ObjectKnownList(L2Object activeObject)
|
||||
{
|
||||
_activeObject = activeObject;
|
||||
}
|
||||
|
||||
public boolean addKnownObject(L2Object object)
|
||||
{
|
||||
if (object == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Instance -1 is for GMs that can see everything on all instances
|
||||
if ((getActiveObject().getInstanceId() != -1) && (object.getInstanceId() != getActiveObject().getInstanceId()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the object is an L2PcInstance in ghost mode
|
||||
if (object.isPlayer() && object.getActingPlayer().getAppearance().isGhost())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if already know object
|
||||
if (knowsObject(object))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if object is not inside distance to watch object
|
||||
if (!Util.checkIfInShortRadius(getDistanceToWatchObject(object), getActiveObject(), object, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (getKnownObjects().put(object.getObjectId(), object) == null);
|
||||
}
|
||||
|
||||
public final boolean knowsObject(L2Object object)
|
||||
{
|
||||
if (object == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (getActiveObject() == object) || getKnownObjects().containsKey(object.getObjectId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all L2Object from _knownObjects
|
||||
*/
|
||||
public void removeAllKnownObjects()
|
||||
{
|
||||
getKnownObjects().clear();
|
||||
}
|
||||
|
||||
public final boolean removeKnownObject(L2Object object)
|
||||
{
|
||||
return removeKnownObject(object, false);
|
||||
}
|
||||
|
||||
protected boolean removeKnownObject(L2Object object, boolean forget)
|
||||
{
|
||||
if (object == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (forget)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return getKnownObjects().remove(object.getObjectId()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used only in Config.MOVE_BASED_KNOWNLIST and does not support guards seeing moving monsters
|
||||
*/
|
||||
public final void findObjects()
|
||||
{
|
||||
final L2WorldRegion region = getActiveObject().getWorldRegion();
|
||||
if (region == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (getActiveObject().isPlayable())
|
||||
{
|
||||
for (L2WorldRegion regi : region.getSurroundingRegions()) // offer members of this and surrounding regions
|
||||
{
|
||||
Collection<L2Object> vObj = regi.getVisibleObjects().values();
|
||||
for (L2Object object : vObj)
|
||||
{
|
||||
if (object != getActiveObject())
|
||||
{
|
||||
addKnownObject(object);
|
||||
if (object instanceof L2Character)
|
||||
{
|
||||
object.getKnownList().addKnownObject(getActiveObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (getActiveObject() instanceof L2Character)
|
||||
{
|
||||
for (L2WorldRegion regi : region.getSurroundingRegions()) // offer members of this and surrounding regions
|
||||
{
|
||||
if (regi.isActive())
|
||||
{
|
||||
Collection<L2Playable> vPls = regi.getVisiblePlayable().values();
|
||||
for (L2Object object : vPls)
|
||||
{
|
||||
if (object != getActiveObject())
|
||||
{
|
||||
addKnownObject(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove invisible and too far L2Object from _knowObject and if necessary from _knownPlayers of the L2Character
|
||||
* @param fullCheck
|
||||
*/
|
||||
public void forgetObjects(boolean fullCheck)
|
||||
{
|
||||
// Go through knownObjects
|
||||
final Collection<L2Object> objs = getKnownObjects().values();
|
||||
final Iterator<L2Object> oIter = objs.iterator();
|
||||
L2Object object;
|
||||
while (oIter.hasNext())
|
||||
{
|
||||
object = oIter.next();
|
||||
if (object == null)
|
||||
{
|
||||
oIter.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!fullCheck && !object.isPlayable())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove all objects invisible or too far
|
||||
if (!object.isVisible() || !Util.checkIfInShortRadius(getDistanceToForgetObject(object), getActiveObject(), object, true))
|
||||
{
|
||||
oIter.remove();
|
||||
removeKnownObject(object, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public L2Object getActiveObject()
|
||||
{
|
||||
return _activeObject;
|
||||
}
|
||||
|
||||
public int getDistanceToForgetObject(L2Object object)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getDistanceToWatchObject(L2Object object)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the _knownObjects containing all L2Object known by the L2Character.
|
||||
*/
|
||||
public final Map<Integer, L2Object> getKnownObjects()
|
||||
{
|
||||
if (_knownObjects == null)
|
||||
{
|
||||
_knownObjects = new ConcurrentHashMap<>();
|
||||
}
|
||||
return _knownObjects;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2AirShipInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.serverpackets.DeleteObject;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SpawnItem;
|
||||
|
||||
public class PcKnownList extends PlayableKnownList
|
||||
{
|
||||
public PcKnownList(L2PcInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a visible L2Object to L2PcInstance _knownObjects and _knownPlayer (if necessary) and send Server-Client Packets needed to inform the L2PcInstance of its state and actions in progress.<BR>
|
||||
* <BR>
|
||||
* <B><U> object is a L2ItemInstance </U> :</B><BR>
|
||||
* <BR>
|
||||
* <li>Send Server-Client Packet DropItem/SpawnItem to the L2PcInstance</li><BR>
|
||||
* <BR>
|
||||
* <B><U> object is a L2DoorInstance </U> :</B><BR>
|
||||
* <BR>
|
||||
* <li>Send Server-Client Packets DoorInfo and DoorStatusUpdate to the L2PcInstance</li> <li>Send Server->Client packet MoveToPawn/CharMoveToLocation and AutoAttackStart to the L2PcInstance</li><BR>
|
||||
* <BR>
|
||||
* <B><U> object is a L2NpcInstance </U> :</B><BR>
|
||||
* <BR>
|
||||
* <li>Send Server-Client Packet NpcInfo to the L2PcInstance</li> <li>Send Server->Client packet MoveToPawn/CharMoveToLocation and AutoAttackStart to the L2PcInstance</li><BR>
|
||||
* <BR>
|
||||
* <B><U> object is a L2Summon </U> :</B><BR>
|
||||
* <BR>
|
||||
* <li>Send Server-Client Packet NpcInfo/PetItemList (if the L2PcInstance is the owner) to the L2PcInstance</li> <li>Send Server->Client packet MoveToPawn/CharMoveToLocation and AutoAttackStart to the L2PcInstance</li><BR>
|
||||
* <BR>
|
||||
* <B><U> object is a L2PcInstance </U> :</B><BR>
|
||||
* <BR>
|
||||
* <li>Send Server-Client Packet CharInfo to the L2PcInstance</li> <li>If the object has a private store, Send Server-Client Packet PrivateStoreMsgSell to the L2PcInstance</li> <li>Send Server->Client packet MoveToPawn/CharMoveToLocation and AutoAttackStart to the L2PcInstance</li><BR>
|
||||
* <BR>
|
||||
* @param object The L2Object to add to _knownObjects and _knownPlayer
|
||||
*/
|
||||
@Override
|
||||
public boolean addKnownObject(L2Object object)
|
||||
{
|
||||
if (!super.addKnownObject(object))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (object.getPoly().isMorphed() && object.getPoly().getPolyType().equals("item"))
|
||||
{
|
||||
// if (object.getPolytype().equals("item"))
|
||||
getActiveChar().sendPacket(new SpawnItem(object));
|
||||
// else if (object.getPolytype().equals("npc"))
|
||||
// sendPacket(new NpcInfoPoly(object, this));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (object.isVisibleFor(getActiveChar()))
|
||||
{
|
||||
object.sendInfo(getActiveChar());
|
||||
|
||||
if (object instanceof L2Character)
|
||||
{
|
||||
// Update the state of the L2Character object client side by sending Server->Client packet MoveToPawn/CharMoveToLocation and AutoAttackStart to the L2PcInstance
|
||||
final L2Character obj = (L2Character) object;
|
||||
if (obj.hasAI())
|
||||
{
|
||||
obj.getAI().describeStateToPlayer(getActiveChar());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a L2Object from L2PcInstance _knownObjects and _knownPlayer (if necessary) and send Server-Client Packet DeleteObject to the L2PcInstance.<BR>
|
||||
* <BR>
|
||||
* @param object The L2Object to remove from _knownObjects and _knownPlayer
|
||||
*/
|
||||
@Override
|
||||
protected boolean removeKnownObject(L2Object object, boolean forget)
|
||||
{
|
||||
if (!super.removeKnownObject(object, forget))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (object instanceof L2AirShipInstance)
|
||||
{
|
||||
if ((((L2AirShipInstance) object).getCaptainId() != 0) && (((L2AirShipInstance) object).getCaptainId() != getActiveChar().getObjectId()))
|
||||
{
|
||||
getActiveChar().sendPacket(new DeleteObject(((L2AirShipInstance) object).getCaptainId()));
|
||||
}
|
||||
if (((L2AirShipInstance) object).getHelmObjectId() != 0)
|
||||
{
|
||||
getActiveChar().sendPacket(new DeleteObject(((L2AirShipInstance) object).getHelmObjectId()));
|
||||
}
|
||||
}
|
||||
|
||||
// Send Server-Client Packet DeleteObject to the L2PcInstance
|
||||
getActiveChar().sendPacket(new DeleteObject(object));
|
||||
|
||||
if (Config.CHECK_KNOWN && (object instanceof L2Npc) && getActiveChar().isGM())
|
||||
{
|
||||
getActiveChar().sendMessage("Removed NPC: " + object.getName());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final L2PcInstance getActiveChar()
|
||||
{
|
||||
return (L2PcInstance) super.getActiveChar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToForgetObject(L2Object object)
|
||||
{
|
||||
if (object.isVehicle())
|
||||
{
|
||||
return 10000;
|
||||
}
|
||||
|
||||
// when knownlist grows, the distance to forget should be at least
|
||||
// the same as the previous watch range, or it becomes possible that
|
||||
// extra charinfo packets are being sent (watch-forget-watch-forget)
|
||||
final int knownlistSize = getKnownObjects().size();
|
||||
if (knownlistSize <= 25)
|
||||
{
|
||||
return 4000;
|
||||
}
|
||||
if (knownlistSize <= 35)
|
||||
{
|
||||
return 3500;
|
||||
}
|
||||
if (knownlistSize <= 70)
|
||||
{
|
||||
return 2910;
|
||||
}
|
||||
return 2310;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToWatchObject(L2Object object)
|
||||
{
|
||||
if (object.isVehicle())
|
||||
{
|
||||
return 9000;
|
||||
}
|
||||
|
||||
final int knownlistSize = getKnownObjects().size();
|
||||
if (knownlistSize <= 25)
|
||||
{
|
||||
return 3400; // empty field
|
||||
}
|
||||
if (knownlistSize <= 35)
|
||||
{
|
||||
return 2900;
|
||||
}
|
||||
if (knownlistSize <= 70)
|
||||
{
|
||||
return 2300;
|
||||
}
|
||||
return 1700; // Siege, TOI, city
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
|
||||
public class PlayableKnownList extends CharKnownList
|
||||
{
|
||||
public PlayableKnownList(L2Playable activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Playable getActiveChar()
|
||||
{
|
||||
return (L2Playable) super.getActiveChar();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jserver.gameserver.MonsterRace;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2RaceManagerInstance;
|
||||
import com.l2jserver.gameserver.network.serverpackets.DeleteObject;
|
||||
|
||||
public class RaceManagerKnownList extends NpcKnownList
|
||||
{
|
||||
public RaceManagerKnownList(L2RaceManagerInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean removeKnownObject(L2Object object, boolean forget)
|
||||
{
|
||||
if (!super.removeKnownObject(object, forget))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (object.isPlayer())
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
object.sendPacket(new DeleteObject(MonsterRace.getInstance().getMonsters()[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2RaceManagerInstance getActiveChar()
|
||||
{
|
||||
return (L2RaceManagerInstance) super.getActiveChar();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2DefenderInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2StaticObjectInstance;
|
||||
|
||||
public class StaticObjectKnownList extends CharKnownList
|
||||
{
|
||||
public StaticObjectKnownList(L2StaticObjectInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final L2StaticObjectInstance getActiveChar()
|
||||
{
|
||||
return (L2StaticObjectInstance) super.getActiveChar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToForgetObject(L2Object object)
|
||||
{
|
||||
if (object instanceof L2DefenderInstance)
|
||||
{
|
||||
return 800;
|
||||
}
|
||||
if (!object.isPlayer())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 4000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToWatchObject(L2Object object)
|
||||
{
|
||||
if (object instanceof L2DefenderInstance)
|
||||
{
|
||||
return 600;
|
||||
}
|
||||
if (!object.isPlayer())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 2000;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
|
||||
public class SummonKnownList extends PlayableKnownList
|
||||
{
|
||||
public SummonKnownList(L2Summon activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final L2Summon getActiveChar()
|
||||
{
|
||||
return (L2Summon) super.getActiveChar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToForgetObject(L2Object object)
|
||||
{
|
||||
if ((object == getActiveChar().getOwner()) || (object == getActiveChar().getTarget()))
|
||||
{
|
||||
return 6000;
|
||||
}
|
||||
return 3000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToWatchObject(L2Object object)
|
||||
{
|
||||
return 1500;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2TrapInstance;
|
||||
|
||||
public class TrapKnownList extends NpcKnownList
|
||||
{
|
||||
public TrapKnownList(L2TrapInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final L2TrapInstance getActiveChar()
|
||||
{
|
||||
return (L2TrapInstance) super.getActiveChar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToForgetObject(L2Object object)
|
||||
{
|
||||
if ((object == getActiveChar().getActingPlayer()) || (object == getActiveChar().getTarget()))
|
||||
{
|
||||
return 6000;
|
||||
}
|
||||
|
||||
return 3000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToWatchObject(L2Object object)
|
||||
{
|
||||
return 1500;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
|
||||
public class VehicleKnownList extends CharKnownList
|
||||
{
|
||||
public VehicleKnownList(L2Character activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToForgetObject(L2Object object)
|
||||
{
|
||||
if (!object.isPlayer())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return object.getKnownList().getDistanceToForgetObject(getActiveObject());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToWatchObject(L2Object object)
|
||||
{
|
||||
if (!object.isPlayer())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return object.getKnownList().getDistanceToWatchObject(getActiveObject());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.poly;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
|
||||
public class ObjectPoly
|
||||
{
|
||||
private final L2Object _activeObject;
|
||||
private int _polyId;
|
||||
private String _polyType;
|
||||
|
||||
public ObjectPoly(L2Object activeObject)
|
||||
{
|
||||
_activeObject = activeObject;
|
||||
}
|
||||
|
||||
public void setPolyInfo(String polyType, String polyId)
|
||||
{
|
||||
setPolyId(Integer.parseInt(polyId));
|
||||
setPolyType(polyType);
|
||||
}
|
||||
|
||||
public final L2Object getActiveObject()
|
||||
{
|
||||
return _activeObject;
|
||||
}
|
||||
|
||||
public final boolean isMorphed()
|
||||
{
|
||||
return getPolyType() != null;
|
||||
}
|
||||
|
||||
public final int getPolyId()
|
||||
{
|
||||
return _polyId;
|
||||
}
|
||||
|
||||
public final void setPolyId(int value)
|
||||
{
|
||||
_polyId = value;
|
||||
}
|
||||
|
||||
public final String getPolyType()
|
||||
{
|
||||
return _polyType;
|
||||
}
|
||||
|
||||
public final void setPolyType(String value)
|
||||
{
|
||||
_polyType = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,853 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.stat;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.model.Elementals;
|
||||
import com.l2jserver.gameserver.model.PcCondOverride;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.items.L2Weapon;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.stats.Calculator;
|
||||
import com.l2jserver.gameserver.model.stats.MoveType;
|
||||
import com.l2jserver.gameserver.model.stats.Stats;
|
||||
import com.l2jserver.gameserver.model.stats.TraitType;
|
||||
import com.l2jserver.gameserver.model.zone.ZoneId;
|
||||
|
||||
public class CharStat
|
||||
{
|
||||
private final L2Character _activeChar;
|
||||
private long _exp = 0;
|
||||
private long _sp = 0;
|
||||
private byte _level = 1;
|
||||
private final float[] _attackTraits = new float[TraitType.values().length];
|
||||
private final int[] _attackTraitsCount = new int[TraitType.values().length];
|
||||
private final float[] _defenceTraits = new float[TraitType.values().length];
|
||||
private final int[] _defenceTraitsCount = new int[TraitType.values().length];
|
||||
private final int[] _traitsInvul = new int[TraitType.values().length];
|
||||
/** Creature's maximum buff count. */
|
||||
private int _maxBuffCount = Config.BUFFS_MAX_AMOUNT;
|
||||
|
||||
public CharStat(L2Character activeChar)
|
||||
{
|
||||
_activeChar = activeChar;
|
||||
Arrays.fill(_attackTraits, 1.0f);
|
||||
Arrays.fill(_defenceTraits, 1.0f);
|
||||
}
|
||||
|
||||
public final double calcStat(Stats stat, double init)
|
||||
{
|
||||
return calcStat(stat, init, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the new value of the state with modifiers that will be applied on the targeted L2Character.<BR>
|
||||
* <B><U> Concept</U> :</B><BR
|
||||
* A L2Character owns a table of Calculators called <B>_calculators</B>. Each Calculator (a calculator per state) own a table of Func object. A Func object is a mathematic function that permit to calculate the modifier of a state (ex : REGENERATE_HP_RATE...) : <BR>
|
||||
* FuncAtkAccuracy -> Math.sqrt(_player.getDEX())*6+_player.getLevel()<BR>
|
||||
* When the calc method of a calculator is launched, each mathematical function is called according to its priority <B>_order</B>.<br>
|
||||
* Indeed, Func with lowest priority order is executed firsta and Funcs with the same order are executed in unspecified order.<br>
|
||||
* The result of the calculation is stored in the value property of an Env class instance.<br>
|
||||
* @param stat The stat to calculate the new value with modifiers
|
||||
* @param initVal The initial value of the stat before applying modifiers
|
||||
* @param target The L2Charcater whose properties will be used in the calculation (ex : CON, INT...)
|
||||
* @param skill The L2Skill whose properties will be used in the calculation (ex : Level...)
|
||||
* @return
|
||||
*/
|
||||
public final double calcStat(Stats stat, double initVal, L2Character target, Skill skill)
|
||||
{
|
||||
double value = initVal;
|
||||
if (stat == null)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
final int id = stat.ordinal();
|
||||
final Calculator c = _activeChar.getCalculators()[id];
|
||||
|
||||
// If no Func object found, no modifier is applied
|
||||
if ((c == null) || (c.size() == 0))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
// Apply transformation stats.
|
||||
if (getActiveChar().isPlayer() && getActiveChar().isTransformed())
|
||||
{
|
||||
double val = getActiveChar().getTransformation().getStat(getActiveChar().getActingPlayer(), stat);
|
||||
if (val > 0)
|
||||
{
|
||||
value = val;
|
||||
}
|
||||
}
|
||||
|
||||
// Launch the calculation
|
||||
value = c.calc(_activeChar, target, skill, value);
|
||||
|
||||
// avoid some troubles with negative stats (some stats should never be negative)
|
||||
if (value <= 0)
|
||||
{
|
||||
switch (stat)
|
||||
{
|
||||
case MAX_HP:
|
||||
case MAX_MP:
|
||||
case MAX_CP:
|
||||
case MAGIC_DEFENCE:
|
||||
case POWER_DEFENCE:
|
||||
case POWER_ATTACK:
|
||||
case MAGIC_ATTACK:
|
||||
case POWER_ATTACK_SPEED:
|
||||
case MAGIC_ATTACK_SPEED:
|
||||
case SHIELD_DEFENCE:
|
||||
case STAT_CON:
|
||||
case STAT_DEX:
|
||||
case STAT_INT:
|
||||
case STAT_MEN:
|
||||
case STAT_STR:
|
||||
case STAT_WIT:
|
||||
case STAT_LUC:
|
||||
case STAT_CHA:
|
||||
{
|
||||
value = 1.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Accuracy (base+modifier) of the L2Character in function of the Weapon Expertise Penalty.
|
||||
*/
|
||||
public int getAccuracy()
|
||||
{
|
||||
return (int) Math.round(calcStat(Stats.ACCURACY_COMBAT, 0, null, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Magic Accuracy (base+modifier) of the L2Character
|
||||
*/
|
||||
public int getMagicAccuracy()
|
||||
{
|
||||
return (int) Math.round(calcStat(Stats.ACCURACY_MAGIC, 0, null, null));
|
||||
}
|
||||
|
||||
public L2Character getActiveChar()
|
||||
{
|
||||
return _activeChar;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Attack Speed multiplier (base+modifier) of the L2Character to get proper animations.
|
||||
*/
|
||||
public final float getAttackSpeedMultiplier()
|
||||
{
|
||||
return (float) (((1.1) * getPAtkSpd()) / _activeChar.getTemplate().getBasePAtkSpd());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the CON of the L2Character (base+modifier).
|
||||
*/
|
||||
public final int getCON()
|
||||
{
|
||||
return (int) calcStat(Stats.STAT_CON, _activeChar.getTemplate().getBaseCON());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target
|
||||
* @param init
|
||||
* @return the Critical Damage rate (base+modifier) of the L2Character.
|
||||
*/
|
||||
public final double getCriticalDmg(L2Character target, double init)
|
||||
{
|
||||
return calcStat(Stats.CRITICAL_DAMAGE, init, target, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target
|
||||
* @param skill
|
||||
* @return the Critical Hit rate (base+modifier) of the L2Character.
|
||||
*/
|
||||
public int getCriticalHit(L2Character target, Skill skill)
|
||||
{
|
||||
int val = (int) calcStat(Stats.CRITICAL_RATE, _activeChar.getTemplate().getBaseCritRate(), target, skill);
|
||||
|
||||
if (!_activeChar.canOverrideCond(PcCondOverride.MAX_STATS_VALUE))
|
||||
{
|
||||
val = Math.min(val, Config.MAX_PCRIT_RATE);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the DEX of the L2Character (base+modifier).
|
||||
*/
|
||||
public final int getDEX()
|
||||
{
|
||||
return (int) calcStat(Stats.STAT_DEX, _activeChar.getTemplate().getBaseDEX());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target
|
||||
* @return the Attack Evasion rate (base+modifier) of the L2Character.
|
||||
*/
|
||||
public int getEvasionRate(L2Character target)
|
||||
{
|
||||
int val = (int) Math.round(calcStat(Stats.EVASION_RATE, 0, target, null));
|
||||
|
||||
if (!_activeChar.canOverrideCond(PcCondOverride.MAX_STATS_VALUE))
|
||||
{
|
||||
val = Math.min(val, Config.MAX_EVASION);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target
|
||||
* @return the Attack Evasion rate (base+modifier) of the L2Character.
|
||||
*/
|
||||
public int getMagicEvasionRate(L2Character target)
|
||||
{
|
||||
int val = (int) Math.round(calcStat(Stats.MAGIC_EVASION_RATE, 0, target, null));
|
||||
|
||||
if (!_activeChar.canOverrideCond(PcCondOverride.MAX_STATS_VALUE))
|
||||
{
|
||||
val = Math.min(val, Config.MAX_EVASION);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
public long getExp()
|
||||
{
|
||||
return _exp;
|
||||
}
|
||||
|
||||
public void setExp(long value)
|
||||
{
|
||||
_exp = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the INT of the L2Character (base+modifier).
|
||||
*/
|
||||
public int getINT()
|
||||
{
|
||||
return (int) calcStat(Stats.STAT_INT, _activeChar.getTemplate().getBaseINT());
|
||||
}
|
||||
|
||||
public byte getLevel()
|
||||
{
|
||||
return _level;
|
||||
}
|
||||
|
||||
public void setLevel(byte value)
|
||||
{
|
||||
_level = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param skill
|
||||
* @return the Magical Attack range (base+modifier) of the L2Character.
|
||||
*/
|
||||
public final int getMagicalAttackRange(Skill skill)
|
||||
{
|
||||
if (skill != null)
|
||||
{
|
||||
return (int) calcStat(Stats.MAGIC_ATTACK_RANGE, skill.getCastRange(), null, skill);
|
||||
}
|
||||
|
||||
return _activeChar.getTemplate().getBaseAttackRange();
|
||||
}
|
||||
|
||||
public int getMaxCp()
|
||||
{
|
||||
return (int) calcStat(Stats.MAX_CP, _activeChar.getTemplate().getBaseCpMax());
|
||||
}
|
||||
|
||||
public int getMaxRecoverableCp()
|
||||
{
|
||||
return (int) calcStat(Stats.MAX_RECOVERABLE_CP, getMaxCp());
|
||||
}
|
||||
|
||||
public int getMaxHp()
|
||||
{
|
||||
return (int) calcStat(Stats.MAX_HP, _activeChar.getTemplate().getBaseHpMax());
|
||||
}
|
||||
|
||||
public int getMaxRecoverableHp()
|
||||
{
|
||||
return (int) calcStat(Stats.MAX_RECOVERABLE_HP, getMaxHp());
|
||||
}
|
||||
|
||||
public int getMaxMp()
|
||||
{
|
||||
return (int) calcStat(Stats.MAX_MP, _activeChar.getTemplate().getBaseMpMax());
|
||||
}
|
||||
|
||||
public int getMaxRecoverableMp()
|
||||
{
|
||||
return (int) calcStat(Stats.MAX_RECOVERABLE_MP, getMaxMp());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the MAtk (base+modifier) of the L2Character.<br>
|
||||
* <B><U>Example of use</U>: Calculate Magic damage
|
||||
* @param target The L2Character targeted by the skill
|
||||
* @param skill The L2Skill used against the target
|
||||
* @return
|
||||
*/
|
||||
public int getMAtk(L2Character target, Skill skill)
|
||||
{
|
||||
float bonusAtk = 1;
|
||||
if (Config.L2JMOD_CHAMPION_ENABLE && _activeChar.isChampion())
|
||||
{
|
||||
bonusAtk = Config.L2JMOD_CHAMPION_ATK;
|
||||
}
|
||||
if (_activeChar.isRaid())
|
||||
{
|
||||
bonusAtk *= Config.RAID_MATTACK_MULTIPLIER;
|
||||
}
|
||||
|
||||
// Calculate modifiers Magic Attack
|
||||
return (int) calcStat(Stats.MAGIC_ATTACK, _activeChar.getTemplate().getBaseMAtk() * bonusAtk, target, skill);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the MAtk Speed (base+modifier) of the L2Character in function of the Armour Expertise Penalty.
|
||||
*/
|
||||
public int getMAtkSpd()
|
||||
{
|
||||
float bonusSpdAtk = 1;
|
||||
if (Config.L2JMOD_CHAMPION_ENABLE && _activeChar.isChampion())
|
||||
{
|
||||
bonusSpdAtk = Config.L2JMOD_CHAMPION_SPD_ATK;
|
||||
}
|
||||
|
||||
double val = calcStat(Stats.MAGIC_ATTACK_SPEED, _activeChar.getTemplate().getBaseMAtkSpd() * bonusSpdAtk);
|
||||
|
||||
if (!_activeChar.canOverrideCond(PcCondOverride.MAX_STATS_VALUE))
|
||||
{
|
||||
val = Math.min(val, Config.MAX_MATK_SPEED);
|
||||
}
|
||||
|
||||
return (int) val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target
|
||||
* @param skill
|
||||
* @return the Magic Critical Hit rate (base+modifier) of the L2Character.
|
||||
*/
|
||||
public final int getMCriticalHit(L2Character target, Skill skill)
|
||||
{
|
||||
int val = (int) calcStat(Stats.MCRITICAL_RATE, getActiveChar().getTemplate().getBaseMCritRate(), target, skill);
|
||||
|
||||
if (!_activeChar.canOverrideCond(PcCondOverride.MAX_STATS_VALUE))
|
||||
{
|
||||
val = Math.min(val, Config.MAX_MCRIT_RATE);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* <B><U>Example of use </U>: Calculate Magic damage.
|
||||
* @param target The L2Character targeted by the skill
|
||||
* @param skill The L2Skill used against the target
|
||||
* @return the MDef (base+modifier) of the L2Character against a skill in function of abnormal effects in progress.
|
||||
*/
|
||||
public int getMDef(L2Character target, Skill skill)
|
||||
{
|
||||
// Get the base MDef of the L2Character
|
||||
double defence = _activeChar.getTemplate().getBaseMDef();
|
||||
|
||||
// Calculate modifier for Raid Bosses
|
||||
if (_activeChar.isRaid())
|
||||
{
|
||||
defence *= Config.RAID_MDEFENCE_MULTIPLIER;
|
||||
}
|
||||
|
||||
// Calculate modifiers Magic Attack
|
||||
return (int) calcStat(Stats.MAGIC_DEFENCE, defence, target, skill);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the MEN of the L2Character (base+modifier).
|
||||
*/
|
||||
public final int getMEN()
|
||||
{
|
||||
return (int) calcStat(Stats.STAT_MEN, _activeChar.getTemplate().getBaseMEN());
|
||||
}
|
||||
|
||||
public final int getLUC()
|
||||
{
|
||||
return (int) calcStat(Stats.STAT_LUC, _activeChar.getTemplate().getBaseLUC());
|
||||
}
|
||||
|
||||
public final int getCHA()
|
||||
{
|
||||
return (int) calcStat(Stats.STAT_CHA, _activeChar.getTemplate().getBaseCHA());
|
||||
}
|
||||
|
||||
public double getMovementSpeedMultiplier()
|
||||
{
|
||||
double baseSpeed;
|
||||
if (_activeChar.isInsideZone(ZoneId.WATER))
|
||||
{
|
||||
baseSpeed = getBaseMoveSpeed(_activeChar.isRunning() ? MoveType.FAST_SWIM : MoveType.SLOW_SWIM);
|
||||
}
|
||||
else
|
||||
{
|
||||
baseSpeed = getBaseMoveSpeed(_activeChar.isRunning() ? MoveType.RUN : MoveType.WALK);
|
||||
}
|
||||
return getMoveSpeed() * (1. / baseSpeed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the RunSpeed (base+modifier) of the L2Character in function of the Armour Expertise Penalty.
|
||||
*/
|
||||
public double getRunSpeed()
|
||||
{
|
||||
final double baseRunSpd = _activeChar.isInsideZone(ZoneId.WATER) ? getSwimRunSpeed() : getBaseMoveSpeed(MoveType.RUN);
|
||||
if (baseRunSpd <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return calcStat(Stats.MOVE_SPEED, baseRunSpd, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the WalkSpeed (base+modifier) of the L2Character.
|
||||
*/
|
||||
public double getWalkSpeed()
|
||||
{
|
||||
final double baseWalkSpd = _activeChar.isInsideZone(ZoneId.WATER) ? getSwimWalkSpeed() : getBaseMoveSpeed(MoveType.WALK);
|
||||
if (baseWalkSpd <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return calcStat(Stats.MOVE_SPEED, baseWalkSpd);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the SwimRunSpeed (base+modifier) of the L2Character.
|
||||
*/
|
||||
public double getSwimRunSpeed()
|
||||
{
|
||||
final double baseRunSpd = getBaseMoveSpeed(MoveType.FAST_SWIM);
|
||||
if (baseRunSpd <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return calcStat(Stats.MOVE_SPEED, baseRunSpd, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the SwimWalkSpeed (base+modifier) of the L2Character.
|
||||
*/
|
||||
public double getSwimWalkSpeed()
|
||||
{
|
||||
final double baseWalkSpd = getBaseMoveSpeed(MoveType.SLOW_SWIM);
|
||||
if (baseWalkSpd <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return calcStat(Stats.MOVE_SPEED, baseWalkSpd);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type movement type
|
||||
* @return the base move speed of given movement type.
|
||||
*/
|
||||
public double getBaseMoveSpeed(MoveType type)
|
||||
{
|
||||
return _activeChar.getTemplate().getBaseMoveSpeed(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the RunSpeed (base+modifier) or WalkSpeed (base+modifier) of the L2Character in function of the movement type.
|
||||
*/
|
||||
public double getMoveSpeed()
|
||||
{
|
||||
if (_activeChar.isInsideZone(ZoneId.WATER))
|
||||
{
|
||||
return _activeChar.isRunning() ? getSwimRunSpeed() : getSwimWalkSpeed();
|
||||
}
|
||||
return _activeChar.isRunning() ? getRunSpeed() : getWalkSpeed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param skill
|
||||
* @return the MReuse rate (base+modifier) of the L2Character.
|
||||
*/
|
||||
public final double getMReuseRate(Skill skill)
|
||||
{
|
||||
return calcStat(Stats.MAGIC_REUSE_RATE, 1, null, skill);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target
|
||||
* @return the PAtk (base+modifier) of the L2Character.
|
||||
*/
|
||||
public int getPAtk(L2Character target)
|
||||
{
|
||||
float bonusAtk = 1;
|
||||
if (Config.L2JMOD_CHAMPION_ENABLE && _activeChar.isChampion())
|
||||
{
|
||||
bonusAtk = Config.L2JMOD_CHAMPION_ATK;
|
||||
}
|
||||
if (_activeChar.isRaid())
|
||||
{
|
||||
bonusAtk *= Config.RAID_PATTACK_MULTIPLIER;
|
||||
}
|
||||
return (int) calcStat(Stats.POWER_ATTACK, _activeChar.getTemplate().getBasePAtk() * bonusAtk, target, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the PAtk Speed (base+modifier) of the L2Character in function of the Armour Expertise Penalty.
|
||||
*/
|
||||
public int getPAtkSpd()
|
||||
{
|
||||
float bonusAtk = 1;
|
||||
if (Config.L2JMOD_CHAMPION_ENABLE && _activeChar.isChampion())
|
||||
{
|
||||
bonusAtk = Config.L2JMOD_CHAMPION_SPD_ATK;
|
||||
}
|
||||
int val = (int) Math.round(calcStat(Stats.POWER_ATTACK_SPEED, _activeChar.getTemplate().getBasePAtkSpd() * bonusAtk, null, null));
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target
|
||||
* @return the PDef (base+modifier) of the L2Character.
|
||||
*/
|
||||
public int getPDef(L2Character target)
|
||||
{
|
||||
return (int) calcStat(Stats.POWER_DEFENCE, (_activeChar.isRaid()) ? _activeChar.getTemplate().getBasePDef() * Config.RAID_PDEFENCE_MULTIPLIER : _activeChar.getTemplate().getBasePDef(), target, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Physical Attack range (base+modifier) of the L2Character.
|
||||
*/
|
||||
public final int getPhysicalAttackRange()
|
||||
{
|
||||
final L2Weapon weapon = _activeChar.getActiveWeaponItem();
|
||||
int baseAttackRange;
|
||||
if (_activeChar.isTransformed() && _activeChar.isPlayer())
|
||||
{
|
||||
baseAttackRange = _activeChar.getTransformation().getBaseAttackRange(_activeChar.getActingPlayer());
|
||||
}
|
||||
else if (weapon != null)
|
||||
{
|
||||
baseAttackRange = weapon.getBaseAttackRange();
|
||||
}
|
||||
else
|
||||
{
|
||||
baseAttackRange = _activeChar.getTemplate().getBaseAttackRange();
|
||||
}
|
||||
|
||||
return (int) calcStat(Stats.POWER_ATTACK_RANGE, baseAttackRange, null, null);
|
||||
}
|
||||
|
||||
public int getPhysicalAttackAngle()
|
||||
{
|
||||
final L2Weapon weapon = _activeChar.getActiveWeaponItem();
|
||||
final int baseAttackAngle;
|
||||
if (weapon != null)
|
||||
{
|
||||
baseAttackAngle = weapon.getBaseAttackAngle();
|
||||
}
|
||||
else
|
||||
{
|
||||
baseAttackAngle = 120;
|
||||
}
|
||||
return baseAttackAngle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target
|
||||
* @return the weapon reuse modifier.
|
||||
*/
|
||||
public final double getWeaponReuseModifier(L2Character target)
|
||||
{
|
||||
return calcStat(Stats.ATK_REUSE, 1, target, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ShieldDef rate (base+modifier) of the L2Character.
|
||||
*/
|
||||
public final int getShldDef()
|
||||
{
|
||||
return (int) calcStat(Stats.SHIELD_DEFENCE, 0);
|
||||
}
|
||||
|
||||
public long getSp()
|
||||
{
|
||||
return _sp;
|
||||
}
|
||||
|
||||
public void setSp(long value)
|
||||
{
|
||||
_sp = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the STR of the L2Character (base+modifier).
|
||||
*/
|
||||
public final int getSTR()
|
||||
{
|
||||
return (int) calcStat(Stats.STAT_STR, _activeChar.getTemplate().getBaseSTR());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the WIT of the L2Character (base+modifier).
|
||||
*/
|
||||
public final int getWIT()
|
||||
{
|
||||
return (int) calcStat(Stats.STAT_WIT, _activeChar.getTemplate().getBaseWIT());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param skill
|
||||
* @return the mpConsume.
|
||||
*/
|
||||
public final int getMpConsume(Skill skill)
|
||||
{
|
||||
if (skill == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
double mpConsume = skill.getMpConsume();
|
||||
double nextDanceMpCost = Math.ceil(skill.getMpConsume() / 2.);
|
||||
if (skill.isDance())
|
||||
{
|
||||
if (Config.DANCE_CONSUME_ADDITIONAL_MP && (_activeChar != null) && (_activeChar.getDanceCount() > 0))
|
||||
{
|
||||
mpConsume += _activeChar.getDanceCount() * nextDanceMpCost;
|
||||
}
|
||||
}
|
||||
|
||||
mpConsume = calcStat(Stats.MP_CONSUME, mpConsume, null, skill);
|
||||
|
||||
if (skill.isDance())
|
||||
{
|
||||
return (int) calcStat(Stats.DANCE_MP_CONSUME_RATE, mpConsume);
|
||||
}
|
||||
else if (skill.isMagic())
|
||||
{
|
||||
return (int) calcStat(Stats.MAGICAL_MP_CONSUME_RATE, mpConsume);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int) calcStat(Stats.PHYSICAL_MP_CONSUME_RATE, mpConsume);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param skill
|
||||
* @return the mpInitialConsume.
|
||||
*/
|
||||
public final int getMpInitialConsume(Skill skill)
|
||||
{
|
||||
if (skill == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
double mpConsume = calcStat(Stats.MP_CONSUME, skill.getMpInitialConsume(), null, skill);
|
||||
|
||||
if (skill.isDance())
|
||||
{
|
||||
return (int) calcStat(Stats.DANCE_MP_CONSUME_RATE, mpConsume);
|
||||
}
|
||||
else if (skill.isMagic())
|
||||
{
|
||||
return (int) calcStat(Stats.MAGICAL_MP_CONSUME_RATE, mpConsume);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int) calcStat(Stats.PHYSICAL_MP_CONSUME_RATE, mpConsume);
|
||||
}
|
||||
}
|
||||
|
||||
public byte getAttackElement()
|
||||
{
|
||||
L2ItemInstance weaponInstance = _activeChar.getActiveWeaponInstance();
|
||||
// 1st order - weapon element
|
||||
if ((weaponInstance != null) && (weaponInstance.getAttackElementType() >= 0))
|
||||
{
|
||||
return weaponInstance.getAttackElementType();
|
||||
}
|
||||
|
||||
// temp fix starts
|
||||
int tempVal = 0, stats[] =
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
byte returnVal = -2;
|
||||
stats[0] = (int) calcStat(Stats.FIRE_POWER, _activeChar.getTemplate().getBaseFire());
|
||||
stats[1] = (int) calcStat(Stats.WATER_POWER, _activeChar.getTemplate().getBaseWater());
|
||||
stats[2] = (int) calcStat(Stats.WIND_POWER, _activeChar.getTemplate().getBaseWind());
|
||||
stats[3] = (int) calcStat(Stats.EARTH_POWER, _activeChar.getTemplate().getBaseEarth());
|
||||
stats[4] = (int) calcStat(Stats.HOLY_POWER, _activeChar.getTemplate().getBaseHoly());
|
||||
stats[5] = (int) calcStat(Stats.DARK_POWER, _activeChar.getTemplate().getBaseDark());
|
||||
|
||||
for (byte x = 0; x < 6; x++)
|
||||
{
|
||||
if (stats[x] > tempVal)
|
||||
{
|
||||
returnVal = x;
|
||||
tempVal = stats[x];
|
||||
}
|
||||
}
|
||||
|
||||
return returnVal;
|
||||
// temp fix ends
|
||||
|
||||
/*
|
||||
* uncomment me once deadlocks in getAllEffects() fixed return _activeChar.getElementIdFromEffects();
|
||||
*/
|
||||
}
|
||||
|
||||
public int getAttackElementValue(byte attackAttribute)
|
||||
{
|
||||
switch (attackAttribute)
|
||||
{
|
||||
case Elementals.FIRE:
|
||||
return (int) calcStat(Stats.FIRE_POWER, _activeChar.getTemplate().getBaseFire());
|
||||
case Elementals.WATER:
|
||||
return (int) calcStat(Stats.WATER_POWER, _activeChar.getTemplate().getBaseWater());
|
||||
case Elementals.WIND:
|
||||
return (int) calcStat(Stats.WIND_POWER, _activeChar.getTemplate().getBaseWind());
|
||||
case Elementals.EARTH:
|
||||
return (int) calcStat(Stats.EARTH_POWER, _activeChar.getTemplate().getBaseEarth());
|
||||
case Elementals.HOLY:
|
||||
return (int) calcStat(Stats.HOLY_POWER, _activeChar.getTemplate().getBaseHoly());
|
||||
case Elementals.DARK:
|
||||
return (int) calcStat(Stats.DARK_POWER, _activeChar.getTemplate().getBaseDark());
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getDefenseElementValue(byte defenseAttribute)
|
||||
{
|
||||
switch (defenseAttribute)
|
||||
{
|
||||
case Elementals.FIRE:
|
||||
return (int) calcStat(Stats.FIRE_RES, _activeChar.getTemplate().getBaseFireRes());
|
||||
case Elementals.WATER:
|
||||
return (int) calcStat(Stats.WATER_RES, _activeChar.getTemplate().getBaseWaterRes());
|
||||
case Elementals.WIND:
|
||||
return (int) calcStat(Stats.WIND_RES, _activeChar.getTemplate().getBaseWindRes());
|
||||
case Elementals.EARTH:
|
||||
return (int) calcStat(Stats.EARTH_RES, _activeChar.getTemplate().getBaseEarthRes());
|
||||
case Elementals.HOLY:
|
||||
return (int) calcStat(Stats.HOLY_RES, _activeChar.getTemplate().getBaseHolyRes());
|
||||
case Elementals.DARK:
|
||||
return (int) calcStat(Stats.DARK_RES, _activeChar.getTemplate().getBaseDarkRes());
|
||||
default:
|
||||
return (int) _activeChar.getTemplate().getBaseElementRes();
|
||||
}
|
||||
}
|
||||
|
||||
public float getAttackTrait(TraitType traitType)
|
||||
{
|
||||
return _attackTraits[traitType.getId()];
|
||||
}
|
||||
|
||||
public float[] getAttackTraits()
|
||||
{
|
||||
return _attackTraits;
|
||||
}
|
||||
|
||||
public boolean hasAttackTrait(TraitType traitType)
|
||||
{
|
||||
return _attackTraitsCount[traitType.getId()] > 0;
|
||||
}
|
||||
|
||||
public int[] getAttackTraitsCount()
|
||||
{
|
||||
return _attackTraitsCount;
|
||||
}
|
||||
|
||||
public float getDefenceTrait(TraitType traitType)
|
||||
{
|
||||
return _defenceTraits[traitType.getId()];
|
||||
}
|
||||
|
||||
public float[] getDefenceTraits()
|
||||
{
|
||||
return _defenceTraits;
|
||||
}
|
||||
|
||||
public boolean hasDefenceTrait(TraitType traitType)
|
||||
{
|
||||
return _defenceTraitsCount[traitType.getId()] > 0;
|
||||
}
|
||||
|
||||
public int[] getDefenceTraitsCount()
|
||||
{
|
||||
return _defenceTraitsCount;
|
||||
}
|
||||
|
||||
public boolean isTraitInvul(TraitType traitType)
|
||||
{
|
||||
return _traitsInvul[traitType.getId()] > 0;
|
||||
}
|
||||
|
||||
public int[] getTraitsInvul()
|
||||
{
|
||||
return _traitsInvul;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum buff count.
|
||||
* @return the maximum buff count
|
||||
*/
|
||||
public int getMaxBuffCount()
|
||||
{
|
||||
return _maxBuffCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum buff count.
|
||||
* @param buffCount the buff count
|
||||
*/
|
||||
public void setMaxBuffCount(int buffCount)
|
||||
{
|
||||
_maxBuffCount = buffCount;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.stat;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2ControllableAirShipInstance;
|
||||
|
||||
public class ControllableAirShipStat extends VehicleStat
|
||||
{
|
||||
public ControllableAirShipStat(L2ControllableAirShipInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2ControllableAirShipInstance getActiveChar()
|
||||
{
|
||||
return (L2ControllableAirShipInstance) super.getActiveChar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMoveSpeed()
|
||||
{
|
||||
if (getActiveChar().isInDock() || (getActiveChar().getFuel() > 0))
|
||||
{
|
||||
return super.getMoveSpeed();
|
||||
}
|
||||
return super.getMoveSpeed() * 0.05f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.stat;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
|
||||
|
||||
/**
|
||||
* @author malyelfik
|
||||
*/
|
||||
public class DoorStat extends CharStat
|
||||
{
|
||||
private int _upgradeHpRatio = 1;
|
||||
|
||||
public DoorStat(L2DoorInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2DoorInstance getActiveChar()
|
||||
{
|
||||
return (L2DoorInstance) super.getActiveChar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxHp()
|
||||
{
|
||||
return super.getMaxHp() * _upgradeHpRatio;
|
||||
}
|
||||
|
||||
public void setUpgradeHpRatio(int ratio)
|
||||
{
|
||||
_upgradeHpRatio = ratio;
|
||||
}
|
||||
|
||||
public int getUpgradeHpRatio()
|
||||
{
|
||||
return _upgradeHpRatio;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.stat;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
public class NpcStat extends CharStat
|
||||
{
|
||||
public NpcStat(L2Npc activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getLevel()
|
||||
{
|
||||
return getActiveChar().getTemplate().getLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2Npc getActiveChar()
|
||||
{
|
||||
return (L2Npc) super.getActiveChar();
|
||||
}
|
||||
}
|
||||
916
trunk/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java
Normal file
916
trunk/java/com/l2jserver/gameserver/model/actor/stat/PcStat.java
Normal file
@@ -0,0 +1,916 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* L2J Server is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.l2jserver.gameserver.model.actor.stat;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.datatables.ExperienceTable;
|
||||
import com.l2jserver.gameserver.datatables.PetDataTable;
|
||||
import com.l2jserver.gameserver.enums.PartySmallWindowUpdateType;
|
||||
import com.l2jserver.gameserver.enums.UserInfoType;
|
||||
import com.l2jserver.gameserver.model.L2PetLevelData;
|
||||
import com.l2jserver.gameserver.model.PcCondOverride;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2ClassMasterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
|
||||
import com.l2jserver.gameserver.model.actor.transform.TransformTemplate;
|
||||
import com.l2jserver.gameserver.model.entity.RecoBonus;
|
||||
import com.l2jserver.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jserver.gameserver.model.events.impl.character.player.OnPlayerLevelChanged;
|
||||
import com.l2jserver.gameserver.model.stats.Formulas;
|
||||
import com.l2jserver.gameserver.model.stats.MoveType;
|
||||
import com.l2jserver.gameserver.model.stats.Stats;
|
||||
import com.l2jserver.gameserver.model.zone.ZoneId;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.AcquireSkillList;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExVitalityPointInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExVoteSystemInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PartySmallWindowUpdate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PledgeShowMemberListUpdate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jserver.gameserver.network.serverpackets.StatusUpdate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jserver.gameserver.network.serverpackets.UserInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.friend.L2FriendStatus;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
public class PcStat extends PlayableStat
|
||||
{
|
||||
private int _oldMaxHp; // stats watch
|
||||
private int _oldMaxMp; // stats watch
|
||||
private int _oldMaxCp; // stats watch
|
||||
private float _vitalityPoints = 1;
|
||||
private byte _vitalityLevel = 0;
|
||||
private long _startingXp;
|
||||
/** Player's maximum cubic count. */
|
||||
private int _maxCubicCount = 1;
|
||||
/** Player's maximum talisman count. */
|
||||
private final AtomicInteger _talismanSlots = new AtomicInteger();
|
||||
private boolean _cloakSlot = false;
|
||||
|
||||
public static final int VITALITY_LEVELS[] =
|
||||
{
|
||||
240,
|
||||
2000,
|
||||
13000,
|
||||
17000,
|
||||
20000
|
||||
};
|
||||
|
||||
public static final int MAX_VITALITY_POINTS = VITALITY_LEVELS[4];
|
||||
public static final int MIN_VITALITY_POINTS = 1;
|
||||
|
||||
public PcStat(L2PcInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addExp(long value)
|
||||
{
|
||||
L2PcInstance activeChar = getActiveChar();
|
||||
|
||||
// Allowed to gain exp?
|
||||
if (!getActiveChar().getAccessLevel().canGainExp())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!super.addExp(value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set new karma
|
||||
if (!activeChar.isCursedWeaponEquipped() && (activeChar.getKarma() > 0) && (activeChar.isGM() || !activeChar.isInsideZone(ZoneId.PVP)))
|
||||
{
|
||||
int karmaLost = Formulas.calculateKarmaLost(activeChar, value);
|
||||
if (karmaLost > 0)
|
||||
{
|
||||
activeChar.setKarma(activeChar.getKarma() - karmaLost);
|
||||
final SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.YOUR_REPUTATION_HAS_BEEN_CHANGED_TO_S1);
|
||||
msg.addInt(activeChar.getKarma());
|
||||
activeChar.sendPacket(msg);
|
||||
}
|
||||
}
|
||||
|
||||
// EXP status update currently not used in retail
|
||||
activeChar.sendPacket(new UserInfo(activeChar));
|
||||
activeChar.sendPacket(new ExBrExtraUserInfo(activeChar));
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean addExpAndSp(long addToExp, long addToSp, boolean useBonuses)
|
||||
{
|
||||
L2PcInstance activeChar = getActiveChar();
|
||||
|
||||
// Allowed to gain exp/sp?
|
||||
if (!activeChar.getAccessLevel().canGainExp())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
long baseExp = addToExp;
|
||||
long baseSp = addToSp;
|
||||
|
||||
double bonusExp = 1.;
|
||||
double bonusSp = 1.;
|
||||
|
||||
if (useBonuses)
|
||||
{
|
||||
bonusExp = getExpBonusMultiplier();
|
||||
bonusSp = getSpBonusMultiplier();
|
||||
}
|
||||
|
||||
addToExp *= bonusExp;
|
||||
addToSp *= bonusSp;
|
||||
|
||||
float ratioTakenByPlayer = 0;
|
||||
|
||||
// if this player has a pet and it is in his range he takes from the owner's Exp, give the pet Exp now
|
||||
if (activeChar.hasPet() && Util.checkIfInShortRadius(Config.ALT_PARTY_RANGE, activeChar, activeChar.getSummon(), false))
|
||||
{
|
||||
L2PetInstance pet = (L2PetInstance) activeChar.getSummon();
|
||||
ratioTakenByPlayer = pet.getPetLevelData().getOwnerExpTaken() / 100f;
|
||||
|
||||
// only give exp/sp to the pet by taking from the owner if the pet has a non-zero, positive ratio
|
||||
// allow possible customizations that would have the pet earning more than 100% of the owner's exp/sp
|
||||
if (ratioTakenByPlayer > 1)
|
||||
{
|
||||
ratioTakenByPlayer = 1;
|
||||
}
|
||||
|
||||
if (!pet.isDead())
|
||||
{
|
||||
pet.addExpAndSp((long) (addToExp * (1 - ratioTakenByPlayer)), (int) (addToSp * (1 - ratioTakenByPlayer)));
|
||||
}
|
||||
|
||||
// now adjust the max ratio to avoid the owner earning negative exp/sp
|
||||
addToExp = (long) (addToExp * ratioTakenByPlayer);
|
||||
addToSp = (int) (addToSp * ratioTakenByPlayer);
|
||||
}
|
||||
|
||||
if (!addExp(addToExp))
|
||||
{
|
||||
addToExp = 0;
|
||||
}
|
||||
|
||||
if (!addSp(addToSp))
|
||||
{
|
||||
addToSp = 0;
|
||||
}
|
||||
|
||||
if ((addToExp == 0) && (addToSp == 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SystemMessage sm = null;
|
||||
if ((addToExp == 0) && (addToSp != 0))
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_ACQUIRED_S1_SP);
|
||||
sm.addLong(addToSp);
|
||||
}
|
||||
else if ((addToSp == 0) && (addToExp != 0))
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S1_XP);
|
||||
sm.addLong(addToExp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((addToExp - baseExp) > 0)
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_ACQUIRED_S1_XP_BONUS_S2_AND_S3_SP_BONUS_S4);
|
||||
sm.addLong(addToExp);
|
||||
sm.addLong(addToExp - baseExp);
|
||||
sm.addLong(addToSp);
|
||||
sm.addLong(addToSp - baseSp);
|
||||
}
|
||||
else
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_EARNED_S1_XP_AND_S2_SP);
|
||||
sm.addLong(addToExp);
|
||||
sm.addLong(addToSp);
|
||||
}
|
||||
}
|
||||
activeChar.sendPacket(sm);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeExpAndSp(long addToExp, long addToSp)
|
||||
{
|
||||
return removeExpAndSp(addToExp, addToSp, true);
|
||||
}
|
||||
|
||||
public boolean removeExpAndSp(long addToExp, long addToSp, boolean sendMessage)
|
||||
{
|
||||
int level = getLevel();
|
||||
if (!super.removeExpAndSp(addToExp, addToSp))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sendMessage)
|
||||
{
|
||||
// Send a Server->Client System Message to the L2PcInstance
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOUR_XP_HAS_DECREASED_BY_S1);
|
||||
sm.addLong(addToExp);
|
||||
getActiveChar().sendPacket(sm);
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.YOUR_SP_HAS_DECREASED_BY_S1);
|
||||
sm.addLong(addToSp);
|
||||
getActiveChar().sendPacket(sm);
|
||||
if (getLevel() < level)
|
||||
{
|
||||
getActiveChar().broadcastStatusUpdate();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean addLevel(byte value)
|
||||
{
|
||||
if ((getLevel() + value) > (ExperienceTable.getInstance().getMaxLevel() - 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Notify to scripts
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerLevelChanged(getActiveChar(), getLevel(), getLevel() + value), getActiveChar());
|
||||
|
||||
boolean levelIncreased = super.addLevel(value);
|
||||
if (levelIncreased)
|
||||
{
|
||||
getActiveChar().setCurrentCp(getMaxCp());
|
||||
getActiveChar().broadcastPacket(new SocialAction(getActiveChar().getObjectId(), SocialAction.LEVEL_UP));
|
||||
getActiveChar().sendPacket(SystemMessageId.YOUR_LEVEL_HAS_INCREASED);
|
||||
getActiveChar().notifyFriends(L2FriendStatus.MODE_LEVEL);
|
||||
|
||||
L2ClassMasterInstance.showQuestionMark(getActiveChar());
|
||||
}
|
||||
|
||||
// Give AutoGet skills and all normal skills if Auto-Learn is activated.
|
||||
getActiveChar().rewardSkills();
|
||||
|
||||
if (getActiveChar().getClan() != null)
|
||||
{
|
||||
getActiveChar().getClan().updateClanMember(getActiveChar());
|
||||
getActiveChar().getClan().broadcastToOnlineMembers(new PledgeShowMemberListUpdate(getActiveChar()));
|
||||
}
|
||||
if (getActiveChar().isInParty())
|
||||
{
|
||||
getActiveChar().getParty().recalculatePartyLevel(); // Recalculate the party level
|
||||
}
|
||||
|
||||
if (getActiveChar().isTransformed() || getActiveChar().isInStance())
|
||||
{
|
||||
getActiveChar().getTransformation().onLevelUp(getActiveChar());
|
||||
}
|
||||
|
||||
// Synchronize level with pet if possible.
|
||||
if (getActiveChar().hasPet())
|
||||
{
|
||||
final L2PetInstance pet = (L2PetInstance) getActiveChar().getSummon();
|
||||
if (pet.getPetData().isSynchLevel() && (pet.getLevel() != getLevel()))
|
||||
{
|
||||
pet.getStat().setLevel(getLevel());
|
||||
pet.getStat().getExpForLevel(getActiveChar().getLevel());
|
||||
pet.setCurrentHp(pet.getMaxHp());
|
||||
pet.setCurrentMp(pet.getMaxMp());
|
||||
pet.broadcastPacket(new SocialAction(getActiveChar().getObjectId(), SocialAction.LEVEL_UP));
|
||||
pet.updateAndBroadcastStatus(1);
|
||||
}
|
||||
}
|
||||
|
||||
StatusUpdate su = new StatusUpdate(getActiveChar());
|
||||
su.addAttribute(StatusUpdate.LEVEL, getLevel());
|
||||
su.addAttribute(StatusUpdate.MAX_CP, getMaxCp());
|
||||
su.addAttribute(StatusUpdate.MAX_HP, getMaxHp());
|
||||
su.addAttribute(StatusUpdate.MAX_MP, getMaxMp());
|
||||
getActiveChar().sendPacket(su);
|
||||
|
||||
// Update the overloaded status of the L2PcInstance
|
||||
getActiveChar().refreshOverloaded();
|
||||
// Update the expertise status of the L2PcInstance
|
||||
getActiveChar().refreshExpertisePenalty();
|
||||
// Send a Server->Client packet UserInfo to the L2PcInstance
|
||||
getActiveChar().sendPacket(new UserInfo(getActiveChar()));
|
||||
// Send acquirable skill list
|
||||
getActiveChar().sendPacket(new AcquireSkillList(getActiveChar()));
|
||||
getActiveChar().sendPacket(new ExBrExtraUserInfo(getActiveChar()));
|
||||
getActiveChar().sendPacket(new ExVoteSystemInfo(getActiveChar()));
|
||||
if (getActiveChar().isInParty())
|
||||
{
|
||||
final PartySmallWindowUpdate partyWindow = new PartySmallWindowUpdate(getActiveChar(), false);
|
||||
partyWindow.addUpdateType(PartySmallWindowUpdateType.LEVEL);
|
||||
getActiveChar().getParty().broadcastToPartyMembers(getActiveChar(), partyWindow);
|
||||
}
|
||||
|
||||
return levelIncreased;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addSp(long value)
|
||||
{
|
||||
if (!super.addSp(value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
UserInfo ui = new UserInfo(getActiveChar(), false);
|
||||
ui.addComponentType(UserInfoType.CURRENT_HPMPCP_EXP_SP);
|
||||
getActiveChar().sendPacket(ui);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final long getExpForLevel(int level)
|
||||
{
|
||||
return ExperienceTable.getInstance().getExpForLevel(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final L2PcInstance getActiveChar()
|
||||
{
|
||||
return (L2PcInstance) super.getActiveChar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final long getExp()
|
||||
{
|
||||
if (getActiveChar().isSubClassActive())
|
||||
{
|
||||
return getActiveChar().getSubClasses().get(getActiveChar().getClassIndex()).getExp();
|
||||
}
|
||||
|
||||
return super.getExp();
|
||||
}
|
||||
|
||||
public final long getBaseExp()
|
||||
{
|
||||
return super.getExp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setExp(long value)
|
||||
{
|
||||
if (getActiveChar().isSubClassActive())
|
||||
{
|
||||
getActiveChar().getSubClasses().get(getActiveChar().getClassIndex()).setExp(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.setExp(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void setStartingExp(long value)
|
||||
{
|
||||
if (Config.BOTREPORT_ENABLE)
|
||||
{
|
||||
_startingXp = value;
|
||||
}
|
||||
}
|
||||
|
||||
public long getStartingExp()
|
||||
{
|
||||
return _startingXp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum cubic count.
|
||||
* @return the maximum cubic count
|
||||
*/
|
||||
public int getMaxCubicCount()
|
||||
{
|
||||
return _maxCubicCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum cubic count.
|
||||
* @param cubicCount the maximum cubic count
|
||||
*/
|
||||
public void setMaxCubicCount(int cubicCount)
|
||||
{
|
||||
_maxCubicCount = cubicCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum talisman count.
|
||||
* @return the maximum talisman count
|
||||
*/
|
||||
public int getTalismanSlots()
|
||||
{
|
||||
return _talismanSlots.get();
|
||||
}
|
||||
|
||||
public void addTalismanSlots(int count)
|
||||
{
|
||||
_talismanSlots.addAndGet(count);
|
||||
}
|
||||
|
||||
public boolean canEquipCloak()
|
||||
{
|
||||
return _cloakSlot;
|
||||
}
|
||||
|
||||
public void setCloakSlotStatus(boolean cloakSlot)
|
||||
{
|
||||
_cloakSlot = cloakSlot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final byte getLevel()
|
||||
{
|
||||
if (getActiveChar().isSubClassActive())
|
||||
{
|
||||
return getActiveChar().getSubClasses().get(getActiveChar().getClassIndex()).getLevel();
|
||||
}
|
||||
|
||||
return super.getLevel();
|
||||
}
|
||||
|
||||
public final byte getBaseLevel()
|
||||
{
|
||||
return super.getLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setLevel(byte value)
|
||||
{
|
||||
if (value > (ExperienceTable.getInstance().getMaxLevel() - 1))
|
||||
{
|
||||
value = (byte) (ExperienceTable.getInstance().getMaxLevel() - 1);
|
||||
}
|
||||
|
||||
if (getActiveChar().isSubClassActive())
|
||||
{
|
||||
getActiveChar().getSubClasses().get(getActiveChar().getClassIndex()).setLevel(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.setLevel(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getMaxCp()
|
||||
{
|
||||
// Get the Max CP (base+modifier) of the L2PcInstance
|
||||
int val = (getActiveChar() == null) ? 1 : (int) calcStat(Stats.MAX_CP, getActiveChar().getTemplate().getBaseCpMax(getActiveChar().getLevel()));
|
||||
if (val != _oldMaxCp)
|
||||
{
|
||||
_oldMaxCp = val;
|
||||
|
||||
// Launch a regen task if the new Max CP is higher than the old one
|
||||
if (getActiveChar().getStatus().getCurrentCp() != val)
|
||||
{
|
||||
getActiveChar().getStatus().setCurrentCp(getActiveChar().getStatus().getCurrentCp()); // trigger start of regeneration
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getMaxHp()
|
||||
{
|
||||
// Get the Max HP (base+modifier) of the L2PcInstance
|
||||
int val = (getActiveChar() == null) ? 1 : (int) calcStat(Stats.MAX_HP, getActiveChar().getTemplate().getBaseHpMax(getActiveChar().getLevel()));
|
||||
if (val != _oldMaxHp)
|
||||
{
|
||||
_oldMaxHp = val;
|
||||
|
||||
// Launch a regen task if the new Max HP is higher than the old one
|
||||
if (getActiveChar().getStatus().getCurrentHp() != val)
|
||||
{
|
||||
getActiveChar().getStatus().setCurrentHp(getActiveChar().getStatus().getCurrentHp()); // trigger start of regeneration
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getMaxMp()
|
||||
{
|
||||
// Get the Max MP (base+modifier) of the L2PcInstance
|
||||
int val = (getActiveChar() == null) ? 1 : (int) calcStat(Stats.MAX_MP, getActiveChar().getTemplate().getBaseMpMax(getActiveChar().getLevel()));
|
||||
|
||||
if (val != _oldMaxMp)
|
||||
{
|
||||
_oldMaxMp = val;
|
||||
|
||||
// Launch a regen task if the new Max MP is higher than the old one
|
||||
if (getActiveChar().getStatus().getCurrentMp() != val)
|
||||
{
|
||||
getActiveChar().getStatus().setCurrentMp(getActiveChar().getStatus().getCurrentMp()); // trigger start of regeneration
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final long getSp()
|
||||
{
|
||||
if (getActiveChar().isSubClassActive())
|
||||
{
|
||||
return getActiveChar().getSubClasses().get(getActiveChar().getClassIndex()).getSp();
|
||||
}
|
||||
|
||||
return super.getSp();
|
||||
}
|
||||
|
||||
public final long getBaseSp()
|
||||
{
|
||||
return super.getSp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setSp(long value)
|
||||
{
|
||||
if (getActiveChar().isSubClassActive())
|
||||
{
|
||||
getActiveChar().getSubClasses().get(getActiveChar().getClassIndex()).setSp(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.setSp(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param type movement type
|
||||
* @return the base move speed of given movement type.
|
||||
*/
|
||||
@Override
|
||||
public double getBaseMoveSpeed(MoveType type)
|
||||
{
|
||||
final L2PcInstance player = getActiveChar();
|
||||
if (player.isTransformed())
|
||||
{
|
||||
final TransformTemplate template = player.getTransformation().getTemplate(player);
|
||||
if (template != null)
|
||||
{
|
||||
return template.getBaseMoveSpeed(type);
|
||||
}
|
||||
}
|
||||
else if (player.isMounted())
|
||||
{
|
||||
final L2PetLevelData data = PetDataTable.getInstance().getPetLevelData(player.getMountNpcId(), player.getMountLevel());
|
||||
if (data != null)
|
||||
{
|
||||
return data.getSpeedOnRide(type);
|
||||
}
|
||||
}
|
||||
return super.getBaseMoveSpeed(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRunSpeed()
|
||||
{
|
||||
double val = super.getRunSpeed() + Config.RUN_SPD_BOOST;
|
||||
|
||||
// Apply max run speed cap.
|
||||
if ((val > Config.MAX_RUN_SPEED) && !getActiveChar().canOverrideCond(PcCondOverride.MAX_STATS_VALUE))
|
||||
{
|
||||
return Config.MAX_RUN_SPEED;
|
||||
}
|
||||
|
||||
// Check for mount penalties
|
||||
if (getActiveChar().isMounted())
|
||||
{
|
||||
// if level diff with mount >= 10, it decreases move speed by 50%
|
||||
if ((getActiveChar().getMountLevel() - getActiveChar().getLevel()) >= 10)
|
||||
{
|
||||
val /= 2;
|
||||
}
|
||||
// if mount is hungry, it decreases move speed by 50%
|
||||
if (getActiveChar().isHungry())
|
||||
{
|
||||
val /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getWalkSpeed()
|
||||
{
|
||||
double val = super.getWalkSpeed() + Config.RUN_SPD_BOOST;
|
||||
|
||||
// Apply max run speed cap.
|
||||
if ((val > Config.MAX_RUN_SPEED) && !getActiveChar().canOverrideCond(PcCondOverride.MAX_STATS_VALUE))
|
||||
{
|
||||
return Config.MAX_RUN_SPEED;
|
||||
}
|
||||
|
||||
if (getActiveChar().isMounted())
|
||||
{
|
||||
// if level diff with mount >= 10, it decreases move speed by 50%
|
||||
if ((getActiveChar().getMountLevel() - getActiveChar().getLevel()) >= 10)
|
||||
{
|
||||
val /= 2;
|
||||
}
|
||||
// if mount is hungry, it decreases move speed by 50%
|
||||
if (getActiveChar().isHungry())
|
||||
{
|
||||
val /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPAtkSpd()
|
||||
{
|
||||
int val = super.getPAtkSpd();
|
||||
|
||||
if ((val > Config.MAX_PATK_SPEED) && !getActiveChar().canOverrideCond(PcCondOverride.MAX_STATS_VALUE))
|
||||
{
|
||||
return Config.MAX_PATK_SPEED;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private void updateVitalityLevel(boolean quiet)
|
||||
{
|
||||
final byte level;
|
||||
|
||||
if (_vitalityPoints <= VITALITY_LEVELS[0])
|
||||
{
|
||||
level = 0;
|
||||
}
|
||||
else if (_vitalityPoints <= VITALITY_LEVELS[1])
|
||||
{
|
||||
level = 1;
|
||||
}
|
||||
else if (_vitalityPoints <= VITALITY_LEVELS[2])
|
||||
{
|
||||
level = 2;
|
||||
}
|
||||
else if (_vitalityPoints <= VITALITY_LEVELS[3])
|
||||
{
|
||||
level = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
level = 4;
|
||||
}
|
||||
|
||||
if (!quiet && (level != _vitalityLevel))
|
||||
{
|
||||
if (level < _vitalityLevel)
|
||||
{
|
||||
getActiveChar().sendPacket(SystemMessageId.YOUR_VITALITY_HAS_DECREASED);
|
||||
}
|
||||
else
|
||||
{
|
||||
getActiveChar().sendPacket(SystemMessageId.YOUR_VITALITY_HAS_INCREASED);
|
||||
}
|
||||
if (level == 0)
|
||||
{
|
||||
getActiveChar().sendPacket(SystemMessageId.YOUR_VITALITY_IS_FULLY_EXHAUSTED);
|
||||
}
|
||||
else if (level == 4)
|
||||
{
|
||||
getActiveChar().sendPacket(SystemMessageId.YOUR_VITALITY_IS_AT_MAXIMUM);
|
||||
}
|
||||
}
|
||||
|
||||
_vitalityLevel = level;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return current vitality points in integer format
|
||||
*/
|
||||
public int getVitalityPoints()
|
||||
{
|
||||
return (int) _vitalityPoints;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set current vitality points to this value if quiet = true - does not send system messages
|
||||
*/
|
||||
public void setVitalityPoints(int points, boolean quiet)
|
||||
{
|
||||
points = Math.min(Math.max(points, MIN_VITALITY_POINTS), MAX_VITALITY_POINTS);
|
||||
if (points == _vitalityPoints)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_vitalityPoints = points;
|
||||
updateVitalityLevel(quiet);
|
||||
final L2PcInstance player = getActiveChar();
|
||||
player.sendPacket(new ExVitalityPointInfo(getVitalityPoints()));
|
||||
if (player.isInParty())
|
||||
{
|
||||
final PartySmallWindowUpdate partyWindow = new PartySmallWindowUpdate(player, false);
|
||||
partyWindow.addUpdateType(PartySmallWindowUpdateType.VITALITY_POINTS);
|
||||
player.getParty().broadcastToPartyMembers(player, partyWindow);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void updateVitalityPoints(float points, boolean useRates, boolean quiet)
|
||||
{
|
||||
if ((points == 0) || !Config.ENABLE_VITALITY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (useRates)
|
||||
{
|
||||
if (getActiveChar().isLucky())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (points < 0) // vitality consumed
|
||||
{
|
||||
int stat = (int) calcStat(Stats.VITALITY_CONSUME_RATE, 1, getActiveChar(), null);
|
||||
|
||||
if (stat == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (stat < 0)
|
||||
{
|
||||
points = -points;
|
||||
}
|
||||
}
|
||||
|
||||
if (points > 0)
|
||||
{
|
||||
// vitality increased
|
||||
points *= Config.RATE_VITALITY_GAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
// vitality decreased
|
||||
points *= Config.RATE_VITALITY_LOST;
|
||||
}
|
||||
}
|
||||
|
||||
if (points > 0)
|
||||
{
|
||||
points = Math.min(_vitalityPoints + points, MAX_VITALITY_POINTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
points = Math.max(_vitalityPoints + points, MIN_VITALITY_POINTS);
|
||||
}
|
||||
|
||||
if (Math.abs(points - _vitalityPoints) <= 1e-6)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_vitalityPoints = points;
|
||||
updateVitalityLevel(quiet);
|
||||
}
|
||||
|
||||
public double getVitalityMultiplier()
|
||||
{
|
||||
double vitality = 1.0;
|
||||
|
||||
if (Config.ENABLE_VITALITY)
|
||||
{
|
||||
switch (getVitalityLevel())
|
||||
{
|
||||
case 1:
|
||||
vitality = Config.RATE_VITALITY_LEVEL_1;
|
||||
break;
|
||||
case 2:
|
||||
vitality = Config.RATE_VITALITY_LEVEL_2;
|
||||
break;
|
||||
case 3:
|
||||
vitality = Config.RATE_VITALITY_LEVEL_3;
|
||||
break;
|
||||
case 4:
|
||||
vitality = Config.RATE_VITALITY_LEVEL_4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return vitality;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the _vitalityLevel
|
||||
*/
|
||||
public byte getVitalityLevel()
|
||||
{
|
||||
return _vitalityLevel;
|
||||
}
|
||||
|
||||
public double getExpBonusMultiplier()
|
||||
{
|
||||
double bonus = 1.0;
|
||||
double vitality = 1.0;
|
||||
double nevits = 1.0;
|
||||
double hunting = 1.0;
|
||||
double bonusExp = 1.0;
|
||||
|
||||
// Bonus from Vitality System
|
||||
vitality = getVitalityMultiplier();
|
||||
|
||||
// Bonus from Nevit's Blessing
|
||||
nevits = RecoBonus.getRecoMultiplier(getActiveChar());
|
||||
|
||||
// Bonus from Nevit's Hunting
|
||||
// TODO: Nevit's hunting bonus
|
||||
|
||||
// Bonus exp from skills
|
||||
bonusExp = 1 + (calcStat(Stats.BONUS_EXP, 0, null, null) / 100);
|
||||
|
||||
if (vitality > 1.0)
|
||||
{
|
||||
bonus += (vitality - 1);
|
||||
}
|
||||
if (nevits > 1.0)
|
||||
{
|
||||
bonus += (nevits - 1);
|
||||
}
|
||||
if (hunting > 1.0)
|
||||
{
|
||||
bonus += (hunting - 1);
|
||||
}
|
||||
if (bonusExp > 1)
|
||||
{
|
||||
bonus += (bonusExp - 1);
|
||||
}
|
||||
|
||||
// Check for abnormal bonuses
|
||||
bonus = Math.max(bonus, 1);
|
||||
bonus = Math.min(bonus, Config.MAX_BONUS_EXP);
|
||||
|
||||
return bonus;
|
||||
}
|
||||
|
||||
public double getSpBonusMultiplier()
|
||||
{
|
||||
double bonus = 1.0;
|
||||
double vitality = 1.0;
|
||||
double nevits = 1.0;
|
||||
double hunting = 1.0;
|
||||
double bonusSp = 1.0;
|
||||
|
||||
// Bonus from Vitality System
|
||||
vitality = getVitalityMultiplier();
|
||||
|
||||
// Bonus from Nevit's Blessing
|
||||
nevits = RecoBonus.getRecoMultiplier(getActiveChar());
|
||||
|
||||
// Bonus from Nevit's Hunting
|
||||
// TODO: Nevit's hunting bonus
|
||||
|
||||
// Bonus sp from skills
|
||||
bonusSp = 1 + (calcStat(Stats.BONUS_SP, 0, null, null) / 100);
|
||||
|
||||
if (vitality > 1.0)
|
||||
{
|
||||
bonus += (vitality - 1);
|
||||
}
|
||||
if (nevits > 1.0)
|
||||
{
|
||||
bonus += (nevits - 1);
|
||||
}
|
||||
if (hunting > 1.0)
|
||||
{
|
||||
bonus += (hunting - 1);
|
||||
}
|
||||
if (bonusSp > 1)
|
||||
{
|
||||
bonus += (bonusSp - 1);
|
||||
}
|
||||
|
||||
// Check for abnormal bonuses
|
||||
bonus = Math.max(bonus, 1);
|
||||
bonus = Math.min(bonus, Config.MAX_BONUS_SP);
|
||||
|
||||
return bonus;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user