/* * 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 silentium.gameserver.model.actor.instance; import java.util.concurrent.ScheduledFuture; import silentium.commons.utils.Rnd; import silentium.gameserver.ThreadPoolManager; import silentium.gameserver.model.actor.L2Attackable; import silentium.gameserver.model.actor.L2Character; import silentium.gameserver.model.actor.knownlist.MonsterKnownList; import silentium.gameserver.templates.chars.L2NpcTemplate; import silentium.gameserver.utils.MinionList; /** * This class manages all Monsters. L2MonsterInstance :<BR> * <BR> * <li>L2RaidBossInstance</li> <li>L2GrandBossInstance</li> */ public class L2MonsterInstance extends L2Attackable { protected boolean _enableMinions = true; private L2MonsterInstance _master = null; private MinionList _minionList = null; protected ScheduledFuture<?> _maintenanceTask = null; private static final int MONSTER_MAINTENANCE_INTERVAL = 1000; /** * Constructor of L2MonsterInstance (use L2Character and L2NpcInstance constructor).<BR> * <BR> * <B><U> Actions</U> :</B><BR> * <BR> * <li>Call the L2Character constructor to set the _template of the L2MonsterInstance (copy skills from template to object and link * _calculators to NPC_STD_CALCULATOR)</li> <li>Set the name of the L2MonsterInstance</li> <li>Create a RandomAnimation Task that will be * launched after the calculated delay if the server allow it</li><BR> * <BR> * * @param objectId * Identifier of the object to initialized * @param template * L2NpcTemplate to apply to the NPC */ public L2MonsterInstance(int objectId, L2NpcTemplate template) { super(objectId, template); } @Override public void initKnownList() { setKnownList(new MonsterKnownList(this)); } @Override public final MonsterKnownList getKnownList() { return (MonsterKnownList) super.getKnownList(); } /** * Return True if the attacker is not another L2MonsterInstance.<BR> * <BR> */ @Override public boolean isAutoAttackable(L2Character attacker) { // FIXME: to test to allow monsters hit others monsters if (attacker instanceof L2MonsterInstance) return false; return true; } /** * Return True if the L2MonsterInstance is Agressive (aggroRange > 0).<BR> * <BR> */ @Override public boolean isAggressive() { return (getAggroRange() > 0); } @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; } /** * Spawn all minions at a regular interval */ protected void startMaintenanceTask() { // maintenance task now used only for minions spawn if (getTemplate().getMinionData() == null) return; if (_maintenanceTask == null) { _maintenanceTask = ThreadPoolManager.getInstance().scheduleGeneral(new Runnable() { @Override public void run() { if (_enableMinions) getMinionList().spawnMinions(); } }, getMaintenanceInterval() + Rnd.get(1000)); } } @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 void deleteMe() { if (_maintenanceTask != null) { _maintenanceTask.cancel(false); _maintenanceTask = null; } if (hasMinions()) getMinionList().onMasterDie(true); if (getLeader() != null) getLeader().getMinionList().onMinionDie(this, 0); 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) _minionList = new MinionList(this); return _minionList; } }