Project update.

This commit is contained in:
MobiusDev
2015-12-31 23:53:41 +00:00
parent e0d681a17e
commit ad2bcd79be
4084 changed files with 83696 additions and 86998 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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);
}
}
}

File diff suppressed because it is too large Load Diff

View 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;
}
}

File diff suppressed because it is too large Load Diff

View 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);
}
}

View 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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";
}
}

View File

@@ -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));
}
}
}

View File

@@ -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)
{
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}
}
}

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}
}

View File

@@ -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
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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));
}
}
}

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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)
{
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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";
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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";
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}
}
}
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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()
{
}
}

View File

@@ -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);
});
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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());
}
}

View File

@@ -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