Project update.
This commit is contained in:
1750
trunk/java/com/l2jmobius/gameserver/model/actor/L2Attackable.java
Normal file
1750
trunk/java/com/l2jmobius/gameserver/model/actor/L2Attackable.java
Normal file
File diff suppressed because it is too large
Load Diff
7135
trunk/java/com/l2jmobius/gameserver/model/actor/L2Character.java
Normal file
7135
trunk/java/com/l2jmobius/gameserver/model/actor/L2Character.java
Normal file
File diff suppressed because it is too large
Load Diff
185
trunk/java/com/l2jmobius/gameserver/model/actor/L2Decoy.java
Normal file
185
trunk/java/com/l2jmobius/gameserver/model/actor/L2Decoy.java
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.items.L2Weapon;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CharInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.L2GameServerPacket;
|
||||
import com.l2jmobius.gameserver.taskmanager.DecayTaskManager;
|
||||
|
||||
public abstract class L2Decoy extends L2Character
|
||||
{
|
||||
private final L2PcInstance _owner;
|
||||
|
||||
/**
|
||||
* Creates an abstract decoy.
|
||||
* @param template the decoy template
|
||||
* @param owner the owner
|
||||
*/
|
||||
public L2Decoy(L2CharTemplate template, L2PcInstance owner)
|
||||
{
|
||||
super(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 updateAbnormalVisualEffects()
|
||||
{
|
||||
final 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
1850
trunk/java/com/l2jmobius/gameserver/model/actor/L2Npc.java
Normal file
1850
trunk/java/com/l2jmobius/gameserver/model/actor/L2Npc.java
Normal file
File diff suppressed because it is too large
Load Diff
364
trunk/java/com/l2jmobius/gameserver/model/actor/L2Playable.java
Normal file
364
trunk/java/com/l2jmobius/gameserver/model/actor/L2Playable.java
Normal file
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.CtrlEvent;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.InstanceManager;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.knownlist.PlayableKnownList;
|
||||
import com.l2jmobius.gameserver.model.actor.stat.PlayableStat;
|
||||
import com.l2jmobius.gameserver.model.actor.status.PlayableStatus;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jmobius.gameserver.model.effects.EffectFlag;
|
||||
import com.l2jmobius.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jmobius.gameserver.model.entity.Instance;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.OnCreatureKill;
|
||||
import com.l2jmobius.gameserver.model.events.returns.TerminateReturn;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* Creates an abstract playable creature.
|
||||
* @param objectId the playable object ID
|
||||
* @param template the creature template
|
||||
*/
|
||||
public L2Playable(int objectId, L2CharTemplate template)
|
||||
{
|
||||
super(objectId, template);
|
||||
setInstanceType(InstanceType.L2Playable);
|
||||
setIsInvul(false);
|
||||
}
|
||||
|
||||
public L2Playable(L2CharTemplate template)
|
||||
{
|
||||
super(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())
|
||||
{
|
||||
final 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
|
||||
final 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)
|
||||
{
|
||||
final L2PcInstance player = killer.getActingPlayer();
|
||||
|
||||
if (player != null)
|
||||
{
|
||||
player.onKillUpdatePvPKarma(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify L2Character AI
|
||||
getAI().notifyEvent(CtrlEvent.EVT_DEAD);
|
||||
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.getReputation() < 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.getReputation() < 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 void doPickupItem(L2Object object);
|
||||
|
||||
public abstract int getReputation();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
1255
trunk/java/com/l2jmobius/gameserver/model/actor/L2Summon.java
Normal file
1255
trunk/java/com/l2jmobius/gameserver/model/actor/L2Summon.java
Normal file
File diff suppressed because it is too large
Load Diff
85
trunk/java/com/l2jmobius/gameserver/model/actor/L2Tower.java
Normal file
85
trunk/java/com/l2jmobius/gameserver/model/actor/L2Tower.java
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor;
|
||||
|
||||
import com.l2jmobius.gameserver.GeoData;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
|
||||
/**
|
||||
* This class is a super-class for L2ControlTowerInstance and L2FlameTowerInstance.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public abstract class L2Tower extends L2Npc
|
||||
{
|
||||
/**
|
||||
* Creates an abstract Tower.
|
||||
* @param template the tower template
|
||||
*/
|
||||
public L2Tower(L2NpcTemplate template)
|
||||
{
|
||||
super(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);
|
||||
}
|
||||
}
|
||||
508
trunk/java/com/l2jmobius/gameserver/model/actor/L2Vehicle.java
Normal file
508
trunk/java/com/l2jmobius/gameserver/model/actor/L2Vehicle.java
Normal file
@@ -0,0 +1,508 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.GameTimeController;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.TeleportWhereType;
|
||||
import com.l2jmobius.gameserver.model.VehiclePathPoint;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.knownlist.VehicleKnownList;
|
||||
import com.l2jmobius.gameserver.model.actor.stat.VehicleStat;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jmobius.gameserver.model.interfaces.ILocational;
|
||||
import com.l2jmobius.gameserver.model.items.L2Weapon;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.L2GameServerPacket;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* @author DS
|
||||
*/
|
||||
public abstract class L2Vehicle extends L2Character
|
||||
{
|
||||
protected int _dockId = 0;
|
||||
protected final List<L2PcInstance> _passengers = new CopyOnWriteArrayList<>();
|
||||
protected Location _oustLoc = null;
|
||||
private Runnable _engine = null;
|
||||
|
||||
protected VehiclePathPoint[] _currentPath = null;
|
||||
protected int _runState = 0;
|
||||
|
||||
/**
|
||||
* Creates an abstract vehicle.
|
||||
* @param template the vehicle template
|
||||
*/
|
||||
public L2Vehicle(L2CharTemplate template)
|
||||
{
|
||||
super(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());
|
||||
}
|
||||
|
||||
final 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()
|
||||
{
|
||||
_passengers.forEach(p -> oustPlayer(p));
|
||||
_passengers.clear();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
final boolean result = super.updatePosition();
|
||||
|
||||
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 updateAbnormalVisualEffects()
|
||||
{
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detachAI()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVehicle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.appearance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.Sex;
|
||||
import com.l2jmobius.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()
|
||||
{
|
||||
if (_owner.getReputation() != 0)
|
||||
{
|
||||
return 0xFFFFFF; // Using 0xFFFFFF value in case _nameColor has changed.
|
||||
}
|
||||
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,47 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.commission.ExShowCommission;
|
||||
|
||||
/**
|
||||
* @author NosBit
|
||||
*/
|
||||
public class CommissionManagerInstance extends L2Npc
|
||||
{
|
||||
public CommissionManagerInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.CommissionManagerInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
if (command.equalsIgnoreCase("show_commission"))
|
||||
{
|
||||
player.sendPacket(ExShowCommission.STATIC_PACKET);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onBypassFeedback(player, command);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision: $ $Date: $
|
||||
* @author LBaldi
|
||||
*/
|
||||
public class L2AdventurerInstance extends L2NpcInstance
|
||||
{
|
||||
public L2AdventurerInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2AdventurerInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "html/adventurer_guildsman/" + pom + ".htm";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.L2AirShipAI;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.AirShipManager;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExAirShipInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExGetOffAirShip;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExGetOnAirShip;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExMoveToLocationAirShip;
|
||||
import com.l2jmobius.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(L2CharTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2AirShipInstance);
|
||||
setAI(new L2AirShipAI(this));
|
||||
}
|
||||
|
||||
@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 updateAbnormalVisualEffects()
|
||||
{
|
||||
broadcastPacket(new ExAirShipInfo(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendInfo(L2PcInstance activeChar)
|
||||
{
|
||||
if (isVisibleFor(activeChar))
|
||||
{
|
||||
activeChar.sendPacket(new ExAirShipInfo(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
|
||||
public final class L2ArtefactInstance extends L2Npc
|
||||
{
|
||||
/**
|
||||
* Creates a castle siege artifact.
|
||||
* @param template the artifact NPC template
|
||||
*/
|
||||
public L2ArtefactInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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,741 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import static com.l2jmobius.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 java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.ClanHallAuctionManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.ClanHallManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
|
||||
import com.l2jmobius.gameserver.model.ClanPrivilege;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.entity.Auction;
|
||||
import com.l2jmobius.gameserver.model.entity.Auction.Bidder;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.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 ConcurrentHashMap<>();
|
||||
|
||||
public L2AuctioneerInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2AuctioneerInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
final int condition = validateCondition(player);
|
||||
if (condition <= COND_ALL_FALSE)
|
||||
{
|
||||
// TODO: html
|
||||
player.sendMessage("Wrong conditions.");
|
||||
return;
|
||||
}
|
||||
else if (condition == COND_BUSY_BECAUSE_OF_SIEGE)
|
||||
{
|
||||
final String filename = "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)
|
||||
{
|
||||
final StringTokenizer st = new StringTokenizer(command, " ");
|
||||
final 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
|
||||
{
|
||||
final int days = Integer.parseInt(val);
|
||||
try
|
||||
{
|
||||
final 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);
|
||||
}
|
||||
|
||||
final 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);
|
||||
|
||||
final String filename = "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
|
||||
{
|
||||
final 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
|
||||
{
|
||||
final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
|
||||
final int auctionId = Integer.parseInt(val);
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.warning("auction test started");
|
||||
}
|
||||
|
||||
final String filename = "html/auction/AgitAuctionInfo.htm";
|
||||
final Auction a = ClanHallAuctionManager.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
|
||||
{
|
||||
final int auctionId = Integer.parseInt(val);
|
||||
try
|
||||
{
|
||||
long bid = 0;
|
||||
if (st.countTokens() >= 1)
|
||||
{
|
||||
bid = Math.min(Long.parseLong(st.nextToken()), MAX_ADENA);
|
||||
}
|
||||
|
||||
ClanHallAuctionManager.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
|
||||
{
|
||||
final String filename = "html/auction/AgitBid1.htm";
|
||||
|
||||
long minimumBid = ClanHallAuctionManager.getInstance().getAuction(Integer.parseInt(val)).getHighestBidderMaxBid();
|
||||
if (minimumBid == 0)
|
||||
{
|
||||
minimumBid = ClanHallAuctionManager.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"))
|
||||
{
|
||||
final List<Auction> auctions = ClanHallAuctionManager.getInstance().getAuctions();
|
||||
final SimpleDateFormat format = new SimpleDateFormat("yy/MM/dd");
|
||||
/** Limit for make new page, prevent client crash **/
|
||||
int limit = 15;
|
||||
int start;
|
||||
int i = 1;
|
||||
final 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");
|
||||
}
|
||||
|
||||
final 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>");
|
||||
final String filename = "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 = "";
|
||||
final Map<Integer, Bidder> bidders = ClanHallAuctionManager.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>";
|
||||
}
|
||||
final String filename = "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))
|
||||
{
|
||||
final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
|
||||
final String filename = "html/auction/AgitBidInfo.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
final Auction a = ClanHallAuctionManager.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) && (ClanHallAuctionManager.getInstance().getAuction(player.getClan().getHideoutId()) != null))
|
||||
{
|
||||
final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
|
||||
final String filename = "html/auction/AgitSaleInfo.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
final Auction a = ClanHallAuctionManager.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))
|
||||
{
|
||||
final int ItemId = player.getClan().getHideoutId();
|
||||
final String filename = "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"))
|
||||
{
|
||||
final long bid = ClanHallAuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt()).getBidders().get(player.getClanId()).getBid();
|
||||
final String filename = "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 (ClanHallAuctionManager.getInstance().getAuction(player.getClan().getAuctionBiddedAt()) != null)
|
||||
{
|
||||
ClanHallAuctionManager.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))
|
||||
{
|
||||
final String filename = "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;
|
||||
}
|
||||
final String filename = "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 (ClanHallAuctionManager.getInstance().getAuction(player.getClan().getHideoutId()) != null)
|
||||
{
|
||||
ClanHallAuctionManager.getInstance().getAuction(player.getClan().getHideoutId()).cancelAuction();
|
||||
player.sendMessage("Your auction has been canceled");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("sale2"))
|
||||
{
|
||||
final String filename = "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))
|
||||
{
|
||||
final String filename = "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;
|
||||
}
|
||||
final String filename = "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"))
|
||||
{
|
||||
final SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm");
|
||||
if (!player.hasClanPrivilege(ClanPrivilege.CH_AUCTION))
|
||||
{
|
||||
final String filename = "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
|
||||
{
|
||||
final String filename = "html/auction/AgitBid2.htm";
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), filename);
|
||||
final Auction a = ClanHallAuctionManager.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(), "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 = "html/auction/auction-no.htm";
|
||||
|
||||
final int condition = validateCondition(player);
|
||||
if (condition == COND_BUSY_BECAUSE_OF_SIEGE)
|
||||
{
|
||||
filename = "html/auction/auction-busy.htm"; // Busy because of siege
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = "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)
|
||||
{
|
||||
final 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,367 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.PetDataTable;
|
||||
import com.l2jmobius.gameserver.datatables.SkillData;
|
||||
import com.l2jmobius.gameserver.enums.CategoryType;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.L2PetData.L2PetSkillLearn;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* Creates a baby pet.
|
||||
* @param template the baby pet NPC template
|
||||
* @param owner the owner
|
||||
* @param control the summoning item
|
||||
*/
|
||||
public L2BabyPetInstance(L2NpcTemplate template, L2PcInstance owner, L2ItemInstance control)
|
||||
{
|
||||
super(template, owner, control);
|
||||
setInstanceType(InstanceType.L2BabyPetInstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a baby pet.
|
||||
* @param template the baby pet NPC template
|
||||
* @param owner the owner
|
||||
* @param control the summoning item
|
||||
* @param level the level
|
||||
*/
|
||||
public L2BabyPetInstance(L2NpcTemplate template, L2PcInstance owner, L2ItemInstance control, byte level)
|
||||
{
|
||||
super(template, owner, control, level);
|
||||
setInstanceType(InstanceType.L2BabyPetInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn()
|
||||
{
|
||||
super.onSpawn();
|
||||
|
||||
double healPower = 0;
|
||||
for (L2PetSkillLearn psl : PetDataTable.getInstance().getPetData(getId()).getAvailableSkills())
|
||||
{
|
||||
final int id = psl.getSkillId();
|
||||
final 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);
|
||||
|
||||
final 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,169 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.model.ArenaParticipantsHolder;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.entity.BlockCheckerEngine;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExCubeGameChangePoints;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExCubeGameExtendedChangePoints;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcInfo;
|
||||
import com.l2jmobius.util.Rnd;
|
||||
|
||||
/**
|
||||
* @author BiggBoss
|
||||
*/
|
||||
public class L2BlockInstance extends L2MonsterInstance
|
||||
{
|
||||
private int _colorEffect;
|
||||
|
||||
/**
|
||||
* Creates a block.
|
||||
* @param template the block NPC template
|
||||
*/
|
||||
public L2BlockInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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
|
||||
final 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);
|
||||
|
||||
final int timeLeft = (int) ((eng.getStarterTime() - System.currentTimeMillis()) / 1000);
|
||||
final boolean isRed = eng.getHolder().getRedPlayers().contains(player);
|
||||
|
||||
final ExCubeGameChangePoints changePoints = new ExCubeGameChangePoints(timeLeft, eng.getBluePoints(), eng.getRedPoints());
|
||||
final 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)
|
||||
{
|
||||
final L2ItemInstance drop = ItemTable.getInstance().createItem("Loot", id, 1, player, this);
|
||||
final int x = getX() + Rnd.get(50);
|
||||
final int y = getY() + Rnd.get(50);
|
||||
final int z = getZ();
|
||||
|
||||
drop.dropMe(this, x, y, z);
|
||||
|
||||
eng.addNewDrop(drop);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.L2BoatAI;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.VehicleDeparture;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.VehicleInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.VehicleStarted;
|
||||
|
||||
/**
|
||||
* @author Maktakien, DS
|
||||
*/
|
||||
public class L2BoatInstance extends L2Vehicle
|
||||
{
|
||||
protected static final Logger _logBoat = Logger.getLogger(L2BoatInstance.class.getName());
|
||||
|
||||
/**
|
||||
* Creates a boat.
|
||||
* @param template the boat template
|
||||
*/
|
||||
public L2BoatInstance(L2CharTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2BoatInstance);
|
||||
setAI(new L2BoatAI(this));
|
||||
}
|
||||
|
||||
@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,107 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.ClanPrivilege;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.entity.clanhall.SiegableHall;
|
||||
|
||||
public class L2CastleDoormenInstance extends L2DoormenInstance
|
||||
{
|
||||
public L2CastleDoormenInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2CastleDoormenInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void openDoors(L2PcInstance player, String command)
|
||||
{
|
||||
final 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)
|
||||
{
|
||||
final 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))
|
||||
{
|
||||
final 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()
|
||||
{
|
||||
final SiegableHall hall = getConquerableHall();
|
||||
if (hall != null)
|
||||
{
|
||||
return hall.isInSiege();
|
||||
}
|
||||
return getCastle().getZone().isActive();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
/**
|
||||
* This class manages all chest.
|
||||
* @author Julian
|
||||
*/
|
||||
public final class L2ChestInstance extends L2MonsterInstance
|
||||
{
|
||||
private volatile boolean _specialDrop;
|
||||
|
||||
/**
|
||||
* Creates a chest.
|
||||
* @param template the chest NPC template
|
||||
*/
|
||||
public L2ChestInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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,224 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.ClanHallManager;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.entity.ClanHall;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jmobius.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
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a clan hall doorman.
|
||||
* @param template the doorman NPC template
|
||||
*/
|
||||
public L2ClanHallDoormenInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2ClanHallDoormenInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
if (_hasEvolve && command.startsWith("evolve"))
|
||||
{
|
||||
if (isOwnerClan(player))
|
||||
{
|
||||
final 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(), "html/clanHallDoormen/evolve-ok.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "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)
|
||||
{
|
||||
final L2Clan owner = ClanTable.getInstance().getClan(getClanHall().getOwnerId());
|
||||
if (isOwnerClan(player))
|
||||
{
|
||||
if (_hasEvolve)
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "html/clanHallDoormen/doormen2.htm");
|
||||
html.replace("%clanname%", owner.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "html/clanHallDoormen/doormen1.htm");
|
||||
html.replace("%clanname%", owner.getName());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((owner != null) && (owner.getLeader() != null))
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "html/clanHallDoormen/doormen-no.htm");
|
||||
html.replace("%leadername%", owner.getLeaderName());
|
||||
html.replace("%clanname%", owner.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "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(), "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(), "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,563 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.cache.HtmCache;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.ClassListData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SkillTreesData;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.enums.Race;
|
||||
import com.l2jmobius.gameserver.enums.SubclassInfoType;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExSubjobInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExUserInfoInvenWeight;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.TutorialCloseHtml;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.TutorialShowQuestionMark;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
|
||||
import com.l2jmobius.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
|
||||
{
|
||||
/**
|
||||
* Creates a class master.
|
||||
* @param template the class master NPC template
|
||||
*/
|
||||
public L2ClassMasterInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2ClassMasterInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "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("4thClass"))
|
||||
{
|
||||
showHtmlMenu(player, getObjectId(), 4);
|
||||
}
|
||||
else if (command.startsWith("change_class"))
|
||||
{
|
||||
final int val = Integer.parseInt(command.substring(13));
|
||||
|
||||
if (checkAndChangeClass(player, val))
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "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));
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "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(), "html/classmaster/noclanleader.htm");
|
||||
player.sendPacket(html);
|
||||
}
|
||||
else if (player.getClan().getLevel() >= 5)
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "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("AlternateClassMaster"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Removed - did not work with normal characres (only GMs)
|
||||
// if (!player.getFloodProtectors().getServerBypass().tryPerformAction("changeclass"))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
try
|
||||
{
|
||||
final int val = Integer.parseInt(request.substring(21));
|
||||
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) > 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(), "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 if (Config.CLASS_MASTER_SETTINGS.isAllowed(4))
|
||||
{
|
||||
sb.append("Come back after your third 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 if (Config.CLASS_MASTER_SETTINGS.isAllowed(4))
|
||||
{
|
||||
sb.append("Come back after your third 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 if (Config.CLASS_MASTER_SETTINGS.isAllowed(4))
|
||||
{
|
||||
sb.append("Come back here when you reached level 85 to change your class.<br>");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("I can't change your occupation.<br>");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
if (Config.CLASS_MASTER_SETTINGS.isAllowed(4))
|
||||
{
|
||||
sb.append("Come back here when you reached level 85 to change your class.<br>");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("I can't change your occupation.<br>");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
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(), "html/classmaster/nomore.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
final int minLevel = getMinLevel(currentClassId.level(), player);
|
||||
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(), "html/classmaster/template.htm");
|
||||
html.replace("%name%", ClassListData.getInstance().getClass(currentClassId).getClientCode());
|
||||
html.replace("%menu%", menu.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "html/classmaster/comebacklater.htm");
|
||||
html.replace("%level%", String.valueOf(getMinLevel(level - 1, player)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (minLevel < Integer.MAX_VALUE)
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "html/classmaster/comebacklater.htm");
|
||||
html.replace("%level%", String.valueOf(minLevel));
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "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) > player.getLevel()) && !Config.ALLOW_ENTIRE_TREE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String msg = HtmCache.getInstance().getHtm(player.getHtmlPrefix(), "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=\"bypass -h AlternateClassMaster ", 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 NpcHtmlMessage(msg));
|
||||
}
|
||||
|
||||
private static final boolean checkAndChangeClass(L2PcInstance player, int val)
|
||||
{
|
||||
final ClassId currentClassId = player.getClassId();
|
||||
if ((getMinLevel(currentClassId.level(), player) > 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_COUNT);
|
||||
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.getActiveClassId());
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setBaseClassId(player.getActiveClassId());
|
||||
}
|
||||
|
||||
player.broadcastUserInfo();
|
||||
if (player.isAwaken())
|
||||
{
|
||||
SkillTreesData.getInstance().cleanSkillUponAwakening(player);
|
||||
}
|
||||
player.sendPacket(new ExSubjobInfo(player, SubclassInfoType.CLASS_CHANGED));
|
||||
player.sendPacket(new ExUserInfoInvenWeight(player));
|
||||
|
||||
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)) || ((player.getClassId().level() == 3) && (player.getLevel() >= 85))))
|
||||
{
|
||||
showQuestionMark(player);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param level - current skillId level (0 - start, 1 - first, etc)
|
||||
* @param player L2PcInstance
|
||||
* @return minimum player level required for next class transfer
|
||||
*/
|
||||
private static final int getMinLevel(int level, L2PcInstance player)
|
||||
{
|
||||
if (player.getRace() == Race.ERTHEIA)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
return 40;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
return 76;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
return 85;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (level)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
return 40;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
return 76;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
return 85;
|
||||
}
|
||||
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 (oldCID.equals(ClassId.FEMALE_SOUL_HOUND) && newCID.equals(ClassId.FEOH_SOUL_HOUND))
|
||||
{
|
||||
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,92 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Tower;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
/**
|
||||
* Class for Control Tower instance.
|
||||
*/
|
||||
public class L2ControlTowerInstance extends L2Tower
|
||||
{
|
||||
private volatile List<L2Spawn> _guards;
|
||||
|
||||
/**
|
||||
* Creates a control tower.
|
||||
* @param template the control tower NPC template
|
||||
*/
|
||||
public L2ControlTowerInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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)
|
||||
{
|
||||
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 CopyOnWriteArrayList<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return _guards;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.model.actor.stat.ControllableAirShipStat;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* Creates a controllable air ship.
|
||||
* @param template the controllable air ship template
|
||||
* @param ownerId the owner ID
|
||||
*/
|
||||
public L2ControllableAirShipInstance(L2CharTemplate template, int ownerId)
|
||||
{
|
||||
super(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;
|
||||
}
|
||||
}
|
||||
updateAbnormalVisualEffects();
|
||||
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);
|
||||
updateAbnormalVisualEffects();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,89 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.L2CharacterAI;
|
||||
import com.l2jmobius.gameserver.ai.L2ControllableMobAI;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
/**
|
||||
* @author littlecrow
|
||||
*/
|
||||
public class L2ControllableMobInstance extends L2MonsterInstance
|
||||
{
|
||||
private boolean _isInvul;
|
||||
|
||||
/**
|
||||
* Creates a controllable monster.
|
||||
* @param template the controllable monster NPC template
|
||||
*/
|
||||
public L2ControllableMobInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2ControllableMobInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAggressive()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAggroRange()
|
||||
{
|
||||
// force mobs to be aggro
|
||||
return 500;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected L2CharacterAI initAI()
|
||||
{
|
||||
return new L2ControllableMobAI(this);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detachAI()
|
||||
{
|
||||
// do nothing, AI of controllable mobs can't be detached automatically
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,921 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.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.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.CtrlEvent;
|
||||
import com.l2jmobius.gameserver.datatables.SkillData;
|
||||
import com.l2jmobius.gameserver.instancemanager.DuelManager;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2Party;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.cubics.CubicAction;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.cubics.CubicBuff;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.cubics.CubicDisappear;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.cubics.CubicHeal;
|
||||
import com.l2jmobius.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jmobius.gameserver.model.entity.TvTEvent;
|
||||
import com.l2jmobius.gameserver.model.entity.TvTEventTeam;
|
||||
import com.l2jmobius.gameserver.model.interfaces.IIdentifiable;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.stats.Formulas;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.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;
|
||||
public static final int AVENGING_CUBIC = 15;
|
||||
public static final int KNIGHT_CUBIC = 16;
|
||||
public static final int FAIRY_CUBIC = 17;
|
||||
public static final int BUFF_CUBIC = 18;
|
||||
public static final int MIND_CUBIC = 19; // NOT USED
|
||||
public static final int PHANTOM_CUBIC = 20;
|
||||
public static final int HEX_CUBIC = 21;
|
||||
public static final int GUARDIAN_CUBIC = 22;
|
||||
|
||||
// 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;
|
||||
public static final int SKILL_CUBIC_HEALER = 11807;
|
||||
public static final int SKILL_BUFF_CUBIC_HEAL = 10083;
|
||||
public static final int SKILL_MIND_CUBIC_RECHARGE = 10084;
|
||||
public static final int SKILL_BUFF_CUBIC_GREAT_HEAL = 10082;
|
||||
public static final int SKILL_MIND_CUBIC_GREAT_RECHARGE = 10089;
|
||||
public static final int SKILL_AVENGING_CUBIC_CLEANCE = 11292;
|
||||
public static final int SKILL_KNIGHT_CUBIC = 10056;
|
||||
public static final int SKILL_GUARDIAN_CUBIC = 10093;
|
||||
|
||||
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;
|
||||
}
|
||||
case AVENGING_CUBIC:
|
||||
{
|
||||
_skills.add(SkillData.getInstance().getSkill(11292, level));
|
||||
_skills.add(SkillData.getInstance().getSkill(11293, level));
|
||||
_skills.add(SkillData.getInstance().getSkill(11294, level));
|
||||
break;
|
||||
}
|
||||
case KNIGHT_CUBIC:
|
||||
{
|
||||
_skills.add(SkillData.getInstance().getSkill(10056, level));
|
||||
doAction();
|
||||
break;
|
||||
}
|
||||
case FAIRY_CUBIC:
|
||||
{
|
||||
_skills.add(SkillData.getInstance().getSkill(11807, level));
|
||||
doAction();
|
||||
break;
|
||||
}
|
||||
case BUFF_CUBIC:
|
||||
{
|
||||
_skills.add(SkillData.getInstance().getSkill(10082, level));
|
||||
_skills.add(SkillData.getInstance().getSkill(10083, level));
|
||||
_skills.add(SkillData.getInstance().getSkill(10084, level));
|
||||
_skills.add(SkillData.getInstance().getSkill(10089, level));
|
||||
doAction();
|
||||
break;
|
||||
}
|
||||
case MIND_CUBIC: // NOT USED
|
||||
{
|
||||
_skills.add(SkillData.getInstance().getSkill(10084, level));
|
||||
_skills.add(SkillData.getInstance().getSkill(10089, level));
|
||||
doAction();
|
||||
break;
|
||||
}
|
||||
case PHANTOM_CUBIC:
|
||||
{
|
||||
_skills.add(SkillData.getInstance().getSkill(10085, level));
|
||||
break;
|
||||
}
|
||||
case HEX_CUBIC:
|
||||
{
|
||||
_skills.add(SkillData.getInstance().getSkill(10086, level));
|
||||
break;
|
||||
}
|
||||
case GUARDIAN_CUBIC:
|
||||
{
|
||||
_skills.add(SkillData.getInstance().getSkill(10093, level));
|
||||
doAction();
|
||||
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:
|
||||
case AVENGING_CUBIC:
|
||||
case PHANTOM_CUBIC:
|
||||
case HEX_CUBIC:
|
||||
{
|
||||
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new CubicAction(this, _cubicSkillChance), 0, _cubicDelay);
|
||||
break;
|
||||
}
|
||||
case LIFE_CUBIC:
|
||||
case FAIRY_CUBIC:
|
||||
case BUFF_CUBIC:
|
||||
case MIND_CUBIC:
|
||||
{
|
||||
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new CubicHeal(this), 0, _cubicDelay);
|
||||
break;
|
||||
}
|
||||
case KNIGHT_CUBIC:
|
||||
case GUARDIAN_CUBIC:
|
||||
{
|
||||
_actionTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new CubicBuff(this, _cubicSkillChance), 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;
|
||||
final L2Object ownerTarget = _owner.getTarget();
|
||||
if (ownerTarget == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// TvT event targeting
|
||||
if (TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(_owner.getObjectId()))
|
||||
{
|
||||
final TvTEventTeam enemyTeam = TvTEvent.getParticipantEnemyTeam(_owner.getObjectId());
|
||||
|
||||
if (ownerTarget.getActingPlayer() != null)
|
||||
{
|
||||
final L2PcInstance target = ownerTarget.getActingPlayer();
|
||||
if (enemyTeam.containsPlayer(target.getObjectId()) && !(target.isDead()))
|
||||
{
|
||||
_target = (L2Character) ownerTarget;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Duel targeting
|
||||
if (_owner.isInDuel())
|
||||
{
|
||||
final L2PcInstance PlayerA = DuelManager.getInstance().getDuel(_owner.getDuelId()).getTeamLeaderA();
|
||||
final L2PcInstance PlayerB = DuelManager.getInstance().getDuel(_owner.getDuelId()).getTeamLeaderB();
|
||||
|
||||
if (DuelManager.getInstance().getDuel(_owner.getDuelId()).isPartyDuel())
|
||||
{
|
||||
final L2Party partyA = PlayerA.getParty();
|
||||
final 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.isPlayable())
|
||||
{
|
||||
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
|
||||
final L2Summon pet = _owner.getPet();
|
||||
if (ownerTarget.isCharacter() && (ownerTarget != pet) && !_owner.hasServitor(ownerTarget.getObjectId()) && (ownerTarget != _owner))
|
||||
{
|
||||
// target mob which has aggro on you or your summon
|
||||
if (ownerTarget.isAttackable())
|
||||
{
|
||||
final L2Attackable attackable = (L2Attackable) ownerTarget;
|
||||
if (attackable.isInAggroList(_owner) && !attackable.isDead())
|
||||
{
|
||||
_target = (L2Character) ownerTarget;
|
||||
return;
|
||||
}
|
||||
if (_owner.hasSummon())
|
||||
{
|
||||
if (attackable.isInAggroList(pet) && !attackable.isDead())
|
||||
{
|
||||
_target = (L2Character) ownerTarget;
|
||||
return;
|
||||
}
|
||||
for (L2Summon servitor : _owner.getServitors().values())
|
||||
{
|
||||
if (attackable.isInAggroList(servitor) && !attackable.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())
|
||||
{
|
||||
final byte shld = Formulas.calcShldUse(_owner, target, skill);
|
||||
final boolean acted = Formulas.calcCubicSkillSuccess(this, target, skill, shld);
|
||||
if (!acted)
|
||||
{
|
||||
_owner.sendPacket(SystemMessageId.YOUR_ATTACK_HAS_FAILED);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply effects
|
||||
skill.applyEffects(_owner, 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() && (_owner.getDuelId() == target.getActingPlayer().getDuelId()))
|
||||
{
|
||||
DuelManager.getInstance().onBuff(target.getActingPlayer(), skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param skill
|
||||
* @param targets
|
||||
*/
|
||||
public void useCubicMdam(Skill skill, L2Object[] targets)
|
||||
{
|
||||
for (L2Character target : (L2Character[]) targets)
|
||||
{
|
||||
if (target == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
if (target.isPlayer())
|
||||
{
|
||||
target.stopFakeDeath(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean mcrit = Formulas.calcMCrit(_owner.getMCriticalHit(target, skill));
|
||||
final byte shld = Formulas.calcShldUse(_owner, target, skill);
|
||||
int damage = (int) Formulas.calcMagicDam(this, 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
|
||||
{
|
||||
_owner.sendDamageMessage(target, damage, mcrit, false, false);
|
||||
target.reduceCurrentHp(damage, _owner, skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void useCubicDrain(Skill skill, L2Object[] targets)
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("L2SkillDrain: useCubicSkill()");
|
||||
}
|
||||
|
||||
for (L2Character target : (L2Character[]) targets)
|
||||
{
|
||||
if (target.isAlikeDead())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final boolean mcrit = Formulas.calcMCrit(_owner.getMCriticalHit(target, skill));
|
||||
final byte shld = Formulas.calcShldUse(_owner, target, skill);
|
||||
|
||||
final int damage = (int) Formulas.calcMagicDam(this, target, skill, mcrit, shld);
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("L2SkillDrain: useCubicSkill() -> damage = " + damage);
|
||||
}
|
||||
|
||||
// TODO: Unhardcode fixed value
|
||||
final double hpAdd = (0.4 * damage);
|
||||
final L2PcInstance owner = _owner;
|
||||
final 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, _owner, 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;
|
||||
}
|
||||
|
||||
final byte shld = Formulas.calcShldUse(_owner, target, skill);
|
||||
|
||||
if (skill.hasEffectType(L2EffectType.STUN, L2EffectType.PARALYZE, L2EffectType.ROOT))
|
||||
{
|
||||
if (Formulas.calcCubicSkillSuccess(this, target, skill, shld))
|
||||
{
|
||||
// Apply effects
|
||||
skill.applyEffects(_owner, 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() && (_owner.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, _owner, (int) ((150 * skill.getPower()) / (target.getLevel() + 7)));
|
||||
}
|
||||
|
||||
// Apply effects
|
||||
skill.applyEffects(_owner, 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
|
||||
final 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final L2Summon pet = partyMember.getPet();
|
||||
if (pet != null)
|
||||
{
|
||||
if (pet.isDead() || !isInCubicRange(_owner, pet))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// member's pet is in cubic casting range, check if he need heal and if he have
|
||||
// the lowest HP
|
||||
if (pet.getCurrentHp() < pet.getMaxHp())
|
||||
{
|
||||
if (percentleft > (pet.getCurrentHp() / pet.getMaxHp()))
|
||||
{
|
||||
percentleft = (pet.getCurrentHp() / pet.getMaxHp());
|
||||
target = pet;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (L2Summon s : partyMember.getServitors().values())
|
||||
{
|
||||
if (s.isDead() || !isInCubicRange(_owner, s))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// member's pet is in cubic casting range, check if he need heal and if he have
|
||||
// the lowest HP
|
||||
if (s.getCurrentHp() < s.getMaxHp())
|
||||
{
|
||||
if (percentleft > (s.getCurrentHp() / s.getMaxHp()))
|
||||
{
|
||||
percentleft = (s.getCurrentHp() / s.getMaxHp());
|
||||
target = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_owner.getCurrentHp() < _owner.getMaxHp())
|
||||
{
|
||||
percentleft = (_owner.getCurrentHp() / _owner.getMaxHp());
|
||||
target = _owner;
|
||||
}
|
||||
for (L2Summon summon : _owner.getServitors().values())
|
||||
{
|
||||
if (!summon.isDead() && (summon.getCurrentHp() < summon.getMaxHp()) && (percentleft > (summon.getCurrentHp() / summon.getMaxHp())) && isInCubicRange(_owner, summon))
|
||||
{
|
||||
target = summon;
|
||||
}
|
||||
}
|
||||
final L2Summon pet = _owner.getPet();
|
||||
if (pet != null)
|
||||
{
|
||||
if (!pet.isDead() && (pet.getCurrentHp() < pet.getMaxHp()) && (percentleft > (pet.getCurrentHp() / pet.getMaxHp())) && isInCubicRange(_owner, pet))
|
||||
{
|
||||
target = _owner.getPet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_target = target;
|
||||
}
|
||||
|
||||
public boolean givenByOther()
|
||||
{
|
||||
return _givenByOther;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.datatables.SkillData;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Decoy;
|
||||
import com.l2jmobius.gameserver.model.actor.knownlist.DecoyKnownList;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.taskmanager.DecayTaskManager;
|
||||
|
||||
public class L2DecoyInstance extends L2Decoy
|
||||
{
|
||||
private int _totalLifeTime;
|
||||
private int _timeRemaining;
|
||||
private Future<?> _DecoyLifeTask;
|
||||
private Future<?> _HateSpam;
|
||||
|
||||
/**
|
||||
* Creates a decoy.
|
||||
* @param template the decoy NPC template
|
||||
* @param owner the owner
|
||||
* @param totalLifeTime the total life time
|
||||
*/
|
||||
public L2DecoyInstance(L2NpcTemplate template, L2PcInstance owner, int totalLifeTime)
|
||||
{
|
||||
super(template, owner);
|
||||
setInstanceType(InstanceType.L2DecoyInstance);
|
||||
_totalLifeTime = totalLifeTime;
|
||||
_timeRemaining = _totalLifeTime;
|
||||
final 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);
|
||||
final 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,230 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.ai.L2CharacterAI;
|
||||
import com.l2jmobius.gameserver.ai.L2FortSiegeGuardAI;
|
||||
import com.l2jmobius.gameserver.ai.L2SiegeGuardAI;
|
||||
import com.l2jmobius.gameserver.ai.L2SpecialSiegeGuardAI;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FortManager;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Playable;
|
||||
import com.l2jmobius.gameserver.model.actor.knownlist.DefenderKnownList;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
import com.l2jmobius.gameserver.model.entity.Fort;
|
||||
import com.l2jmobius.gameserver.model.entity.clanhall.SiegableHall;
|
||||
import com.l2jmobius.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
|
||||
|
||||
/**
|
||||
* Creates a defender.
|
||||
* @param template the defender NPC template
|
||||
*/
|
||||
public L2DefenderInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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(this);
|
||||
}
|
||||
else if (getCastle(10000) != null)
|
||||
{
|
||||
return new L2SiegeGuardAI(this);
|
||||
}
|
||||
return new L2SpecialSiegeGuardAI(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
final 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()))
|
||||
{
|
||||
final 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))
|
||||
{
|
||||
final 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()))
|
||||
{
|
||||
final 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,791 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.L2CharacterAI;
|
||||
import com.l2jmobius.gameserver.ai.L2DoorAI;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.enums.Race;
|
||||
import com.l2jmobius.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.ClanHallManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FortManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.InstanceManager;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Playable;
|
||||
import com.l2jmobius.gameserver.model.actor.knownlist.DoorKnownList;
|
||||
import com.l2jmobius.gameserver.model.actor.stat.DoorStat;
|
||||
import com.l2jmobius.gameserver.model.actor.status.DoorStatus;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2DoorTemplate;
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
import com.l2jmobius.gameserver.model.entity.ClanHall;
|
||||
import com.l2jmobius.gameserver.model.entity.Fort;
|
||||
import com.l2jmobius.gameserver.model.entity.Instance;
|
||||
import com.l2jmobius.gameserver.model.entity.clanhall.SiegableHall;
|
||||
import com.l2jmobius.gameserver.model.items.L2Weapon;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.DoorStatusUpdate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.OnEventTrigger;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.StaticObject;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* Creates a door.
|
||||
* @param template the door template
|
||||
*/
|
||||
public L2DoorInstance(L2DoorTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2DoorInstance);
|
||||
setIsInvul(false);
|
||||
setLethalable(false);
|
||||
_open = template.isOpenByDefault();
|
||||
_isAttackableDoor = template.isAttackable();
|
||||
_isTargetable = template.isTargetable();
|
||||
|
||||
if (getGroupName() != null)
|
||||
{
|
||||
DoorData.addDoorGroup(getGroupName(), getId());
|
||||
}
|
||||
|
||||
if (isOpenableByTime())
|
||||
{
|
||||
startTimerOpen();
|
||||
}
|
||||
|
||||
final int clanhallId = template.getClanHallId();
|
||||
if (clanhallId > 0)
|
||||
{
|
||||
final ClanHall hall = ClanHallManager.getAllClanHalls().get(clanhallId);
|
||||
if (hall != null)
|
||||
{
|
||||
setClanHall(hall);
|
||||
hall.getDoors().add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected L2CharacterAI initAI()
|
||||
{
|
||||
return new L2DoorAI(this);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
final 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()
|
||||
{
|
||||
final 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;
|
||||
}
|
||||
|
||||
final L2PcInstance actingPlayer = attacker.getActingPlayer();
|
||||
|
||||
if (getClanHall() != null)
|
||||
{
|
||||
final 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)
|
||||
final boolean isCastle = ((getCastle() != null) && (getCastle().getResidenceId() > 0) && getCastle().getZone().isActive());
|
||||
final boolean isFort = ((getFort() != null) && (getFort().getResidenceId() > 0) && getFort().getZone().isActive());
|
||||
|
||||
if (isFort)
|
||||
{
|
||||
final L2Clan clan = actingPlayer.getClan();
|
||||
if ((clan != null) && (clan == getFort().getOwnerClan()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (isCastle)
|
||||
{
|
||||
final L2Clan clan = actingPlayer.getClan();
|
||||
if ((clan != null) && (clan.getId() == getCastle().getOwnerId()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return (isCastle || isFort);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAbnormalVisualEffects()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
final Collection<L2PcInstance> knownPlayers = getKnownList().getKnownPlayers().values();
|
||||
if ((knownPlayers == null) || knownPlayers.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final StaticObject su = new StaticObject(this, false);
|
||||
final StaticObject targetableSu = new StaticObject(this, true);
|
||||
final DoorStatusUpdate dsu = new DoorStatusUpdate(this);
|
||||
OnEventTrigger oe = null;
|
||||
if (getEmitter() > 0)
|
||||
{
|
||||
oe = new OnEventTrigger(getEmitter(), 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
|
||||
final 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)
|
||||
{
|
||||
final Set<Integer> set = DoorData.getDoorsByGroup(groupName);
|
||||
L2DoorInstance first = null;
|
||||
for (Integer id : set)
|
||||
{
|
||||
final 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)
|
||||
{
|
||||
final 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 List<L2DefenderInstance> getKnownDefenders()
|
||||
{
|
||||
final List<L2DefenderInstance> result = new ArrayList<>();
|
||||
for (L2Object obj : getKnownList().getKnownObjects().values())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
final boolean isFort = ((getFort() != null) && (getFort().getResidenceId() > 0) && getFort().getSiege().isInProgress());
|
||||
final boolean isCastle = ((getCastle() != null) && (getCastle().getResidenceId() > 0) && getCastle().getSiege().isInProgress());
|
||||
final 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 moveToLocation(int x, int y, int z, int offset)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopMove(Location loc)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAttack(L2Character target)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCast(Skill skill)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendInfo(L2PcInstance activeChar)
|
||||
{
|
||||
if (isVisibleFor(activeChar))
|
||||
{
|
||||
if (getEmitter() > 0)
|
||||
{
|
||||
activeChar.sendPacket(new OnEventTrigger(getEmitter(), 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 DoorData.getInstance().getDoor(doorId);
|
||||
}
|
||||
|
||||
final 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;
|
||||
}
|
||||
final 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()
|
||||
{
|
||||
final 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,169 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jmobius.gameserver.data.sql.impl.TeleportLocationTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.L2TeleportLocation;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
|
||||
public class L2DoormenInstance extends L2NpcInstance
|
||||
{
|
||||
/**
|
||||
* Creates a doorman.
|
||||
* @param template the doorman NPC template
|
||||
*/
|
||||
public L2DoormenInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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(), "html/doormen/" + getTemplate().getId() + "-no.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "html/doormen/" + getTemplate().getId() + ".htm");
|
||||
}
|
||||
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
protected void openDoors(L2PcInstance player, String command)
|
||||
{
|
||||
final StringTokenizer st = new StringTokenizer(command.substring(10), ", ");
|
||||
st.nextToken();
|
||||
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
DoorData.getInstance().getDoor(Integer.parseInt(st.nextToken())).openMe();
|
||||
}
|
||||
}
|
||||
|
||||
protected void closeDoors(L2PcInstance player, String command)
|
||||
{
|
||||
final StringTokenizer st = new StringTokenizer(command.substring(11), ", ");
|
||||
st.nextToken();
|
||||
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
DoorData.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(), "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());
|
||||
final 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,72 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
|
||||
public class L2EffectPointInstance extends L2Npc
|
||||
{
|
||||
private final L2PcInstance _owner;
|
||||
|
||||
/**
|
||||
* Creates an effect point.
|
||||
* @param template the effect point NPC template
|
||||
* @param owner the owner
|
||||
*/
|
||||
public L2EffectPointInstance(L2NpcTemplate template, L2Character owner)
|
||||
{
|
||||
super(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)
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActionShift(L2PcInstance player)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* Creates an event monster.
|
||||
* @param template the event monster NPC template
|
||||
*/
|
||||
public L2EventMonsterInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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,35 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.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(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2FeedableBeastInstance);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SkillTreesData;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.FishingChampionshipManager;
|
||||
import com.l2jmobius.gameserver.model.L2SkillLearn;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.base.AcquireSkillType;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExAcquirableSkillListByClass;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
public final class L2FishermanInstance extends L2MerchantInstance
|
||||
{
|
||||
/**
|
||||
* Creates a fisherman.
|
||||
* @param template the fisherman NPC template
|
||||
*/
|
||||
public L2FishermanInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2FishermanInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "html/fisherman/" + pom + ".htm";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
if (command.equalsIgnoreCase("FishSkillList"))
|
||||
{
|
||||
showFishSkillList(player);
|
||||
}
|
||||
else if (command.startsWith("FishingChampionship"))
|
||||
{
|
||||
if (Config.ALT_FISH_CHAMPIONSHIP_ENABLED)
|
||||
{
|
||||
FishingChampionshipManager.getInstance().showChampScreen(player, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendHtml(player, this, "no_fish_event001.htm");
|
||||
}
|
||||
}
|
||||
else if (command.startsWith("FishingReward"))
|
||||
{
|
||||
if (Config.ALT_FISH_CHAMPIONSHIP_ENABLED)
|
||||
{
|
||||
if (FishingChampionshipManager.getInstance().isWinner(player.getName()))
|
||||
{
|
||||
FishingChampionshipManager.getInstance().getReward(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendHtml(player, this, "no_fish_event_reward001.htm");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sendHtml(player, this, "no_fish_event001.htm");
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
final 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));
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendHtml(L2PcInstance player, L2Npc npc, String htmlName)
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(npc.getObjectId());
|
||||
html.setFile(player.getHtmlPrefix(), "html/fisherman/championship/" + htmlName);
|
||||
player.sendPacket(html);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Tower;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* Creates a flame tower.
|
||||
* @param template the flame tower NPC template
|
||||
*/
|
||||
public L2FlameTowerInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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,55 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
|
||||
public final class L2FlyTerrainObjectInstance extends L2Npc
|
||||
{
|
||||
/**
|
||||
* Creates a fly terrain object.
|
||||
* @param template the fly terrain object
|
||||
*/
|
||||
public L2FlyTerrainObjectInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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,201 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.FortSiegeManager;
|
||||
import com.l2jmobius.gameserver.model.FortSiegeSpawn;
|
||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcSay;
|
||||
|
||||
public class L2FortCommanderInstance extends L2DefenderInstance
|
||||
{
|
||||
private boolean _canTalk;
|
||||
|
||||
/**
|
||||
* Creates a fort commander.
|
||||
* @param template the fort commander NPC template
|
||||
*/
|
||||
public L2FortCommanderInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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;
|
||||
}
|
||||
|
||||
final 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)
|
||||
{
|
||||
final L2Spawn spawn = getSpawn();
|
||||
if ((spawn != null) && canTalk())
|
||||
{
|
||||
final List<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)
|
||||
{
|
||||
final NpcSay ns = new NpcSay(getObjectId(), ChatType.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,104 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
|
||||
public class L2FortDoormenInstance extends L2DoormenInstance
|
||||
{
|
||||
/**
|
||||
* Creates a fort doorman.
|
||||
* @param template the fort doorman NPC template
|
||||
*/
|
||||
public L2FortDoormenInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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(), "html/doormen/" + getTemplate().getId() + "-no.htm");
|
||||
}
|
||||
else if (isUnderSiege())
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "html/doormen/" + getTemplate().getId() + "-busy.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "html/doormen/" + getTemplate().getId() + ".htm");
|
||||
}
|
||||
|
||||
html.replace("%objectId%", String.valueOf(getObjectId()));
|
||||
player.sendPacket(html);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void openDoors(L2PcInstance player, String command)
|
||||
{
|
||||
final 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)
|
||||
{
|
||||
final 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,240 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.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
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a fort logistics.
|
||||
* @param template the fort logistics NPC template
|
||||
*/
|
||||
public L2FortLogisticsInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2FortLogisticsInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
if (player.getLastFolkNPC().getObjectId() != getObjectId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final StringTokenizer st = new StringTokenizer(command, " ");
|
||||
final String actualCommand = st.nextToken(); // Get actual command
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
if (actualCommand.equalsIgnoreCase("rewards"))
|
||||
{
|
||||
if (isMyLord(player))
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "html/fortress/logistics-rewards.htm");
|
||||
html.replace("%bloodoath%", String.valueOf(player.getClan().getBloodOathCount()));
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "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(), "html/fortress/logistics-blood.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "html/fortress/logistics-noblood.htm");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "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(), "html/fortress/logistics-supplylvl.htm");
|
||||
html.replace("%supplylvl%", String.valueOf(getFort().getSupplyLvL()));
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "html/fortress/logistics-noprivs.htm");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "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(), "html/fortress/logistics-siege.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
final int level = getFort().getSupplyLvL();
|
||||
if (level > 0)
|
||||
{
|
||||
// spawn box
|
||||
final L2NpcTemplate boxTemplate = NpcData.getInstance().getTemplate(SUPPLY_BOX_IDS[level - 1]);
|
||||
final L2MonsterInstance box = new L2MonsterInstance(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(), "html/fortress/logistics-supply.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "html/fortress/logistics-nosupply.htm");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "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 = "html/fortress/logistics.htm";
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = "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 "html/fortress/" + pom + ".htm";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRandomAnimation()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.knownlist.FriendlyMobKnownList;
|
||||
import com.l2jmobius.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
|
||||
{
|
||||
/**
|
||||
* Creates a friendly monster.
|
||||
* @param template the friendly monster NPC template
|
||||
*/
|
||||
public L2FriendlyMobInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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).getReputation() < 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAggressive()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.entity.Hero;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* Creates a grand boss.
|
||||
* @param template the grand boss NPC template
|
||||
*/
|
||||
public L2GrandBossInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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())
|
||||
{
|
||||
member.setRaidPoints(member.getRaidPoints() + ((getLevel() / 2) + Rnd.get(-5, 5)));
|
||||
if (member.isNoble())
|
||||
{
|
||||
Hero.getInstance().setRBkilled(member.getObjectId(), getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setRaidPoints(player.getRaidPoints() + ((getLevel() / 2) + Rnd.get(-5, 5)));
|
||||
if (player.isNoble())
|
||||
{
|
||||
Hero.getInstance().setRBkilled(player.getObjectId(), getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int 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,211 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.knownlist.GuardKnownList;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.EventType;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcFirstTalk;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jmobius.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());
|
||||
|
||||
/**
|
||||
* Creates a guard.
|
||||
* @param template the guard NPC template
|
||||
*/
|
||||
public L2GuardInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2GuardInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final GuardKnownList getKnownList()
|
||||
{
|
||||
return (GuardKnownList) super.getKnownList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initKnownList()
|
||||
{
|
||||
setKnownList(new GuardKnownList(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return True if the attacker is a L2MonsterInstance.
|
||||
*/
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_GUARDS_ENABLED && attacker.isPlayer() && ((attacker.getActingPlayer().isGood() && getTemplate().isClan(Config.FACTION_EVIL_TEAM_NAME)) || (attacker.getActingPlayer().isEvil() && getTemplate().isClan(Config.FACTION_GOOD_TEAM_NAME))))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
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.
|
||||
final 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>html/guard/12006.htm</B> (npcId-page number)</li>
|
||||
* <li>if page number > 0 : <B>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 "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;
|
||||
}
|
||||
|
||||
if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_GUARDS_ENABLED && ((player.isGood() && getTemplate().isClan(Config.FACTION_EVIL_TEAM_NAME)) || (player.isEvil() && getTemplate().isClan(Config.FACTION_GOOD_TEAM_NAME))))
|
||||
{
|
||||
interact = false;
|
||||
// TODO: Fix normal targeting
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
|
||||
}
|
||||
|
||||
// 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 (isInAggroList(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,109 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.data.xml.impl.BuyListData;
|
||||
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable;
|
||||
import com.l2jmobius.gameserver.datatables.MerchantPriceConfigTable.MerchantPriceConfig;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.BuyList;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* Creates a merchant,
|
||||
* @param template the merchant NPC template
|
||||
*/
|
||||
public L2MerchantInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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 "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,228 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.knownlist.MonsterKnownList;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.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
|
||||
{
|
||||
private static final int MONSTER_MAINTENANCE_INTERVAL = 1000;
|
||||
|
||||
protected boolean _enableMinions = true;
|
||||
|
||||
private L2MonsterInstance _master = null;
|
||||
private volatile MinionList _minionList = null;
|
||||
|
||||
protected ScheduledFuture<?> _maintenanceTask = null;
|
||||
|
||||
/**
|
||||
* Creates a monster.
|
||||
* @param template the monster NPC template
|
||||
*/
|
||||
public L2MonsterInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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();
|
||||
}
|
||||
|
||||
@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,154 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SkillTreesData;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.L2SkillLearn;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.status.FolkStatus;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.base.AcquireSkillType;
|
||||
import com.l2jmobius.gameserver.model.base.ClassId;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExAcquirableSkillListByClass;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.util.StringUtil;
|
||||
|
||||
public class L2NpcInstance extends L2Npc
|
||||
{
|
||||
/**
|
||||
* Creates a NPC.
|
||||
* @param template the NPC template
|
||||
*/
|
||||
public L2NpcInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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)
|
||||
{
|
||||
final 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)
|
||||
{
|
||||
final 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)
|
||||
{
|
||||
final 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,73 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.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
|
||||
{
|
||||
/**
|
||||
* Creates an observation.
|
||||
* @param template the observation NPC template
|
||||
*/
|
||||
public L2ObservationInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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 = "html/observation/" + getId() + "-Oracle.htm";
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = "html/observation/" + getId() + "-Oracle-" + val + ".htm";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (val == 0)
|
||||
{
|
||||
filename = "html/observation/" + getId() + ".htm";
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = "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,54 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.olympiad.Olympiad;
|
||||
|
||||
/**
|
||||
* Olympiad Npc's Instance
|
||||
* @author godson
|
||||
*/
|
||||
public class L2OlympiadManagerInstance extends L2Npc
|
||||
{
|
||||
/**
|
||||
* Creates an olympiad manager.
|
||||
* @param template the olympiad manager NPC template
|
||||
*/
|
||||
public L2OlympiadManagerInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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,207 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jmobius.gameserver.util.Evolve;
|
||||
|
||||
public class L2PetManagerInstance extends L2MerchantInstance
|
||||
{
|
||||
/**
|
||||
* Creates a pet manager.
|
||||
* @param template the pet manager NPC template.
|
||||
*/
|
||||
public L2PetManagerInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2PetManagerInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "html/petmanager/" + pom + ".htm";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showChatWindow(L2PcInstance player)
|
||||
{
|
||||
String filename = "html/petmanager/" + getId() + ".htm";
|
||||
if ((getId() == 36478) && player.hasSummon())
|
||||
{
|
||||
filename = "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"))
|
||||
{
|
||||
final String[] params = command.split(" ");
|
||||
final 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"))
|
||||
{
|
||||
final String[] params = command.split(" ");
|
||||
final 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(), "html/petmanager/evolve_no.htm");
|
||||
player.sendPacket(html);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (command.startsWith("restore"))
|
||||
{
|
||||
final String[] params = command.split(" ");
|
||||
final 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(), "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(), "html/petmanager/" + getId() + ".htm");
|
||||
player.sendPacket(html);
|
||||
}
|
||||
else
|
||||
{
|
||||
html.setFile(player.getHtmlPrefix(), "html/petmanager/exchange_no.htm");
|
||||
player.sendPacket(html);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.attackable.OnAttackableAttack;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.attackable.OnAttackableKill;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* Creates a quest guard.
|
||||
* @param template the quest guard NPC template
|
||||
*/
|
||||
public L2QuestGuardInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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().notifyEventAsync(new OnAttackableKill(null, this, false), this);
|
||||
}
|
||||
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,552 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.gameserver.MonsterRace;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.idfactory.IdFactory;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.knownlist.RaceManagerKnownList;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.InventoryUpdate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.L2GameServerPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MonRaceInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.PlaySound;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.util.Broadcast;
|
||||
|
||||
public class L2RaceManagerInstance extends L2Npc
|
||||
{
|
||||
public static final int LANES = 8;
|
||||
public static final int WINDOW_START = 0;
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a race manager.
|
||||
* @param template the race manager NPC template
|
||||
*/
|
||||
public L2RaceManagerInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2RaceManagerInstance);
|
||||
if (_notInitialized)
|
||||
{
|
||||
_notInitialized = false;
|
||||
|
||||
_managers = new ArrayList<>();
|
||||
|
||||
final 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)
|
||||
{
|
||||
final 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()
|
||||
{
|
||||
final MonsterRace race = MonsterRace.getInstance();
|
||||
if (_state == STARTING_RACE)
|
||||
{
|
||||
// state++;
|
||||
final PlaySound SRace = new PlaySound(1, "S_Race", 0, 0, 0, 0, 0);
|
||||
broadcast(SRace);
|
||||
final 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;
|
||||
}
|
||||
final 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++)
|
||||
{
|
||||
final 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)
|
||||
{
|
||||
final 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++)
|
||||
{
|
||||
final 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;
|
||||
}
|
||||
final 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++)
|
||||
{
|
||||
final 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";
|
||||
final int price = _cost[player.getRace(1) - 1];
|
||||
html.replace(search, "" + price);
|
||||
search = "0tax";
|
||||
final int tax = 0;
|
||||
html.replace(search, "" + tax);
|
||||
search = "0total";
|
||||
final int total = price + tax;
|
||||
html.replace(search, "" + total);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((player.getRace(0) == 0) || (player.getRace(1) == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
final int ticket = player.getRace(0);
|
||||
final 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);
|
||||
final 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);
|
||||
final InventoryUpdate iu = new InventoryUpdate();
|
||||
iu.addItem(item);
|
||||
final 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,171 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.RaidBossSpawnManager;
|
||||
import com.l2jmobius.gameserver.model.L2Spawn;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.entity.Hero;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* Creates a raid boss.
|
||||
* @param template the raid boss template
|
||||
*/
|
||||
public L2RaidBossInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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())
|
||||
{
|
||||
member.setRaidPoints(member.getRaidPoints() + ((getLevel() / 2) + Rnd.get(-5, 5)));
|
||||
if (member.isNoble())
|
||||
{
|
||||
Hero.getInstance().setRBkilled(member.getObjectId(), getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.setRaidPoints(player.getRaidPoints() + ((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 int 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,555 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.FourSepulchersManager;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* @param template
|
||||
*/
|
||||
public L2SepulcherMonsterInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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)
|
||||
{
|
||||
final String questId = "620_FourGoblets";
|
||||
int cupId = 0;
|
||||
final 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;
|
||||
}
|
||||
}
|
||||
|
||||
final L2PcInstance player = killer.getActingPlayer();
|
||||
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getParty() != null)
|
||||
{
|
||||
for (L2PcInstance mem : player.getParty().getMembers())
|
||||
{
|
||||
final 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
|
||||
{
|
||||
final 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(), ChatType.NPC_GENERAL, 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(), ChatType.NPC_GENERAL, 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,459 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.DoorData;
|
||||
import com.l2jmobius.gameserver.enums.ChatType;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.FourSepulchersManager;
|
||||
import com.l2jmobius.gameserver.model.L2World;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.EventType;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcFirstTalk;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.CreatureSay;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
import com.l2jmobius.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 = "html/SepulcherNpc/";
|
||||
private static final int HALLS_KEY = 7260;
|
||||
|
||||
/**
|
||||
* Creates a sepulcher.
|
||||
* @param template the sepulcher NPC template
|
||||
*/
|
||||
public L2SepulcherNpcInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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
|
||||
final 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)
|
||||
{
|
||||
final 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(), "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"))
|
||||
{
|
||||
final 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)
|
||||
{
|
||||
final int doorId = FourSepulchersManager.getInstance().getHallGateKeepers().get(npcId);
|
||||
final DoorData _doorTable = DoorData.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 DoorData _DoorTable = DoorData.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, ChatType.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(), "html/SepulcherNpc/" + file);
|
||||
html.replace("%npcname%", getName());
|
||||
player.sendPacket(html);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,539 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.commons.database.pool.impl.ConnectionFactory;
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.CharSummonTable;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.SummonEffectsTable;
|
||||
import com.l2jmobius.gameserver.datatables.SkillData;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.holders.ItemHolder;
|
||||
import com.l2jmobius.gameserver.model.skills.AbnormalType;
|
||||
import com.l2jmobius.gameserver.model.skills.BuffInfo;
|
||||
import com.l2jmobius.gameserver.model.skills.EffectScope;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.stats.Stats;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SetSummonRemainTime;
|
||||
import com.l2jmobius.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(L2NpcTemplate template, L2PcInstance owner)
|
||||
{
|
||||
super(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(), getObjectId());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doPickupItem(L2Object object)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRestoreSummon(boolean val)
|
||||
{
|
||||
_restoreSummon = val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void stopSkillEffects(boolean removed, int skillId)
|
||||
{
|
||||
super.stopSkillEffects(removed, skillId);
|
||||
SummonEffectsTable.getInstance().removeServitorEffects(getOwner(), getReferenceSkill(), skillId);
|
||||
}
|
||||
|
||||
@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
|
||||
SummonEffectsTable.getInstance().clearServitorEffects(getOwner(), getReferenceSkill());
|
||||
|
||||
try (Connection con = ConnectionFactory.getInstance().getConnection();
|
||||
PreparedStatement ps = con.prepareStatement(DELETE_SKILL_SAVE))
|
||||
{
|
||||
// Delete all current stored effects for summon to avoid dupe
|
||||
ps.setInt(1, getOwner().getObjectId());
|
||||
ps.setInt(2, getOwner().getClassIndex());
|
||||
ps.setInt(3, getReferenceSkill());
|
||||
ps.execute();
|
||||
|
||||
int buff_index = 0;
|
||||
|
||||
final List<Integer> storedSkills = new LinkedList<>();
|
||||
|
||||
// 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();
|
||||
|
||||
SummonEffectsTable.getInstance().addServitorEffect(getOwner(), getReferenceSkill(), 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 = ConnectionFactory.getInstance().getConnection())
|
||||
{
|
||||
if (!SummonEffectsTable.getInstance().containsSkill(getOwner(), getReferenceSkill()))
|
||||
{
|
||||
try (PreparedStatement ps = con.prepareStatement(RESTORE_SKILL_SAVE))
|
||||
{
|
||||
ps.setInt(1, getOwner().getObjectId());
|
||||
ps.setInt(2, getOwner().getClassIndex());
|
||||
ps.setInt(3, getReferenceSkill());
|
||||
try (ResultSet rs = ps.executeQuery())
|
||||
{
|
||||
while (rs.next())
|
||||
{
|
||||
final int effectCurTime = rs.getInt("remaining_time");
|
||||
|
||||
final Skill skill = SkillData.getInstance().getSkill(rs.getInt("skill_id"), rs.getInt("skill_level"));
|
||||
if (skill == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skill.hasEffects(EffectScope.GENERAL))
|
||||
{
|
||||
SummonEffectsTable.getInstance().addServitorEffect(getOwner(), getReferenceSkill(), 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
|
||||
{
|
||||
SummonEffectsTable.getInstance().applyServitorEffects(this, getOwner(), getReferenceSkill());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unSummon(L2PcInstance owner)
|
||||
{
|
||||
if (_summonLifeTask != null)
|
||||
{
|
||||
_summonLifeTask.cancel(false);
|
||||
}
|
||||
|
||||
super.unSummon(owner);
|
||||
|
||||
if (!_restoreSummon)
|
||||
{
|
||||
CharSummonTable.getInstance().removeServitor(owner, getObjectId());
|
||||
}
|
||||
}
|
||||
|
||||
@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()
|
||||
{
|
||||
final 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();
|
||||
|
||||
// Using same task to check if owner is in visible range
|
||||
if (calculateDistance(getOwner(), true, false) > 2000)
|
||||
{
|
||||
getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, getOwner());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMAtk(L2Character target, Skill skill)
|
||||
{
|
||||
return super.getMAtk(target, skill) + (getActingPlayer().getMAtk(target, skill) * (getActingPlayer().getServitorShareBonus(Stats.MAGIC_ATTACK) - 1.0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getMDef(L2Character target, Skill skill)
|
||||
{
|
||||
return super.getMDef(target, skill) + (getActingPlayer().getMDef(target, skill) * (getActingPlayer().getServitorShareBonus(Stats.MAGIC_DEFENCE) - 1.0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getPAtk(L2Character target)
|
||||
{
|
||||
return super.getPAtk(target) + (getActingPlayer().getPAtk(target) * (getActingPlayer().getServitorShareBonus(Stats.POWER_ATTACK) - 1.0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getPDef(L2Character target)
|
||||
{
|
||||
return super.getPDef(target) + (getActingPlayer().getPDef(target) * (getActingPlayer().getServitorShareBonus(Stats.POWER_DEFENCE) - 1.0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMAtkSpd()
|
||||
{
|
||||
return (int) (super.getMAtkSpd() + (getActingPlayer().getMAtkSpd() * (getActingPlayer().getServitorShareBonus(Stats.MAGIC_ATTACK_SPEED) - 1.0)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxHp()
|
||||
{
|
||||
return (int) (super.getMaxHp() + (getActingPlayer().getMaxHp() * (getActingPlayer().getServitorShareBonus(Stats.MAX_HP) - 1.0)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxMp()
|
||||
{
|
||||
return (int) (super.getMaxMp() + (getActingPlayer().getMaxMp() * (getActingPlayer().getServitorShareBonus(Stats.MAX_MP) - 1.0)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCriticalHit(L2Character target, Skill skill)
|
||||
{
|
||||
return (int) (super.getCriticalHit(target, skill) + ((getActingPlayer().getCriticalHit(target, skill)) * (getActingPlayer().getServitorShareBonus(Stats.CRITICAL_RATE) - 1.0)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getPAtkSpd()
|
||||
{
|
||||
return super.getPAtkSpd() + (getActingPlayer().getPAtkSpd() * (getActingPlayer().getServitorShareBonus(Stats.POWER_ATTACK_SPEED) - 1.0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxRecoverableHp()
|
||||
{
|
||||
return (int) calcStat(Stats.MAX_RECOVERABLE_HP, getMaxHp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxRecoverableMp()
|
||||
{
|
||||
return (int) calcStat(Stats.MAX_RECOVERABLE_MP, getMaxMp());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.L2ShuttleAI;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Vehicle;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jmobius.gameserver.model.shuttle.L2ShuttleData;
|
||||
import com.l2jmobius.gameserver.model.shuttle.L2ShuttleStop;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.shuttle.ExShuttleGetOff;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.shuttle.ExShuttleGetOn;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.shuttle.ExShuttleInfo;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class L2ShuttleInstance extends L2Vehicle
|
||||
{
|
||||
private L2ShuttleData _shuttleData;
|
||||
|
||||
public L2ShuttleInstance(L2CharTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2ShuttleInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public L2ShuttleAI initAI()
|
||||
{
|
||||
return new L2ShuttleAI(this);
|
||||
}
|
||||
|
||||
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,206 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.CHSiegeManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FortSiegeManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.SiegeManager;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2SiegeClan;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.status.SiegeFlagStatus;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.entity.Siegable;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
public class L2SiegeFlagInstance extends L2Npc
|
||||
{
|
||||
private final L2Clan _clan;
|
||||
private Siegable _siege;
|
||||
private final boolean _isAdvanced;
|
||||
private boolean _canTalk;
|
||||
|
||||
/**
|
||||
* Creates a siege flag.
|
||||
* @param player
|
||||
* @param template
|
||||
* @param advanced
|
||||
* @param outPost
|
||||
*/
|
||||
public L2SiegeFlagInstance(L2PcInstance player, L2NpcTemplate template, boolean advanced, boolean outPost)
|
||||
{
|
||||
super(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.");
|
||||
}
|
||||
|
||||
final 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() || isHpBlocked());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutoAttackable(L2Character attacker)
|
||||
{
|
||||
return !(isInvul() || isHpBlocked());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doDie(L2Character killer)
|
||||
{
|
||||
if (!super.doDie(killer))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ((_siege != null) && (_clan != null))
|
||||
{
|
||||
final 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,225 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.L2CharacterAI;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.knownlist.StaticObjectKnownList;
|
||||
import com.l2jmobius.gameserver.model.actor.stat.StaticObjStat;
|
||||
import com.l2jmobius.gameserver.model.actor.status.StaticObjStatus;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jmobius.gameserver.model.items.L2Weapon;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ShowTownMap;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* Creates a static object.
|
||||
* @param template the static object
|
||||
* @param staticId the static ID
|
||||
*/
|
||||
public L2StaticObjectInstance(L2CharTemplate template, int staticId)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2StaticObjectInstance);
|
||||
_staticObjectId = staticId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected L2CharacterAI initAI()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the static object ID.
|
||||
* @return the static object ID
|
||||
*/
|
||||
@Override
|
||||
public int getId()
|
||||
{
|
||||
return _staticObjectId;
|
||||
}
|
||||
|
||||
@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 updateAbnormalVisualEffects()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendInfo(L2PcInstance activeChar)
|
||||
{
|
||||
activeChar.sendPacket(new StaticObject(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveToLocation(int x, int y, int z, int offset)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopMove(Location loc)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAttack(L2Character target)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCast(Skill skill)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,586 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import static com.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_IDLE;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
|
||||
import com.l2jmobius.gameserver.datatables.SkillData;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.Location;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.StopMove;
|
||||
import com.l2jmobius.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 npcTemplateId)
|
||||
{
|
||||
super(NpcData.getInstance().getTemplate(npcTemplateId));
|
||||
setInstanceType(InstanceType.L2TamedBeastInstance);
|
||||
setHome(this);
|
||||
}
|
||||
|
||||
public L2TamedBeastInstance(int npcTemplateId, L2PcInstance owner, int foodSkillId, int x, int y, int z)
|
||||
{
|
||||
super(NpcData.getInstance().getTemplate(npcTemplateId));
|
||||
_isFreyaBeast = false;
|
||||
setInstanceType(InstanceType.L2TamedBeastInstance);
|
||||
setCurrentHp(getMaxHp());
|
||||
setCurrentMp(getMaxMp());
|
||||
setOwner(owner);
|
||||
setFoodType(foodSkillId);
|
||||
setHome(x, y, z);
|
||||
spawnMe(x, y, z);
|
||||
}
|
||||
|
||||
public L2TamedBeastInstance(int npcTemplateId, L2PcInstance owner, int food, int x, int y, int z, boolean isFreyaBeast)
|
||||
{
|
||||
super(NpcData.getInstance().getTemplate(npcTemplateId));
|
||||
_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 CopyOnWriteArrayList<>();
|
||||
}
|
||||
_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;
|
||||
}
|
||||
|
||||
final 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()
|
||||
{
|
||||
final int foodTypeSkillId = _tamedBeast.getFoodType();
|
||||
final 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))
|
||||
{
|
||||
final L2Object oldTarget = owner.getTarget();
|
||||
owner.setTarget(_tamedBeast);
|
||||
final 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()
|
||||
{
|
||||
final 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;
|
||||
final 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,606 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.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.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.cache.HtmCache;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.TeleportLocationTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.MultisellData;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.TeleportersData;
|
||||
import com.l2jmobius.gameserver.datatables.ItemTable;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.SiegeManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.TownManager;
|
||||
import com.l2jmobius.gameserver.model.L2TeleportLocation;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.itemcontainer.Inventory;
|
||||
import com.l2jmobius.gameserver.model.items.L2Item;
|
||||
import com.l2jmobius.gameserver.model.quest.QuestState;
|
||||
import com.l2jmobius.gameserver.model.teleporter.TeleportHolder;
|
||||
import com.l2jmobius.gameserver.model.teleporter.TeleportLocation;
|
||||
import com.l2jmobius.gameserver.model.teleporter.TeleportType;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.NpcStringId;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* Creates a teleporter.
|
||||
* @param template the teleporter NPC template
|
||||
*/
|
||||
public L2TeleporterInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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(), "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(), "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, type, loc))
|
||||
{
|
||||
finalName += " - " + calculateFee(player, type, loc) + " " + 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(), "html/teleporter/castleteleporter-busy.htm");
|
||||
player.sendPacket(msg);
|
||||
}
|
||||
else if (!Config.ALT_GAME_KARMA_PLAYER_CAN_USE_GK && (player.getReputation() < 0))
|
||||
{
|
||||
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, type, loc) && !player.destroyItemByItemId("Teleport", loc.getFeeId(), calculateFee(player, type, loc), 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param player
|
||||
* @param type
|
||||
* @param loc
|
||||
* @return
|
||||
*/
|
||||
private long calculateFee(L2PcInstance player, TeleportType type, TeleportLocation loc)
|
||||
{
|
||||
if (type == TeleportType.NORMAL)
|
||||
{
|
||||
if (!player.isSubClassActive() && (player.getLevel() < 77))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
final Calendar cal = Calendar.getInstance();
|
||||
final int hour = cal.get(Calendar.HOUR_OF_DAY);
|
||||
final int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
|
||||
if ((hour >= 20) && ((dayOfWeek >= Calendar.MONDAY) && (dayOfWeek <= Calendar.TUESDAY)))
|
||||
{
|
||||
return loc.getFeeCount() / 2;
|
||||
}
|
||||
}
|
||||
return loc.getFeeCount();
|
||||
}
|
||||
|
||||
protected boolean shouldPayFee(L2PcInstance player, TeleportType type, TeleportLocation loc)
|
||||
{
|
||||
return (type != TeleportType.NORMAL) || (!Config.FREE_TELEPORTING && ((player.getLevel() > 76) || player.isSubClassActive()) && ((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";
|
||||
}
|
||||
case MultisellData.RAID_POINTS:
|
||||
{
|
||||
return "Raid Points";
|
||||
}
|
||||
}
|
||||
return "Unknown item: " + itemId;
|
||||
}
|
||||
|
||||
private void processLegacyBypass(L2PcInstance player, String command)
|
||||
{
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
|
||||
final int condition = validateCondition(player);
|
||||
|
||||
final StringTokenizer st = new StringTokenizer(command, " ");
|
||||
final String actualCommand = st.nextToken(); // Get actual command
|
||||
|
||||
if (player.isAffectedBySkill(6201) || player.isAffectedBySkill(6202) || player.isAffectedBySkill(6203))
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
|
||||
final String filename = "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"))
|
||||
{
|
||||
final 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;
|
||||
}
|
||||
|
||||
final 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"))
|
||||
{
|
||||
final 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 "html/teleporter/" + pom + ".htm";
|
||||
}
|
||||
|
||||
private void showNewbieHtml(L2PcInstance player)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
|
||||
|
||||
String filename = "html/teleporter/free/" + getTemplate().getId() + ".htm";
|
||||
if (!HtmCache.getInstance().isLoadable(filename))
|
||||
{
|
||||
filename = "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 = "html/teleporter/half/" + getId() + ".htm";
|
||||
if (!HtmCache.getInstance().isLoadable(filename))
|
||||
{
|
||||
filename = "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 = "html/teleporter/castleteleporter-no.htm";
|
||||
|
||||
final 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 = "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)
|
||||
{
|
||||
final 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.getReputation() < 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())
|
||||
{
|
||||
final String filename = "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;
|
||||
}
|
||||
|
||||
int price = list.getPrice();
|
||||
|
||||
if (player.getLevel() < 41)
|
||||
{
|
||||
price = 0;
|
||||
}
|
||||
else if (!list.getIsForNoble())
|
||||
{
|
||||
final Calendar cal = Calendar.getInstance();
|
||||
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.FREE_TELEPORTING || 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(), player.getHeading(), -1);
|
||||
}
|
||||
}
|
||||
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,54 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
|
||||
public final class L2TerrainObjectInstance extends L2Npc
|
||||
{
|
||||
/**
|
||||
* Creates a terrain object.
|
||||
* @param template the terrain object NPC template
|
||||
*/
|
||||
public L2TerrainObjectInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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,49 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
public class L2TrainerInstance extends L2NpcInstance
|
||||
{
|
||||
/**
|
||||
* Creates a trainer.
|
||||
* @param template the trainer NPC template
|
||||
*/
|
||||
public L2TrainerInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2TrainerInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "html/trainer/" + pom + ".htm";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,470 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.enums.TrapAction;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.knownlist.TrapKnownList;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.npc.trap.TrapTask;
|
||||
import com.l2jmobius.gameserver.model.actor.tasks.npc.trap.TrapTriggerTask;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.trap.OnTrapAction;
|
||||
import com.l2jmobius.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jmobius.gameserver.model.items.L2Weapon;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jmobius.gameserver.model.olympiad.OlympiadGameManager;
|
||||
import com.l2jmobius.gameserver.model.skills.Skill;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.AbstractNpcInfo.TrapInfo;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.L2GameServerPacket;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.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;
|
||||
|
||||
/**
|
||||
* Creates a trap.
|
||||
* @param template the trap NPC template
|
||||
* @param instanceId the instance ID
|
||||
* @param lifeTime the life time
|
||||
*/
|
||||
public L2TrapInstance(L2NpcTemplate template, int instanceId, int lifeTime)
|
||||
{
|
||||
super(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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a trap.
|
||||
* @param template the trap NPC template
|
||||
* @param owner the owner
|
||||
* @param lifeTime the life time
|
||||
*/
|
||||
public L2TrapInstance(L2NpcTemplate template, L2PcInstance owner, int lifeTime)
|
||||
{
|
||||
this(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)
|
||||
{
|
||||
// Range seems to be reduced from Freya(300) to H5(150)
|
||||
if (!target.isInsideRadius(this, 150, false, false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Skill.checkForAreaOffensiveSkills(this, target, _skill.getSkill(), _isInArena))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// observers
|
||||
if (target.isPlayer() && target.getActingPlayer().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.getReputation() >= 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 getReputation()
|
||||
{
|
||||
return _owner != null ? _owner.getReputation() : 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.isHpBlocked()) && !target.isNpc())
|
||||
{
|
||||
_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.getReputation() >= 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), 500);
|
||||
}
|
||||
|
||||
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 updateAbnormalVisualEffects()
|
||||
{
|
||||
}
|
||||
|
||||
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,44 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.Race;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.base.PlayerClass;
|
||||
|
||||
public final class L2VillageMasterDElfInstance extends L2VillageMasterInstance
|
||||
{
|
||||
/**
|
||||
* Creates a village master.
|
||||
* @param template the village master NPC template
|
||||
*/
|
||||
public L2VillageMasterDElfInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterRace(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfRace(Race.DARK_ELF);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.Race;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.base.PlayerClass;
|
||||
|
||||
public final class L2VillageMasterDwarfInstance extends L2VillageMasterInstance
|
||||
{
|
||||
/**
|
||||
* Creates a village master.
|
||||
* @param template the village master NPC template
|
||||
*/
|
||||
public L2VillageMasterDwarfInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterRace(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfRace(Race.DWARF);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.Race;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.base.ClassType;
|
||||
import com.l2jmobius.gameserver.model.base.PlayerClass;
|
||||
|
||||
public final class L2VillageMasterFighterInstance extends L2VillageMasterInstance
|
||||
{
|
||||
/**
|
||||
* Creates a village master.
|
||||
* @param template the village master NPC template
|
||||
*/
|
||||
public L2VillageMasterFighterInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,658 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.data.sql.impl.ClanTable;
|
||||
import com.l2jmobius.gameserver.data.xml.impl.SkillTreesData;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FortManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.FortSiegeManager;
|
||||
import com.l2jmobius.gameserver.instancemanager.SiegeManager;
|
||||
import com.l2jmobius.gameserver.model.L2Clan;
|
||||
import com.l2jmobius.gameserver.model.L2Clan.SubPledge;
|
||||
import com.l2jmobius.gameserver.model.L2ClanMember;
|
||||
import com.l2jmobius.gameserver.model.L2SkillLearn;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.base.AcquireSkillType;
|
||||
import com.l2jmobius.gameserver.model.base.PlayerClass;
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
import com.l2jmobius.gameserver.model.entity.Fort;
|
||||
import com.l2jmobius.gameserver.model.zone.ZoneId;
|
||||
import com.l2jmobius.gameserver.network.SystemMessageId;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ActionFailed;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.ExAcquirableSkillListByClass;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillLaunched;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision: 1.4.2.3.2.8 $ $Date: 2005/03/29 23:15:15 $
|
||||
*/
|
||||
public class L2VillageMasterInstance extends L2NpcInstance
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(L2VillageMasterInstance.class.getName());
|
||||
|
||||
/**
|
||||
* Creates a village master.
|
||||
* @param template the village master NPC template
|
||||
*/
|
||||
public L2VillageMasterInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
setInstanceType(InstanceType.L2VillageMasterInstance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHtmlPath(int npcId, int val)
|
||||
{
|
||||
String pom = "";
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
pom = "" + npcId;
|
||||
}
|
||||
else
|
||||
{
|
||||
pom = npcId + "-" + val;
|
||||
}
|
||||
|
||||
return "html/villagemaster/" + pom + ".htm";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBypassFeedback(L2PcInstance player, String command)
|
||||
{
|
||||
final String[] commandStr = command.split(" ");
|
||||
final String actualCommand = commandStr[0]; // Get actual command
|
||||
|
||||
String cmdParams = "";
|
||||
String cmdParams2 = "";
|
||||
|
||||
if (commandStr.length >= 2)
|
||||
{
|
||||
cmdParams = commandStr[1];
|
||||
}
|
||||
if (commandStr.length >= 3)
|
||||
{
|
||||
cmdParams2 = commandStr[2];
|
||||
}
|
||||
|
||||
if (actualCommand.equalsIgnoreCase("create_clan"))
|
||||
{
|
||||
if (cmdParams.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isValidName(cmdParams))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.CLAN_NAME_IS_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
ClanTable.getInstance().createClan(player, cmdParams);
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("create_academy"))
|
||||
{
|
||||
if (cmdParams.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
createSubPledge(player, cmdParams, null, L2Clan.SUBUNIT_ACADEMY, 5);
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("rename_pledge"))
|
||||
{
|
||||
if (cmdParams.isEmpty() || cmdParams2.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
renameSubPledge(player, Integer.parseInt(cmdParams), cmdParams2);
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("create_royal"))
|
||||
{
|
||||
if (cmdParams.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
createSubPledge(player, cmdParams, cmdParams2, L2Clan.SUBUNIT_ROYAL1, 6);
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("create_knight"))
|
||||
{
|
||||
if (cmdParams.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
createSubPledge(player, cmdParams, cmdParams2, L2Clan.SUBUNIT_KNIGHT1, 7);
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("assign_subpl_leader"))
|
||||
{
|
||||
if (cmdParams.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
assignSubPledgeLeader(player, cmdParams, cmdParams2);
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("create_ally"))
|
||||
{
|
||||
if (cmdParams.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getClan() == null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.ONLY_CLAN_LEADERS_MAY_CREATE_ALLIANCES);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.getClan().createAlly(player, cmdParams);
|
||||
}
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("dissolve_ally"))
|
||||
{
|
||||
player.getClan().dissolveAlly(player);
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("dissolve_clan"))
|
||||
{
|
||||
dissolveClan(player, player.getClanId());
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("change_clan_leader"))
|
||||
{
|
||||
if (cmdParams.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.isClanLeader())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_ARE_NOT_AUTHORIZED_TO_DO_THAT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getName().equalsIgnoreCase(cmdParams))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final L2Clan clan = player.getClan();
|
||||
final L2ClanMember member = clan.getClanMember(cmdParams);
|
||||
if (member == null)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_DOES_NOT_EXIST);
|
||||
sm.addString(cmdParams);
|
||||
player.sendPacket(sm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!member.isOnline())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THAT_PLAYER_IS_NOT_CURRENTLY_ONLINE);
|
||||
return;
|
||||
}
|
||||
|
||||
// To avoid clans with null clan leader, academy members shouldn't be eligible for clan leader.
|
||||
if (member.getPlayerInstance().isAcademyMember())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THAT_PRIVILEGE_CANNOT_BE_GRANTED_TO_A_CLAN_ACADEMY_MEMBER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.ALT_CLAN_LEADER_INSTANT_ACTIVATION)
|
||||
{
|
||||
clan.setNewLeader(member);
|
||||
}
|
||||
else
|
||||
{
|
||||
final NpcHtmlMessage msg = new NpcHtmlMessage(getObjectId());
|
||||
if (clan.getNewLeaderId() == 0)
|
||||
{
|
||||
clan.setNewLeaderId(member.getObjectId(), true);
|
||||
msg.setFile(player.getHtmlPrefix(), "scripts/village_master/Clan/9000-07-success.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.setFile(player.getHtmlPrefix(), "scripts/village_master/Clan/9000-07-in-progress.htm");
|
||||
}
|
||||
player.sendPacket(msg);
|
||||
}
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("cancel_clan_leader_change"))
|
||||
{
|
||||
if (!player.isClanLeader())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_ARE_NOT_AUTHORIZED_TO_DO_THAT);
|
||||
return;
|
||||
}
|
||||
|
||||
final L2Clan clan = player.getClan();
|
||||
final NpcHtmlMessage msg = new NpcHtmlMessage(getObjectId());
|
||||
if (clan.getNewLeaderId() != 0)
|
||||
{
|
||||
clan.setNewLeaderId(0, true);
|
||||
msg.setFile(player.getHtmlPrefix(), "scripts/village_master/Clan/9000-07-canceled.htm");
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.setHtml("<html><body>You don't have clan leader delegation applications submitted yet!</body></html>");
|
||||
}
|
||||
|
||||
player.sendPacket(msg);
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("recover_clan"))
|
||||
{
|
||||
recoverClan(player, player.getClanId());
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("increase_clan_level"))
|
||||
{
|
||||
if (player.getClan().levelUpClan(player))
|
||||
{
|
||||
player.broadcastPacket(new MagicSkillUse(player, 5103, 1, 0, 0));
|
||||
player.broadcastPacket(new MagicSkillLaunched(player, 5103, 1));
|
||||
}
|
||||
}
|
||||
else if (actualCommand.equalsIgnoreCase("learn_clan_skills"))
|
||||
{
|
||||
showPledgeSkillList(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.onBypassFeedback(player, command);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean checkVillageMasterRace(PlayerClass pclass)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean checkVillageMasterTeachType(PlayerClass pclass)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this classId allowed for master
|
||||
* @param classId
|
||||
* @return
|
||||
*/
|
||||
public final boolean checkVillageMaster(int classId)
|
||||
{
|
||||
return checkVillageMaster(PlayerClass.values()[classId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this PlayerClass is allowed for master
|
||||
* @param pclass
|
||||
* @return
|
||||
*/
|
||||
public final boolean checkVillageMaster(PlayerClass pclass)
|
||||
{
|
||||
return checkVillageMasterRace(pclass) && checkVillageMasterTeachType(pclass);
|
||||
}
|
||||
|
||||
private static final void dissolveClan(L2PcInstance player, int clanId)
|
||||
{
|
||||
if (!player.isClanLeader())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_ARE_NOT_AUTHORIZED_TO_DO_THAT);
|
||||
return;
|
||||
}
|
||||
|
||||
final L2Clan clan = player.getClan();
|
||||
if (clan.getAllyId() != 0)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_DISPERSE_THE_CLANS_IN_YOUR_ALLIANCE);
|
||||
return;
|
||||
}
|
||||
if (clan.isAtWar())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_DISSOLVE_A_CLAN_WHILE_ENGAGED_IN_A_WAR);
|
||||
return;
|
||||
}
|
||||
if ((clan.getCastleId() != 0) || (clan.getHideoutId() != 0) || (clan.getFortId() != 0))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_DISSOLVE_A_CLAN_WHILE_OWNING_A_CLAN_HALL_OR_CASTLE);
|
||||
return;
|
||||
}
|
||||
|
||||
for (Castle castle : CastleManager.getInstance().getCastles())
|
||||
{
|
||||
if (SiegeManager.getInstance().checkIsRegistered(clan, castle.getResidenceId()))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_DISSOLVE_A_CLAN_DURING_A_SIEGE_OR_WHILE_PROTECTING_A_CASTLE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (Fort fort : FortManager.getInstance().getForts())
|
||||
{
|
||||
if (FortSiegeManager.getInstance().checkIsRegistered(clan, fort.getResidenceId()))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_DISSOLVE_A_CLAN_DURING_A_SIEGE_OR_WHILE_PROTECTING_A_CASTLE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (player.isInsideZone(ZoneId.SIEGE))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_DISSOLVE_A_CLAN_DURING_A_SIEGE_OR_WHILE_PROTECTING_A_CASTLE);
|
||||
return;
|
||||
}
|
||||
if (clan.getDissolvingExpiryTime() > System.currentTimeMillis())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_HAVE_ALREADY_REQUESTED_THE_DISSOLUTION_OF_YOUR_CLAN);
|
||||
return;
|
||||
}
|
||||
|
||||
clan.setDissolvingExpiryTime(System.currentTimeMillis() + (Config.ALT_CLAN_DISSOLVE_DAYS * 86400000L)); // 24*60*60*1000 = 86400000
|
||||
clan.updateClanInDB();
|
||||
|
||||
// The clan leader should take the XP penalty of a full death.
|
||||
player.calculateDeathExpPenalty(null, false);
|
||||
ClanTable.getInstance().scheduleRemoveClan(clan.getId());
|
||||
}
|
||||
|
||||
private static final void recoverClan(L2PcInstance player, int clanId)
|
||||
{
|
||||
if (!player.isClanLeader())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_ARE_NOT_AUTHORIZED_TO_DO_THAT);
|
||||
return;
|
||||
}
|
||||
|
||||
final L2Clan clan = player.getClan();
|
||||
clan.setDissolvingExpiryTime(0);
|
||||
clan.updateClanInDB();
|
||||
}
|
||||
|
||||
private static final void createSubPledge(L2PcInstance player, String clanName, String leaderName, int pledgeType, int minClanLvl)
|
||||
{
|
||||
if (!player.isClanLeader())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_ARE_NOT_AUTHORIZED_TO_DO_THAT);
|
||||
return;
|
||||
}
|
||||
|
||||
final L2Clan clan = player.getClan();
|
||||
if (clan.getLevel() < minClanLvl)
|
||||
{
|
||||
if (pledgeType == L2Clan.SUBUNIT_ACADEMY)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.TO_ESTABLISH_A_CLAN_ACADEMY_YOUR_CLAN_MUST_BE_LEVEL_5_OR_HIGHER);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_CONDITIONS_NECESSARY_TO_CREATE_A_MILITARY_UNIT_HAVE_NOT_BEEN_MET);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
if (!Util.isAlphaNumeric(clanName) || !isValidName(clanName) || (2 > clanName.length()))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.CLAN_NAME_IS_INVALID);
|
||||
return;
|
||||
}
|
||||
if (clanName.length() > 16)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.CLAN_NAME_S_LENGTH_IS_INCORRECT);
|
||||
return;
|
||||
}
|
||||
|
||||
for (L2Clan tempClan : ClanTable.getInstance().getClans())
|
||||
{
|
||||
if (tempClan.getSubPledge(clanName) != null)
|
||||
{
|
||||
if (pledgeType == L2Clan.SUBUNIT_ACADEMY)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_ALREADY_EXISTS);
|
||||
sm.addString(clanName);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(SystemMessageId.ANOTHER_MILITARY_UNIT_IS_ALREADY_USING_THAT_NAME_PLEASE_ENTER_A_DIFFERENT_NAME);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pledgeType != L2Clan.SUBUNIT_ACADEMY)
|
||||
{
|
||||
if ((clan.getClanMember(leaderName) == null) || (clan.getClanMember(leaderName).getPledgeType() != 0))
|
||||
{
|
||||
if (pledgeType >= L2Clan.SUBUNIT_KNIGHT1)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_CAPTAIN_OF_THE_ORDER_OF_KNIGHTS_CANNOT_BE_APPOINTED);
|
||||
}
|
||||
else if (pledgeType >= L2Clan.SUBUNIT_ROYAL1)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_ROYAL_GUARD_CAPTAIN_CANNOT_BE_APPOINTED);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final int leaderId = pledgeType != L2Clan.SUBUNIT_ACADEMY ? clan.getClanMember(leaderName).getObjectId() : 0;
|
||||
|
||||
if (clan.createSubPledge(player, pledgeType, leaderId, clanName) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SystemMessage sm;
|
||||
if (pledgeType == L2Clan.SUBUNIT_ACADEMY)
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.CONGRATULATIONS_THE_S1_S_CLAN_ACADEMY_HAS_BEEN_CREATED);
|
||||
sm.addString(player.getClan().getName());
|
||||
}
|
||||
else if (pledgeType >= L2Clan.SUBUNIT_KNIGHT1)
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.THE_KNIGHTS_OF_S1_HAVE_BEEN_CREATED);
|
||||
sm.addString(player.getClan().getName());
|
||||
}
|
||||
else if (pledgeType >= L2Clan.SUBUNIT_ROYAL1)
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.THE_ROYAL_GUARD_OF_S1_HAVE_BEEN_CREATED);
|
||||
sm.addString(player.getClan().getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
sm = SystemMessage.getSystemMessage(SystemMessageId.YOUR_CLAN_HAS_BEEN_CREATED);
|
||||
}
|
||||
player.sendPacket(sm);
|
||||
|
||||
if (pledgeType != L2Clan.SUBUNIT_ACADEMY)
|
||||
{
|
||||
final L2ClanMember leaderSubPledge = clan.getClanMember(leaderName);
|
||||
final L2PcInstance leaderPlayer = leaderSubPledge.getPlayerInstance();
|
||||
if (leaderPlayer != null)
|
||||
{
|
||||
leaderPlayer.setPledgeClass(L2ClanMember.calculatePledgeClass(leaderPlayer));
|
||||
leaderPlayer.sendPacket(new UserInfo(leaderPlayer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final void renameSubPledge(L2PcInstance player, int pledgeType, String pledgeName)
|
||||
{
|
||||
if (!player.isClanLeader())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_ARE_NOT_AUTHORIZED_TO_DO_THAT);
|
||||
return;
|
||||
}
|
||||
|
||||
final L2Clan clan = player.getClan();
|
||||
final SubPledge subPledge = player.getClan().getSubPledge(pledgeType);
|
||||
|
||||
if (subPledge == null)
|
||||
{
|
||||
player.sendMessage("Pledge don't exists.");
|
||||
return;
|
||||
}
|
||||
if (!Util.isAlphaNumeric(pledgeName) || !isValidName(pledgeName) || (2 > pledgeName.length()))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.CLAN_NAME_IS_INVALID);
|
||||
return;
|
||||
}
|
||||
if (pledgeName.length() > 16)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.CLAN_NAME_S_LENGTH_IS_INCORRECT);
|
||||
return;
|
||||
}
|
||||
|
||||
subPledge.setName(pledgeName);
|
||||
clan.updateSubPledgeInDB(subPledge.getId());
|
||||
clan.broadcastClanStatus();
|
||||
player.sendMessage("Pledge name changed.");
|
||||
}
|
||||
|
||||
private static final void assignSubPledgeLeader(L2PcInstance player, String clanName, String leaderName)
|
||||
{
|
||||
if (!player.isClanLeader())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_ARE_NOT_AUTHORIZED_TO_DO_THAT);
|
||||
return;
|
||||
}
|
||||
if (leaderName.length() > 16)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOUR_TITLE_CANNOT_EXCEED_16_CHARACTERS_IN_LENGTH_PLEASE_TRY_AGAIN);
|
||||
return;
|
||||
}
|
||||
if (player.getName().equals(leaderName))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_ROYAL_GUARD_CAPTAIN_CANNOT_BE_APPOINTED);
|
||||
return;
|
||||
}
|
||||
|
||||
final L2Clan clan = player.getClan();
|
||||
final SubPledge subPledge = player.getClan().getSubPledge(clanName);
|
||||
|
||||
if ((null == subPledge) || (subPledge.getId() == L2Clan.SUBUNIT_ACADEMY))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.CLAN_NAME_IS_INVALID);
|
||||
return;
|
||||
}
|
||||
if ((clan.getClanMember(leaderName) == null) || (clan.getClanMember(leaderName).getPledgeType() != 0))
|
||||
{
|
||||
if (subPledge.getId() >= L2Clan.SUBUNIT_KNIGHT1)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_CAPTAIN_OF_THE_ORDER_OF_KNIGHTS_CANNOT_BE_APPOINTED);
|
||||
}
|
||||
else if (subPledge.getId() >= L2Clan.SUBUNIT_ROYAL1)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_ROYAL_GUARD_CAPTAIN_CANNOT_BE_APPOINTED);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
subPledge.setLeaderId(clan.getClanMember(leaderName).getObjectId());
|
||||
clan.updateSubPledgeInDB(subPledge.getId());
|
||||
|
||||
final L2ClanMember leaderSubPledge = clan.getClanMember(leaderName);
|
||||
final L2PcInstance leaderPlayer = leaderSubPledge.getPlayerInstance();
|
||||
if (leaderPlayer != null)
|
||||
{
|
||||
leaderPlayer.setPledgeClass(L2ClanMember.calculatePledgeClass(leaderPlayer));
|
||||
leaderPlayer.sendPacket(new UserInfo(leaderPlayer));
|
||||
}
|
||||
|
||||
clan.broadcastClanStatus();
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.C1_HAS_BEEN_SELECTED_AS_THE_CAPTAIN_OF_S2);
|
||||
sm.addString(leaderName);
|
||||
sm.addString(clanName);
|
||||
clan.broadcastToOnlineMembers(sm);
|
||||
}
|
||||
|
||||
/**
|
||||
* this displays PledgeSkillList to the player.
|
||||
* @param player
|
||||
*/
|
||||
public static final void showPledgeSkillList(L2PcInstance player)
|
||||
{
|
||||
if (!player.isClanLeader())
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage();
|
||||
html.setFile(player.getHtmlPrefix(), "html/villagemaster/NotClanLeader.htm");
|
||||
player.sendPacket(html);
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
return;
|
||||
}
|
||||
|
||||
final List<L2SkillLearn> skills = SkillTreesData.getInstance().getAvailablePledgeSkills(player.getClan());
|
||||
|
||||
if (skills.isEmpty())
|
||||
{
|
||||
if (player.getClan().getLevel() < 8)
|
||||
{
|
||||
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.YOU_DO_NOT_HAVE_ANY_FURTHER_SKILLS_TO_LEARN_COME_BACK_WHEN_YOU_HAVE_REACHED_LEVEL_S1);
|
||||
if (player.getClan().getLevel() < 5)
|
||||
{
|
||||
sm.addInt(5);
|
||||
}
|
||||
else
|
||||
{
|
||||
sm.addInt(player.getClan().getLevel() + 1);
|
||||
}
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
else
|
||||
{
|
||||
final NpcHtmlMessage html = new NpcHtmlMessage();
|
||||
html.setFile(player.getHtmlPrefix(), "html/villagemaster/NoMoreSkills.htm");
|
||||
player.sendPacket(html);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(new ExAcquirableSkillListByClass(skills, AcquireSkillType.PLEDGE));
|
||||
}
|
||||
player.sendPacket(ActionFailed.STATIC_PACKET);
|
||||
}
|
||||
|
||||
private static boolean isValidName(String name)
|
||||
{
|
||||
Pattern pattern;
|
||||
try
|
||||
{
|
||||
pattern = Pattern.compile(Config.CLAN_NAME_TEMPLATE);
|
||||
}
|
||||
catch (PatternSyntaxException e)
|
||||
{
|
||||
_log.warning("ERROR: Wrong pattern for clan name!");
|
||||
pattern = Pattern.compile(".*");
|
||||
}
|
||||
return pattern.matcher(name).matches();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.Race;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.base.PlayerClass;
|
||||
|
||||
public final class L2VillageMasterKamaelInstance extends L2VillageMasterInstance
|
||||
{
|
||||
/**
|
||||
* Creates a village master.
|
||||
* @param template the village master NPC template
|
||||
*/
|
||||
public L2VillageMasterKamaelInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterRace(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfRace(Race.KAMAEL);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.Race;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.base.ClassType;
|
||||
import com.l2jmobius.gameserver.model.base.PlayerClass;
|
||||
|
||||
public final class L2VillageMasterMysticInstance extends L2VillageMasterInstance
|
||||
{
|
||||
/**
|
||||
* Creates a village master.
|
||||
* @param template the village master NPC template
|
||||
*/
|
||||
public L2VillageMasterMysticInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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,44 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.Race;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.base.PlayerClass;
|
||||
|
||||
public final class L2VillageMasterOrcInstance extends L2VillageMasterInstance
|
||||
{
|
||||
/**
|
||||
* Creates a village master.
|
||||
* @param template the village master NPC template
|
||||
*/
|
||||
public L2VillageMasterOrcInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(template);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final boolean checkVillageMasterRace(PlayerClass pclass)
|
||||
{
|
||||
if (pclass == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return pclass.isOfRace(Race.ORC);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.Race;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jmobius.gameserver.model.base.ClassType;
|
||||
import com.l2jmobius.gameserver.model.base.PlayerClass;
|
||||
|
||||
public final class L2VillageMasterPriestInstance extends L2VillageMasterInstance
|
||||
{
|
||||
/**
|
||||
* Creates a village master.
|
||||
* @param template the village master NPC template
|
||||
*/
|
||||
public L2VillageMasterPriestInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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,56 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.instance;
|
||||
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
|
||||
public class L2WarehouseInstance extends L2NpcInstance
|
||||
{
|
||||
/**
|
||||
* Creates a warehouse NPC.
|
||||
* @param template the warehouse NPC template
|
||||
*/
|
||||
public L2WarehouseInstance(L2NpcTemplate template)
|
||||
{
|
||||
super(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 "html/warehouse/" + pom + ".htm";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.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());
|
||||
}
|
||||
|
||||
final int max = Math.max(300, Math.max(getActiveChar().getAggroRange(), getActiveChar().getTemplate().getClanHelpRange()));
|
||||
|
||||
return max;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Summon;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
public class CharKnownList extends ObjectKnownList
|
||||
{
|
||||
private volatile Map<Integer, L2PcInstance> _knownPlayers;
|
||||
private volatile Map<Integer, L2Summon> _knownSummons;
|
||||
private volatile Map<Integer, Integer> _knownRelations;
|
||||
|
||||
public CharKnownList(L2Character activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addKnownObject(L2Object object)
|
||||
{
|
||||
if (!super.addKnownObject(object))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
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 Iterator<L2PcInstance> pIter = getKnownPlayers().values().iterator();
|
||||
while (pIter.hasNext())
|
||||
{
|
||||
final L2PcInstance 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 Iterator<L2Summon> sIter = getKnownSummons().values().iterator();
|
||||
while (sIter.hasNext())
|
||||
{
|
||||
final L2Summon 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 Iterator<L2Object> oIter = getKnownObjects().values().iterator();
|
||||
while (oIter.hasNext())
|
||||
{
|
||||
final L2Object 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 List<L2Character> getKnownCharacters()
|
||||
{
|
||||
final List<L2Character> result = new LinkedList<>();
|
||||
for (L2Object obj : getKnownObjects().values())
|
||||
{
|
||||
if (obj instanceof L2Character)
|
||||
{
|
||||
result.add((L2Character) obj);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<L2Character> getKnownCharactersInRadius(long radius)
|
||||
{
|
||||
final List<L2Character> result = new LinkedList<>();
|
||||
for (L2Object obj : getKnownObjects().values())
|
||||
{
|
||||
if (obj instanceof L2Character)
|
||||
{
|
||||
if (Util.checkIfInRange((int) radius, getActiveChar(), obj, true))
|
||||
{
|
||||
result.add((L2Character) obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public final List<L2PcInstance> getKnownPlayersInRadius(long radius)
|
||||
{
|
||||
final List<L2PcInstance> result = new LinkedList<>();
|
||||
for (L2PcInstance player : getKnownPlayers().values())
|
||||
{
|
||||
if (Util.checkIfInRange((int) radius, getActiveChar(), player, true))
|
||||
{
|
||||
result.add(player);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public final Map<Integer, L2PcInstance> getKnownPlayers()
|
||||
{
|
||||
if (_knownPlayers == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_knownPlayers == null)
|
||||
{
|
||||
_knownPlayers = new ConcurrentHashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return _knownPlayers;
|
||||
}
|
||||
|
||||
public final Map<Integer, Integer> getKnownRelations()
|
||||
{
|
||||
if (_knownRelations == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_knownRelations == null)
|
||||
{
|
||||
_knownRelations = new ConcurrentHashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return _knownRelations;
|
||||
}
|
||||
|
||||
public final Map<Integer, L2Summon> getKnownSummons()
|
||||
{
|
||||
if (_knownSummons == null)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_knownSummons == null)
|
||||
{
|
||||
_knownSummons = new ConcurrentHashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return _knownSummons;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString()
|
||||
{
|
||||
return getActiveChar() + " Known Objects " + getKnownObjects();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.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,72 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2DefenderInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.entity.Castle;
|
||||
import com.l2jmobius.gameserver.model.entity.Fort;
|
||||
import com.l2jmobius.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;
|
||||
}
|
||||
|
||||
final Castle castle = getActiveChar().getCastle();
|
||||
final Fort fortress = getActiveChar().getFort();
|
||||
final 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();
|
||||
}
|
||||
final 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,64 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2DefenderInstance;
|
||||
import com.l2jmobius.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,87 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.CtrlEvent;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.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,123 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2GuardInstance;
|
||||
import com.l2jmobius.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().getReputation() < 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);
|
||||
}
|
||||
}
|
||||
|
||||
// Faction system
|
||||
if (Config.FACTION_SYSTEM_ENABLED && Config.FACTION_GUARDS_ENABLED && ((object.getActingPlayer().isGood() && getActiveChar().getTemplate().isClan(Config.FACTION_EVIL_TEAM_NAME)) || (object.getActingPlayer().isEvil() && getActiveChar().getTemplate().isClan(Config.FACTION_GOOD_TEAM_NAME))))
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.fine(getActiveChar().getObjectId() + ": Enemy faction " + 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,86 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jmobius.gameserver.ai.CtrlEvent;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.ai.L2CharacterAI;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jmobius.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,150 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.ai.CtrlIntention;
|
||||
import com.l2jmobius.gameserver.enums.InstanceType;
|
||||
import com.l2jmobius.gameserver.instancemanager.WalkingManager;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.events.EventDispatcher;
|
||||
import com.l2jmobius.gameserver.model.events.impl.character.npc.OnNpcCreatureSee;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.MoveToLocation;
|
||||
|
||||
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))
|
||||
{
|
||||
// Broadcast correct walking NPC position.
|
||||
if (object.isPlayer() && getActiveChar().isMoving() && !getActiveChar().isInCombat())
|
||||
{
|
||||
((L2Character) object).broadcastPacket(new MoveToLocation(getActiveChar()));
|
||||
}
|
||||
|
||||
// Notify to scripts
|
||||
EventDispatcher.getInstance().notifyEventAsync(new OnNpcCreatureSee(getActiveChar(), (L2Character) object, object.isSummon()), getActiveChar());
|
||||
}
|
||||
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().isAttackable())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final L2Attackable monster = (L2Attackable) getActiveChar();
|
||||
if (monster.getAI().getIntention() != CtrlIntention.AI_INTENTION_MOVE_TO)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (L2PcInstance pl : getKnownPlayers().values())
|
||||
{
|
||||
if (!pl.isDead() && !pl.isInvul() && pl.isInsideRadius(monster, monster.getAggroRange(), true, false) && (monster.isMonster() || (monster.isInstanceTypes(InstanceType.L2GuardInstance) && (pl.getReputation() < 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,62 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jmobius.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,212 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.L2WorldRegion;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.util.Util;
|
||||
|
||||
public class ObjectKnownList
|
||||
{
|
||||
private final L2Object _activeObject;
|
||||
private volatile 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 worldRegion = getActiveObject().getWorldRegion();
|
||||
if (worldRegion == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (getActiveObject().isPlayable())
|
||||
{
|
||||
for (L2WorldRegion surroundingRegion : worldRegion.getSurroundingRegions()) // offer members of this and surrounding regions
|
||||
{
|
||||
for (L2Object object : surroundingRegion.getVisibleObjects().values())
|
||||
{
|
||||
if (object != getActiveObject())
|
||||
{
|
||||
addKnownObject(object);
|
||||
if (object instanceof L2Character)
|
||||
{
|
||||
object.getKnownList().addKnownObject(getActiveObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (getActiveObject() instanceof L2Character)
|
||||
{
|
||||
for (L2WorldRegion surroundingRegion : worldRegion.getSurroundingRegions()) // offer members of this and surrounding regions
|
||||
{
|
||||
if (surroundingRegion.isActive())
|
||||
{
|
||||
for (L2Object object : surroundingRegion.getVisiblePlayable().values())
|
||||
{
|
||||
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)
|
||||
{
|
||||
final Iterator<L2Object> oIter = getKnownObjects().values().iterator();
|
||||
while (oIter.hasNext())
|
||||
{
|
||||
final L2Object object = oIter.next();
|
||||
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)
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
if (_knownObjects == null)
|
||||
{
|
||||
_knownObjects = new ConcurrentHashMap<>();
|
||||
}
|
||||
}
|
||||
}
|
||||
return _knownObjects;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jmobius.Config;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Character;
|
||||
import com.l2jmobius.gameserver.model.actor.L2Npc;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2AirShipInstance;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.DeleteObject;
|
||||
import com.l2jmobius.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;
|
||||
}
|
||||
if (getKnownObjects().size() <= 70)
|
||||
{
|
||||
return 2700;
|
||||
}
|
||||
return 1900; // Siege, etc
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceToWatchObject(L2Object object)
|
||||
{
|
||||
if (object.isVehicle())
|
||||
{
|
||||
return 9000;
|
||||
}
|
||||
if (getKnownObjects().size() <= 70)
|
||||
{
|
||||
return 2500; // Retail seems to have a larger value than this.
|
||||
}
|
||||
return 1700; // Siege, etc
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jmobius.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,55 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jmobius.gameserver.MonsterRace;
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2RaceManagerInstance;
|
||||
import com.l2jmobius.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,64 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2DefenderInstance;
|
||||
import com.l2jmobius.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,50 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.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,51 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.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,50 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.knownlist;
|
||||
|
||||
import com.l2jmobius.gameserver.model.L2Object;
|
||||
import com.l2jmobius.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,67 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.poly;
|
||||
|
||||
import com.l2jmobius.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,91 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.request;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import com.l2jmobius.gameserver.ThreadPoolManager;
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public abstract class AbstractRequest
|
||||
{
|
||||
private final L2PcInstance _activeChar;
|
||||
private volatile long _timestamp = 0;
|
||||
private volatile boolean _isProcessing;
|
||||
private ScheduledFuture<?> _timeOutTask;
|
||||
|
||||
public AbstractRequest(L2PcInstance activeChar)
|
||||
{
|
||||
Objects.requireNonNull(activeChar);
|
||||
_activeChar = activeChar;
|
||||
}
|
||||
|
||||
public L2PcInstance getActiveChar()
|
||||
{
|
||||
return _activeChar;
|
||||
}
|
||||
|
||||
public long getTimestamp()
|
||||
{
|
||||
return _timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp)
|
||||
{
|
||||
_timestamp = timestamp;
|
||||
}
|
||||
|
||||
public void scheduleTimeout(long delay)
|
||||
{
|
||||
_timeOutTask = ThreadPoolManager.getInstance().scheduleGeneral(this::onTimeout, delay);
|
||||
}
|
||||
|
||||
public boolean isTimeout()
|
||||
{
|
||||
return (_timeOutTask != null) && !_timeOutTask.isDone();
|
||||
}
|
||||
|
||||
public boolean isProcessing()
|
||||
{
|
||||
return _isProcessing;
|
||||
}
|
||||
|
||||
public boolean setProcessing(boolean isProcessing)
|
||||
{
|
||||
return _isProcessing = isProcessing;
|
||||
}
|
||||
|
||||
public boolean canWorkWith(AbstractRequest request)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isItemRequest()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract boolean isUsing(int objectId);
|
||||
|
||||
public void onTimeout()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.request;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.network.serverpackets.adenadistribution.ExDivideAdenaCancel;
|
||||
|
||||
/**
|
||||
* @author Sdw
|
||||
*/
|
||||
public class AdenaDistributionRequest extends AbstractRequest
|
||||
{
|
||||
private final L2PcInstance _distributor;
|
||||
private final List<L2PcInstance> _players;
|
||||
private final int _adenaObjectId;
|
||||
private final long _adenaCount;
|
||||
|
||||
public AdenaDistributionRequest(L2PcInstance activeChar, L2PcInstance distributor, List<L2PcInstance> players, int adenaObjectId, long adenaCount)
|
||||
{
|
||||
super(activeChar);
|
||||
_distributor = distributor;
|
||||
_adenaObjectId = adenaObjectId;
|
||||
_players = players;
|
||||
_adenaCount = adenaCount;
|
||||
}
|
||||
|
||||
public L2PcInstance getDistributor()
|
||||
{
|
||||
return _distributor;
|
||||
}
|
||||
|
||||
public List<L2PcInstance> getPlayers()
|
||||
{
|
||||
return _players;
|
||||
}
|
||||
|
||||
public int getAdenaObjectId()
|
||||
{
|
||||
return _adenaObjectId;
|
||||
}
|
||||
|
||||
public long getAdenaCount()
|
||||
{
|
||||
return _adenaCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUsing(int objectId)
|
||||
{
|
||||
return objectId == _adenaObjectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout()
|
||||
{
|
||||
super.onTimeout();
|
||||
_players.forEach(p ->
|
||||
{
|
||||
p.removeRequest(AdenaDistributionRequest.class);
|
||||
p.sendPacket(ExDivideAdenaCancel.STATIC_PACKET);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.request;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class CompoundRequest extends AbstractRequest
|
||||
{
|
||||
private int _itemOne;
|
||||
private int _itemTwo;
|
||||
|
||||
public CompoundRequest(L2PcInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
public L2ItemInstance getItemOne()
|
||||
{
|
||||
return getActiveChar().getInventory().getItemByObjectId(_itemOne);
|
||||
}
|
||||
|
||||
public void setItemOne(int itemOne)
|
||||
{
|
||||
_itemOne = itemOne;
|
||||
}
|
||||
|
||||
public L2ItemInstance getItemTwo()
|
||||
{
|
||||
return getActiveChar().getInventory().getItemByObjectId(_itemTwo);
|
||||
}
|
||||
|
||||
public void setItemTwo(int itemTwo)
|
||||
{
|
||||
_itemTwo = itemTwo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemRequest()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWorkWith(AbstractRequest request)
|
||||
{
|
||||
return !request.isItemRequest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUsing(int objectId)
|
||||
{
|
||||
return (objectId > 0) && ((objectId == _itemOne) || (objectId == _itemTwo));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.request;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public final class EnchantItemAttributeRequest extends AbstractRequest
|
||||
{
|
||||
private volatile int _enchantingItemObjectId;
|
||||
private volatile int _enchantingStoneObjectId;
|
||||
|
||||
public EnchantItemAttributeRequest(L2PcInstance activeChar, int enchantingStoneObjectId)
|
||||
{
|
||||
super(activeChar);
|
||||
_enchantingStoneObjectId = enchantingStoneObjectId;
|
||||
}
|
||||
|
||||
public L2ItemInstance getEnchantingItem()
|
||||
{
|
||||
return getActiveChar().getInventory().getItemByObjectId(_enchantingItemObjectId);
|
||||
}
|
||||
|
||||
public void setEnchantingItem(int objectId)
|
||||
{
|
||||
_enchantingItemObjectId = objectId;
|
||||
}
|
||||
|
||||
public L2ItemInstance getEnchantingStone()
|
||||
{
|
||||
return getActiveChar().getInventory().getItemByObjectId(_enchantingStoneObjectId);
|
||||
}
|
||||
|
||||
public void setEnchantingStone(int objectId)
|
||||
{
|
||||
_enchantingStoneObjectId = objectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemRequest()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWorkWith(AbstractRequest request)
|
||||
{
|
||||
return !request.isItemRequest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUsing(int objectId)
|
||||
{
|
||||
return (objectId > 0) && ((objectId == _enchantingItemObjectId) || (objectId == _enchantingStoneObjectId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.request;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public final class EnchantItemRequest extends AbstractRequest
|
||||
{
|
||||
private volatile int _enchantingItemObjectId;
|
||||
private volatile int _enchantingScrollObjectId;
|
||||
private volatile int _supportItemObjectId;
|
||||
|
||||
public EnchantItemRequest(L2PcInstance activeChar, int enchantingScrollObjectId)
|
||||
{
|
||||
super(activeChar);
|
||||
_enchantingScrollObjectId = enchantingScrollObjectId;
|
||||
}
|
||||
|
||||
public L2ItemInstance getEnchantingItem()
|
||||
{
|
||||
return getActiveChar().getInventory().getItemByObjectId(_enchantingItemObjectId);
|
||||
}
|
||||
|
||||
public void setEnchantingItem(int objectId)
|
||||
{
|
||||
_enchantingItemObjectId = objectId;
|
||||
}
|
||||
|
||||
public L2ItemInstance getEnchantingScroll()
|
||||
{
|
||||
return getActiveChar().getInventory().getItemByObjectId(_enchantingScrollObjectId);
|
||||
}
|
||||
|
||||
public void setEnchantingScroll(int objectId)
|
||||
{
|
||||
_enchantingScrollObjectId = objectId;
|
||||
}
|
||||
|
||||
public L2ItemInstance getSupportItem()
|
||||
{
|
||||
return getActiveChar().getInventory().getItemByObjectId(_supportItemObjectId);
|
||||
}
|
||||
|
||||
public void setSupportItem(int objectId)
|
||||
{
|
||||
_supportItemObjectId = objectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemRequest()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWorkWith(AbstractRequest request)
|
||||
{
|
||||
return !request.isItemRequest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUsing(int objectId)
|
||||
{
|
||||
return (objectId > 0) && ((objectId == _enchantingItemObjectId) || (objectId == _enchantingScrollObjectId) || (objectId == _supportItemObjectId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.request;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class PartyRequest extends AbstractRequest
|
||||
{
|
||||
private final L2PcInstance _targetPlayer;
|
||||
|
||||
public PartyRequest(L2PcInstance activeChar, L2PcInstance targetPlayer)
|
||||
{
|
||||
super(activeChar);
|
||||
Objects.requireNonNull(targetPlayer);
|
||||
_targetPlayer = targetPlayer;
|
||||
}
|
||||
|
||||
public L2PcInstance getTargetPlayer()
|
||||
{
|
||||
return _targetPlayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUsing(int objectId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeout()
|
||||
{
|
||||
super.onTimeout();
|
||||
getActiveChar().removeRequest(getClass());
|
||||
_targetPlayer.removeRequest(getClass());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* This file is part of the L2J Mobius project.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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.l2jmobius.gameserver.model.actor.request;
|
||||
|
||||
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class PrimeShopRequest extends AbstractRequest
|
||||
{
|
||||
public PrimeShopRequest(L2PcInstance activeChar)
|
||||
{
|
||||
super(activeChar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUsing(int objectId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user