/* * 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 . */ package com.l2jserver.gameserver.model; import com.l2jserver.Config; import com.l2jserver.gameserver.idfactory.IdFactory; import com.l2jserver.gameserver.instancemanager.InstanceManager; import com.l2jserver.gameserver.instancemanager.ItemsOnGroundManager; import com.l2jserver.gameserver.model.actor.L2Character; import com.l2jserver.gameserver.model.actor.L2Npc; import com.l2jserver.gameserver.model.actor.instance.L2PcInstance; import com.l2jserver.gameserver.model.actor.knownlist.ObjectKnownList; import com.l2jserver.gameserver.model.actor.poly.ObjectPoly; import com.l2jserver.gameserver.model.actor.position.ObjectPosition; import com.l2jserver.gameserver.network.L2GameClient; import com.l2jserver.gameserver.network.serverpackets.ActionFailed; import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket; /** * Mother class of all objects in the world wich ones is it possible * to interact (PC, NPC, Item...)

* * L2Object :

*
  • L2Character
  • *
  • L2ItemInstance
  • *
  • L2Potion
  • * */ public abstract class L2Object { // ========================================================= // Data Field private boolean _isVisible; // Object visibility private ObjectKnownList _knownList; private String _name; private int _objectId; // Object identifier private ObjectPoly _poly; private ObjectPosition _position; private int _instanceId = 0; // ========================================================= // Constructor public L2Object(int objectId) { _objectId = objectId; initKnownList(); initPosition(); } // ========================================================= // Event - Public public final void onAction(L2PcInstance player) { onAction(player, true); } public void onAction(L2PcInstance player, boolean interact) { player.sendPacket(ActionFailed.STATIC_PACKET); } @Deprecated public void onActionShift(L2GameClient client) { client.getActiveChar().sendPacket(ActionFailed.STATIC_PACKET); } public void onActionShift(L2PcInstance player) { player.sendPacket(ActionFailed.STATIC_PACKET); } public void onForcedAttack(L2PcInstance player) { player.sendPacket(ActionFailed.STATIC_PACKET); } /** * Do Nothing.

    * * Overridden in :

    *
  • L2GuardInstance : Set the home location of its L2GuardInstance
  • *
  • L2Attackable : Reset the Spoiled flag


  • * */ public void onSpawn() { } // ========================================================= // Position - Should remove to fully move to L2ObjectPosition public final void setXYZ(int x, int y, int z) { getPosition().setXYZ(x, y, z); } public final void setXYZInvisible(int x, int y, int z) { getPosition().setXYZInvisible(x, y, z); } public final int getX() { if (Config.ASSERT) assert getPosition().getWorldRegion() != null || _isVisible; return getPosition().getX(); } /** * @return The id of the instance zone the object is in - id 0 is global * since everything like dropped items, mobs, players can be in a instanciated area, it must be in l2object */ public int getInstanceId() { return _instanceId; } /** * @param instanceId The id of the instance zone the object is in - id 0 is global */ public void setInstanceId(int instanceId) { if (_instanceId == instanceId) return; if (this instanceof L2PcInstance) { if (_instanceId > 0) InstanceManager.getInstance().getInstance(_instanceId).removePlayer(getObjectId()); if (instanceId > 0) InstanceManager.getInstance().getInstance(instanceId).addPlayer(getObjectId()); if (((L2PcInstance)this).getPet() != null) ((L2PcInstance)this).getPet().setInstanceId(instanceId); } else if (this instanceof L2Npc) { if (_instanceId > 0) InstanceManager.getInstance().getInstance(_instanceId).removeNpc(((L2Npc)this)); if (instanceId > 0) InstanceManager.getInstance().getInstance(instanceId).addNpc(((L2Npc)this)); } _instanceId = instanceId; // If we change it for visible objects, me must clear & revalidate knownlists if (_isVisible && _knownList != null) { if (this instanceof L2PcInstance) { // We don't want some ugly looking disappear/appear effects, so don't update // the knownlist here, but players usually enter instancezones through teleporting // and the teleport will do the revalidation for us. } else { decayMe(); spawnMe(); } } } public final int getY() { if (Config.ASSERT) assert getPosition().getWorldRegion() != null || _isVisible; return getPosition().getY(); } public final int getZ() { if (Config.ASSERT) assert getPosition().getWorldRegion() != null || _isVisible; return getPosition().getZ(); } // ========================================================= // Method - Public /** * Remove a L2Object from the world.

    * * Actions :

    *
  • Remove the L2Object from the world


  • * * Caution : This method DOESN'T REMOVE the object from _allObjects of L2World
    * Caution : This method DOESN'T SEND Server->Client packets to players

    * * Assert :

    *
  • _worldRegion != null (L2Object is visible at the beginning)


  • * * Example of use :

    *
  • Delete NPC/PC or Unsummon


  • * */ public final void decayMe() { if (Config.ASSERT) assert getPosition().getWorldRegion() != null; L2WorldRegion reg = getPosition().getWorldRegion(); synchronized (this) { _isVisible = false; getPosition().setWorldRegion(null); } // this can synchronize on others instancies, so it's out of // synchronized, to avoid deadlocks // Remove the L2Object from the world L2World.getInstance().removeVisibleObject(this, reg); L2World.getInstance().removeObject(this); if (Config.SAVE_DROPPED_ITEM) ItemsOnGroundManager.getInstance().removeObject(this); } public void refreshID() { L2World.getInstance().removeObject(this); IdFactory.getInstance().releaseId(getObjectId()); _objectId = IdFactory.getInstance().getNextId(); } /** * Init the position of a L2Object spawn and add it in the world as a visible object.

    * * Actions :

    *
  • Set the x,y,z position of the L2Object spawn and update its _worldregion
  • *
  • Add the L2Object spawn in the _allobjects of L2World
  • *
  • Add the L2Object spawn to _visibleObjects of its L2WorldRegion
  • *
  • Add the L2Object spawn in the world as a visible object


  • * * Assert :

    *
  • _worldRegion == null (L2Object is invisible at the beginning)


  • * * Example of use :

    *
  • Create Door
  • *
  • Spawn : Monster, Minion, CTs, Summon...

  • * */ public final void spawnMe() { if (Config.ASSERT) assert getPosition().getWorldRegion() == null && getPosition().getWorldPosition().getX() != 0 && getPosition().getWorldPosition().getY() != 0 && getPosition().getWorldPosition().getZ() != 0; synchronized (this) { // Set the x,y,z position of the L2Object spawn and update its _worldregion _isVisible = true; getPosition().setWorldRegion(L2World.getInstance().getRegion(getPosition().getWorldPosition())); // Add the L2Object spawn in the _allobjects of L2World L2World.getInstance().storeObject(this); // Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion getPosition().getWorldRegion().addVisibleObject(this); } // this can synchronize on others instancies, so it's out of // synchronized, to avoid deadlocks // Add the L2Object spawn in the world as a visible object L2World.getInstance().addVisibleObject(this, getPosition().getWorldRegion()); onSpawn(); } public final void spawnMe(int x, int y, int z) { if (Config.ASSERT) assert getPosition().getWorldRegion() == null; synchronized (this) { // Set the x,y,z position of the L2Object spawn and update its _worldregion _isVisible = true; if (x > L2World.MAP_MAX_X) x = L2World.MAP_MAX_X - 5000; if (x < L2World.MAP_MIN_X) x = L2World.MAP_MIN_X + 5000; if (y > L2World.MAP_MAX_Y) y = L2World.MAP_MAX_Y - 5000; if (y < L2World.MAP_MIN_Y) y = L2World.MAP_MIN_Y + 5000; getPosition().setWorldPosition(x, y ,z); getPosition().setWorldRegion(L2World.getInstance().getRegion(getPosition().getWorldPosition())); // Add the L2Object spawn in the _allobjects of L2World } L2World.getInstance().storeObject(this); // these can synchronize on others instancies, so they're out of // synchronized, to avoid deadlocks // Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion getPosition().getWorldRegion().addVisibleObject(this); // Add the L2Object spawn in the world as a visible object L2World.getInstance().addVisibleObject(this, getPosition().getWorldRegion()); onSpawn(); } public void toggleVisible() { if (isVisible()) decayMe(); else spawnMe(); } // ========================================================= // Method - Private // ========================================================= // Property - Public public boolean isAttackable() { return false; } public abstract boolean isAutoAttackable(L2Character attacker); public boolean isMarker() { return false; } /** * Return the visibilty state of the L2Object.

    * * Concept :

    * A L2Object is visble if __IsVisible=true and _worldregion!=null

    */ public final boolean isVisible() { //return getPosition().getWorldRegion() != null && _IsVisible; return getPosition().getWorldRegion() != null; } public final void setIsVisible(boolean value) { _isVisible = value; if (!_isVisible) getPosition().setWorldRegion(null); } public ObjectKnownList getKnownList() { return _knownList; } /** * Initializes the KnownList of the L2Object, * is overwritten in classes that require a different knownlist Type. * * Removes the need for instanceof checks. */ public void initKnownList() { _knownList = new ObjectKnownList(this); } public final void setKnownList(ObjectKnownList value) { _knownList = value; } public final String getName() { return _name; } public final void setName(String value) { _name = value; } public final int getObjectId() { return _objectId; } public final ObjectPoly getPoly() { if (_poly == null) _poly = new ObjectPoly(this); return _poly; } public ObjectPosition getPosition() { return _position; } /** * Initializes the Position class of the L2Object, * is overwritten in classes that require a different position Type. * * Removes the need for instanceof checks. */ public void initPosition() { _position = new ObjectPosition(this); } public final void setObjectPosition(ObjectPosition value) { _position = value; } /** * returns reference to region this object is in */ public L2WorldRegion getWorldRegion() { return getPosition().getWorldRegion(); } public L2PcInstance getActingPlayer() { return null; } /** * Sends the Server->Client info packet for the object.

    * Is Overridden in: *
  • L2AirShipInstance
  • *
  • L2BoatInstance
  • *
  • L2DoorInstance
  • *
  • L2PcInstance
  • *
  • L2StaticObjectInstance
  • *
  • L2Decoy
  • *
  • L2Npc
  • *
  • L2Summon
  • *
  • L2Trap
  • *
  • L2ItemInstance
  • */ public void sendInfo(L2PcInstance activeChar) { } @Override public String toString() { return "" + getObjectId(); } /** * Not Implemented.

    * * Overridden in :

    *
  • L2PcInstance


  • */ public void sendPacket(L2GameServerPacket mov) { // default implementation } }