 d722c7a961
			
		
	
	d722c7a961
	
	
	
		
			
			-Added <target hp="n%" /> condition (example - Last Attack skill). -Updated DamOverTime effect - add increase charges count over time. -Updated EnergyAttack effect to new charges system. -Updated FatalBlow effect (able to increase skill power damage if target has affected by selected abnormal type). -Added parameter ignorePhysDefPercent for skills that ignores some % of enemy pDef. -Added function isInvulnerableFor(player) and updated PcCondOverride for this function. -NPC and NPC buffers data updated for Othell Ground skill Poison Zone. -Updated PhysicalAttack effect for skills, that decreases power when using some weapon types, and increases power when using some weapon types. also added isLastAttack parameter (for skill Last Attack atm). -Added stat momentumSkillPower (for Tyrr' passive). Increases power when player have more charges (max 3). -Updated some effect for working with maxSkillDamage parameter. -Updated some old and new skills to 10531. Contributed by NviX.
		
			
				
	
	
		
			1031 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			1031 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| /*
 | |
|  * Copyright (C) 2004-2015 L2J Server
 | |
|  * 
 | |
|  * This file is part of L2J Server.
 | |
|  * 
 | |
|  * L2J Server is free software: you can redistribute it and/or modify
 | |
|  * it under the terms of the GNU General Public License as published by
 | |
|  * the Free Software Foundation, either version 3 of the License, or
 | |
|  * (at your option) any later version.
 | |
|  * 
 | |
|  * L2J Server is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 | |
|  * General Public License for more details.
 | |
|  * 
 | |
|  * You should have received a copy of the GNU General Public License
 | |
|  * along with this program. If not, see <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| package com.l2jserver.gameserver.model;
 | |
| 
 | |
| import java.util.Map;
 | |
| import java.util.concurrent.ConcurrentHashMap;
 | |
| import java.util.concurrent.atomic.AtomicInteger;
 | |
| 
 | |
| import com.l2jserver.gameserver.enums.InstanceType;
 | |
| import com.l2jserver.gameserver.enums.ShotType;
 | |
| import com.l2jserver.gameserver.handler.ActionHandler;
 | |
| import com.l2jserver.gameserver.handler.ActionShiftHandler;
 | |
| import com.l2jserver.gameserver.handler.IActionHandler;
 | |
| import com.l2jserver.gameserver.handler.IActionShiftHandler;
 | |
| import com.l2jserver.gameserver.idfactory.IdFactory;
 | |
| import com.l2jserver.gameserver.instancemanager.InstanceManager;
 | |
| import com.l2jserver.gameserver.model.actor.L2Character;
 | |
| import com.l2jserver.gameserver.model.actor.L2Npc;
 | |
| import com.l2jserver.gameserver.model.actor.L2Summon;
 | |
| 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.entity.Instance;
 | |
| import com.l2jserver.gameserver.model.events.ListenersContainer;
 | |
| import com.l2jserver.gameserver.model.interfaces.IDecayable;
 | |
| import com.l2jserver.gameserver.model.interfaces.IIdentifiable;
 | |
| import com.l2jserver.gameserver.model.interfaces.ILocational;
 | |
| import com.l2jserver.gameserver.model.interfaces.INamable;
 | |
| import com.l2jserver.gameserver.model.interfaces.IPositionable;
 | |
| import com.l2jserver.gameserver.model.interfaces.ISpawnable;
 | |
| import com.l2jserver.gameserver.model.interfaces.IUniqueId;
 | |
| import com.l2jserver.gameserver.model.zone.ZoneId;
 | |
| import com.l2jserver.gameserver.network.SystemMessageId;
 | |
| import com.l2jserver.gameserver.network.serverpackets.ActionFailed;
 | |
| import com.l2jserver.gameserver.network.serverpackets.DeleteObject;
 | |
| import com.l2jserver.gameserver.network.serverpackets.ExSendUIEvent;
 | |
| import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
 | |
| import com.l2jserver.gameserver.util.Util;
 | |
| 
 | |
| /**
 | |
|  * Base class for all interactive objects.
 | |
|  */
 | |
| public abstract class L2Object extends ListenersContainer implements IIdentifiable, INamable, ISpawnable, IUniqueId, IDecayable, IPositionable
 | |
| {
 | |
| 	/** Name */
 | |
| 	private String _name;
 | |
| 	/** Object ID */
 | |
| 	private int _objectId;
 | |
| 	/** World Region */
 | |
| 	private L2WorldRegion _worldRegion;
 | |
| 	/** Instance type */
 | |
| 	private InstanceType _instanceType = null;
 | |
| 	private volatile Map<String, Object> _scripts;
 | |
| 	/** X coordinate */
 | |
| 	private final AtomicInteger _x = new AtomicInteger(0);
 | |
| 	/** Y coordinate */
 | |
| 	private final AtomicInteger _y = new AtomicInteger(0);
 | |
| 	/** Z coordinate */
 | |
| 	private final AtomicInteger _z = new AtomicInteger(0);
 | |
| 	/** Orientation */
 | |
| 	private final AtomicInteger _heading = new AtomicInteger(0);
 | |
| 	/** Instance id of object. 0 - Global */
 | |
| 	private final AtomicInteger _instanceId = new AtomicInteger(0);
 | |
| 	private boolean _isVisible;
 | |
| 	private boolean _isInvisible;
 | |
| 	private ObjectKnownList _knownList;
 | |
| 	
 | |
| 	public L2Object(int objectId)
 | |
| 	{
 | |
| 		setInstanceType(InstanceType.L2Object);
 | |
| 		_objectId = objectId;
 | |
| 		initKnownList();
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Gets the instance type of object.
 | |
| 	 * @return the instance type
 | |
| 	 */
 | |
| 	public final InstanceType getInstanceType()
 | |
| 	{
 | |
| 		return _instanceType;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Sets the instance type.
 | |
| 	 * @param newInstanceType the instance type to set
 | |
| 	 */
 | |
| 	protected final void setInstanceType(InstanceType newInstanceType)
 | |
| 	{
 | |
| 		_instanceType = newInstanceType;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verifies if object is of any given instance types.
 | |
| 	 * @param instanceTypes the instance types to verify
 | |
| 	 * @return {@code true} if object is of any given instance types, {@code false} otherwise
 | |
| 	 */
 | |
| 	public final boolean isInstanceTypes(InstanceType... instanceTypes)
 | |
| 	{
 | |
| 		return _instanceType.isTypes(instanceTypes);
 | |
| 	}
 | |
| 	
 | |
| 	public final void onAction(L2PcInstance player)
 | |
| 	{
 | |
| 		onAction(player, true);
 | |
| 	}
 | |
| 	
 | |
| 	public void onAction(L2PcInstance player, boolean interact)
 | |
| 	{
 | |
| 		IActionHandler handler = ActionHandler.getInstance().getHandler(getInstanceType());
 | |
| 		if (handler != null)
 | |
| 		{
 | |
| 			handler.action(player, this, interact);
 | |
| 		}
 | |
| 		
 | |
| 		player.sendPacket(ActionFailed.STATIC_PACKET);
 | |
| 	}
 | |
| 	
 | |
| 	public void onActionShift(L2PcInstance player)
 | |
| 	{
 | |
| 		IActionShiftHandler handler = ActionShiftHandler.getInstance().getHandler(getInstanceType());
 | |
| 		if (handler != null)
 | |
| 		{
 | |
| 			handler.action(player, this, true);
 | |
| 		}
 | |
| 		
 | |
| 		player.sendPacket(ActionFailed.STATIC_PACKET);
 | |
| 	}
 | |
| 	
 | |
| 	public void onForcedAttack(L2PcInstance player)
 | |
| 	{
 | |
| 		player.sendPacket(ActionFailed.STATIC_PACKET);
 | |
| 	}
 | |
| 	
 | |
| 	public void onSpawn()
 | |
| 	{
 | |
| 	}
 | |
| 	
 | |
| 	@Override
 | |
| 	public boolean decayMe()
 | |
| 	{
 | |
| 		assert getWorldRegion() != null;
 | |
| 		
 | |
| 		L2WorldRegion reg = getWorldRegion();
 | |
| 		
 | |
| 		synchronized (this)
 | |
| 		{
 | |
| 			_isVisible = false;
 | |
| 			setWorldRegion(null);
 | |
| 		}
 | |
| 		
 | |
| 		// this can synchronize on others instances, so it's out of
 | |
| 		// synchronized, to avoid deadlocks
 | |
| 		// Remove the L2Object from the world
 | |
| 		L2World.getInstance().removeVisibleObject(this, reg);
 | |
| 		L2World.getInstance().removeObject(this);
 | |
| 		
 | |
| 		return true;
 | |
| 	}
 | |
| 	
 | |
| 	public void refreshID()
 | |
| 	{
 | |
| 		L2World.getInstance().removeObject(this);
 | |
| 		IdFactory.getInstance().releaseId(getObjectId());
 | |
| 		_objectId = IdFactory.getInstance().getNextId();
 | |
| 	}
 | |
| 	
 | |
| 	@Override
 | |
| 	public final boolean spawnMe()
 | |
| 	{
 | |
| 		assert(getWorldRegion() == null) && (getLocation().getX() != 0) && (getLocation().getY() != 0) && (getLocation().getZ() != 0);
 | |
| 		
 | |
| 		synchronized (this)
 | |
| 		{
 | |
| 			// Set the x,y,z position of the L2Object spawn and update its _worldregion
 | |
| 			_isVisible = true;
 | |
| 			setWorldRegion(L2World.getInstance().getRegion(getLocation()));
 | |
| 			
 | |
| 			// 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
 | |
| 			getWorldRegion().addVisibleObject(this);
 | |
| 		}
 | |
| 		
 | |
| 		// this can synchronize on others instances, so it's out of synchronized, to avoid deadlocks
 | |
| 		// Add the L2Object spawn in the world as a visible object
 | |
| 		L2World.getInstance().addVisibleObject(this, getWorldRegion());
 | |
| 		
 | |
| 		onSpawn();
 | |
| 		
 | |
| 		return true;
 | |
| 	}
 | |
| 	
 | |
| 	public final void spawnMe(int x, int y, int z)
 | |
| 	{
 | |
| 		assert 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;
 | |
| 			}
 | |
| 			
 | |
| 			setXYZ(x, y, z);
 | |
| 			setWorldRegion(L2World.getInstance().getRegion(getLocation()));
 | |
| 			
 | |
| 			// Add the L2Object spawn in the _allobjects of L2World
 | |
| 		}
 | |
| 		
 | |
| 		L2World.getInstance().storeObject(this);
 | |
| 		
 | |
| 		// these can synchronize on others instances, so they're out of
 | |
| 		// synchronized, to avoid deadlocks
 | |
| 		
 | |
| 		// Add the L2Object spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
 | |
| 		getWorldRegion().addVisibleObject(this);
 | |
| 		
 | |
| 		// Add the L2Object spawn in the world as a visible object
 | |
| 		L2World.getInstance().addVisibleObject(this, getWorldRegion());
 | |
| 		
 | |
| 		onSpawn();
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verify if object can be attacked.
 | |
| 	 * @return {@code true} if object can be attacked, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean canBeAttacked()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	public abstract boolean isAutoAttackable(L2Character attacker);
 | |
| 	
 | |
| 	public final boolean isVisible()
 | |
| 	{
 | |
| 		return getWorldRegion() != null;
 | |
| 	}
 | |
| 	
 | |
| 	public final void setIsVisible(boolean value)
 | |
| 	{
 | |
| 		_isVisible = value;
 | |
| 		if (!_isVisible)
 | |
| 		{
 | |
| 			setWorldRegion(null);
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	public void toggleVisible()
 | |
| 	{
 | |
| 		if (isVisible())
 | |
| 		{
 | |
| 			decayMe();
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			spawnMe();
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	public ObjectKnownList getKnownList()
 | |
| 	{
 | |
| 		return _knownList;
 | |
| 	}
 | |
| 	
 | |
| 	public void initKnownList()
 | |
| 	{
 | |
| 		_knownList = new ObjectKnownList(this);
 | |
| 	}
 | |
| 	
 | |
| 	public final void setKnownList(ObjectKnownList value)
 | |
| 	{
 | |
| 		_knownList = value;
 | |
| 	}
 | |
| 	
 | |
| 	@Override
 | |
| 	public String getName()
 | |
| 	{
 | |
| 		return _name;
 | |
| 	}
 | |
| 	
 | |
| 	public void setName(String value)
 | |
| 	{
 | |
| 		_name = value;
 | |
| 	}
 | |
| 	
 | |
| 	@Override
 | |
| 	public final int getObjectId()
 | |
| 	{
 | |
| 		return _objectId;
 | |
| 	}
 | |
| 	
 | |
| 	public final ObjectPoly getPoly()
 | |
| 	{
 | |
| 		final ObjectPoly poly = getScript(ObjectPoly.class);
 | |
| 		return (poly == null) ? addScript(new ObjectPoly(this)) : poly;
 | |
| 	}
 | |
| 	
 | |
| 	public abstract void sendInfo(L2PcInstance activeChar);
 | |
| 	
 | |
| 	public void sendPacket(L2GameServerPacket mov)
 | |
| 	{
 | |
| 	}
 | |
| 	
 | |
| 	public void sendPacket(SystemMessageId id)
 | |
| 	{
 | |
| 	}
 | |
| 	
 | |
| 	public L2PcInstance getActingPlayer()
 | |
| 	{
 | |
| 		return null;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verify if object is instance of L2Attackable.
 | |
| 	 * @return {@code true} if object is instance of L2Attackable, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isAttackable()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verify if object is instance of L2Character.
 | |
| 	 * @return {@code true} if object is instance of L2Character, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isCharacter()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verify if object is instance of L2DoorInstance.
 | |
| 	 * @return {@code true} if object is instance of L2DoorInstance, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isDoor()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verify if object is instance of L2MonsterInstance.
 | |
| 	 * @return {@code true} if object is instance of L2MonsterInstance, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isMonster()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verify if object is instance of L2Npc.
 | |
| 	 * @return {@code true} if object is instance of L2Npc, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isNpc()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verify if object is instance of L2PetInstance.
 | |
| 	 * @return {@code true} if object is instance of L2PetInstance, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isPet()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verify if object is instance of L2PcInstance.
 | |
| 	 * @return {@code true} if object is instance of L2PcInstance, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isPlayer()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verify if object is instance of L2Playable.
 | |
| 	 * @return {@code true} if object is instance of L2Playable, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isPlayable()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verify if object is instance of L2ServitorInstance.
 | |
| 	 * @return {@code true} if object is instance of L2ServitorInstance, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isServitor()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verify if object is instance of L2Summon.
 | |
| 	 * @return {@code true} if object is instance of L2Summon, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isSummon()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verify if object is instance of L2TrapInstance.
 | |
| 	 * @return {@code true} if object is instance of L2TrapInstance, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isTrap()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verify if object is instance of L2ItemInstance.
 | |
| 	 * @return {@code true} if object is instance of L2ItemInstance, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isItem()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verifies if the object is a walker NPC.
 | |
| 	 * @return {@code true} if object is a walker NPC, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isWalker()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Verifies if this object is a vehicle.
 | |
| 	 * @return {@code true} if object is Vehicle, {@code false} otherwise
 | |
| 	 */
 | |
| 	public boolean isVehicle()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * @return {@code true} if object Can be targeted
 | |
| 	 */
 | |
| 	public boolean isTargetable()
 | |
| 	{
 | |
| 		return true;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Check if the object is in the given zone Id.
 | |
| 	 * @param zone the zone Id to check
 | |
| 	 * @return {@code true} if the object is in that zone Id
 | |
| 	 */
 | |
| 	public boolean isInsideZone(ZoneId zone)
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Check if current object has charged shot.
 | |
| 	 * @param type of the shot to be checked.
 | |
| 	 * @return {@code true} if the object has charged shot
 | |
| 	 */
 | |
| 	public boolean isChargedShot(ShotType type)
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Charging shot into the current object.
 | |
| 	 * @param type of the shot to be charged.
 | |
| 	 * @param charged
 | |
| 	 */
 | |
| 	public void setChargedShot(ShotType type, boolean charged)
 | |
| 	{
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Try to recharge a shot.
 | |
| 	 * @param physical skill are using Soul shots.
 | |
| 	 * @param magical skill are using Spirit shots.
 | |
| 	 */
 | |
| 	public void rechargeShots(boolean physical, boolean magical)
 | |
| 	{
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * @param <T>
 | |
| 	 * @param script
 | |
| 	 * @return
 | |
| 	 */
 | |
| 	public final <T> T addScript(T script)
 | |
| 	{
 | |
| 		if (_scripts == null)
 | |
| 		{
 | |
| 			synchronized (this)
 | |
| 			{
 | |
| 				if (_scripts == null)
 | |
| 				{
 | |
| 					_scripts = new ConcurrentHashMap<>();
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		_scripts.put(script.getClass().getName(), script);
 | |
| 		return script;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * @param <T>
 | |
| 	 * @param script
 | |
| 	 * @return
 | |
| 	 */
 | |
| 	@SuppressWarnings("unchecked")
 | |
| 	public final <T> T removeScript(Class<T> script)
 | |
| 	{
 | |
| 		if (_scripts == null)
 | |
| 		{
 | |
| 			return null;
 | |
| 		}
 | |
| 		return (T) _scripts.remove(script.getName());
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * @param <T>
 | |
| 	 * @param script
 | |
| 	 * @return
 | |
| 	 */
 | |
| 	@SuppressWarnings("unchecked")
 | |
| 	public final <T> T getScript(Class<T> script)
 | |
| 	{
 | |
| 		if (_scripts == null)
 | |
| 		{
 | |
| 			return null;
 | |
| 		}
 | |
| 		return (T) _scripts.get(script.getName());
 | |
| 	}
 | |
| 	
 | |
| 	public void removeStatusListener(L2Character object)
 | |
| 	{
 | |
| 	
 | |
| 	}
 | |
| 	
 | |
| 	protected void badCoords()
 | |
| 	{
 | |
| 		if (isCharacter())
 | |
| 		{
 | |
| 			decayMe();
 | |
| 		}
 | |
| 		else if (isPlayer())
 | |
| 		{
 | |
| 			((L2Character) this).teleToLocation(new Location(0, 0, 0), false);
 | |
| 			((L2Character) this).sendMessage("Error with your coords, Please ask a GM for help!");
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	public final void setXYZInvisible(int x, int y, int z)
 | |
| 	{
 | |
| 		assert getWorldRegion() == null;
 | |
| 		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;
 | |
| 		}
 | |
| 		
 | |
| 		setXYZ(x, y, z);
 | |
| 		setIsVisible(false);
 | |
| 	}
 | |
| 	
 | |
| 	public final void setLocationInvisible(ILocational loc)
 | |
| 	{
 | |
| 		setXYZInvisible(loc.getX(), loc.getY(), loc.getZ());
 | |
| 	}
 | |
| 	
 | |
| 	public void updateWorldRegion()
 | |
| 	{
 | |
| 		if (!isVisible())
 | |
| 		{
 | |
| 			return;
 | |
| 		}
 | |
| 		
 | |
| 		L2WorldRegion newRegion = L2World.getInstance().getRegion(getLocation());
 | |
| 		if (newRegion != getWorldRegion())
 | |
| 		{
 | |
| 			getWorldRegion().removeVisibleObject(this);
 | |
| 			
 | |
| 			setWorldRegion(newRegion);
 | |
| 			
 | |
| 			// Add the L2Oject spawn to _visibleObjects and if necessary to _allplayers of its L2WorldRegion
 | |
| 			getWorldRegion().addVisibleObject(this);
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	public final L2WorldRegion getWorldRegion()
 | |
| 	{
 | |
| 		return _worldRegion;
 | |
| 	}
 | |
| 	
 | |
| 	public void setWorldRegion(L2WorldRegion value)
 | |
| 	{
 | |
| 		if ((getWorldRegion() != null) && isCharacter()) // confirm revalidation of old region's zones
 | |
| 		{
 | |
| 			if (value != null)
 | |
| 			{
 | |
| 				getWorldRegion().revalidateZones((L2Character) this); // at world region change
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				getWorldRegion().removeFromZones((L2Character) this); // at world region change
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		_worldRegion = value;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Gets the X coordinate.
 | |
| 	 * @return the X coordinate
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public int getX()
 | |
| 	{
 | |
| 		return _x.get();
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Gets the Y coordinate.
 | |
| 	 * @return the Y coordinate
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public int getY()
 | |
| 	{
 | |
| 		return _y.get();
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Gets the Z coordinate.
 | |
| 	 * @return the Z coordinate
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public int getZ()
 | |
| 	{
 | |
| 		return _z.get();
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Gets the heading.
 | |
| 	 * @return the heading
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public int getHeading()
 | |
| 	{
 | |
| 		return _heading.get();
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Gets the instance ID.
 | |
| 	 * @return the instance ID
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public int getInstanceId()
 | |
| 	{
 | |
| 		return _instanceId.get();
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Gets the location object.
 | |
| 	 * @return the location object
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public Location getLocation()
 | |
| 	{
 | |
| 		return new Location(getX(), getY(), getZ(), getHeading(), getInstanceId());
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Sets the X coordinate
 | |
| 	 * @param newX the X coordinate
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public void setX(int newX)
 | |
| 	{
 | |
| 		_x.set(newX);
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Sets the Y coordinate
 | |
| 	 * @param newY the Y coordinate
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public void setY(int newY)
 | |
| 	{
 | |
| 		_y.set(newY);
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Sets the Z coordinate
 | |
| 	 * @param newZ the Z coordinate
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public void setZ(int newZ)
 | |
| 	{
 | |
| 		_z.set(newZ);
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Sets the x, y, z coordinate.
 | |
| 	 * @param newX the X coordinate
 | |
| 	 * @param newY the Y coordinate
 | |
| 	 * @param newZ the Z coordinate
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public final void setXYZ(int newX, int newY, int newZ)
 | |
| 	{
 | |
| 		assert getWorldRegion() != null;
 | |
| 		
 | |
| 		setX(newX);
 | |
| 		setY(newY);
 | |
| 		setZ(newZ);
 | |
| 		
 | |
| 		try
 | |
| 		{
 | |
| 			if (L2World.getInstance().getRegion(getLocation()) != getWorldRegion())
 | |
| 			{
 | |
| 				updateWorldRegion();
 | |
| 			}
 | |
| 		}
 | |
| 		catch (Exception e)
 | |
| 		{
 | |
| 			badCoords();
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Sets the x, y, z coordinate.
 | |
| 	 * @param loc the location object
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public void setXYZ(ILocational loc)
 | |
| 	{
 | |
| 		setXYZ(loc.getX(), loc.getY(), loc.getZ());
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Sets heading of object.
 | |
| 	 * @param newHeading the new heading
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public void setHeading(int newHeading)
 | |
| 	{
 | |
| 		_heading.set(newHeading);
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Sets the instance ID of object.<br>
 | |
| 	 * 0 - Global<br>
 | |
| 	 * TODO: Add listener here.
 | |
| 	 * @param instanceId the ID of the instance
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public void setInstanceId(int instanceId)
 | |
| 	{
 | |
| 		if ((instanceId < 0) || (getInstanceId() == instanceId))
 | |
| 		{
 | |
| 			return;
 | |
| 		}
 | |
| 		
 | |
| 		Instance oldI = InstanceManager.getInstance().getInstance(getInstanceId());
 | |
| 		Instance newI = InstanceManager.getInstance().getInstance(instanceId);
 | |
| 		if (newI == null)
 | |
| 		{
 | |
| 			return;
 | |
| 		}
 | |
| 		
 | |
| 		if (isPlayer())
 | |
| 		{
 | |
| 			final L2PcInstance player = getActingPlayer();
 | |
| 			if ((getInstanceId() > 0) && (oldI != null))
 | |
| 			{
 | |
| 				oldI.removePlayer(getObjectId());
 | |
| 				if (oldI.isShowTimer())
 | |
| 				{
 | |
| 					sendInstanceUpdate(oldI, true);
 | |
| 				}
 | |
| 			}
 | |
| 			if (instanceId > 0)
 | |
| 			{
 | |
| 				newI.addPlayer(getObjectId());
 | |
| 				if (newI.isShowTimer())
 | |
| 				{
 | |
| 					sendInstanceUpdate(newI, false);
 | |
| 				}
 | |
| 			}
 | |
| 			final L2Summon pet = player.getPet();
 | |
| 			if (pet != null)
 | |
| 			{
 | |
| 				pet.setInstanceId(instanceId);
 | |
| 			}
 | |
| 			player.getServitors().values().forEach(s -> s.setInstanceId(instanceId));
 | |
| 		}
 | |
| 		else if (isNpc())
 | |
| 		{
 | |
| 			final L2Npc npc = (L2Npc) this;
 | |
| 			if ((getInstanceId() > 0) && (oldI != null))
 | |
| 			{
 | |
| 				oldI.removeNpc(npc);
 | |
| 			}
 | |
| 			if (instanceId > 0)
 | |
| 			{
 | |
| 				newI.addNpc(npc);
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		_instanceId.set(instanceId);
 | |
| 		if (_isVisible && (_knownList != null))
 | |
| 		{
 | |
| 			// 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.
 | |
| 			if (!isPlayer())
 | |
| 			{
 | |
| 				decayMe();
 | |
| 				spawnMe();
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Sets location of object.
 | |
| 	 * @param loc the location object
 | |
| 	 */
 | |
| 	@Override
 | |
| 	public void setLocation(Location loc)
 | |
| 	{
 | |
| 		_x.set(loc.getX());
 | |
| 		_y.set(loc.getY());
 | |
| 		_z.set(loc.getZ());
 | |
| 		_heading.set(loc.getHeading());
 | |
| 		_instanceId.set(loc.getInstanceId());
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Calculates distance between this L2Object and given x, y , z.
 | |
| 	 * @param x the X coordinate
 | |
| 	 * @param y the Y coordinate
 | |
| 	 * @param z the Z coordinate
 | |
| 	 * @param includeZAxis if {@code true} Z axis will be included
 | |
| 	 * @param squared if {@code true} return will be squared
 | |
| 	 * @return distance between object and given x, y, z.
 | |
| 	 */
 | |
| 	public final double calculateDistance(int x, int y, int z, boolean includeZAxis, boolean squared)
 | |
| 	{
 | |
| 		final double distance = Math.pow(x - getX(), 2) + Math.pow(y - getY(), 2) + (includeZAxis ? Math.pow(z - getZ(), 2) : 0);
 | |
| 		return (squared) ? distance : Math.sqrt(distance);
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Calculates distance between this L2Object and given location.
 | |
| 	 * @param loc the location object
 | |
| 	 * @param includeZAxis if {@code true} Z axis will be included
 | |
| 	 * @param squared if {@code true} return will be squared
 | |
| 	 * @return distance between object and given location.
 | |
| 	 */
 | |
| 	public final double calculateDistance(ILocational loc, boolean includeZAxis, boolean squared)
 | |
| 	{
 | |
| 		return calculateDistance(loc.getX(), loc.getY(), loc.getZ(), includeZAxis, squared);
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Calculates the angle in degrees from this object to the given object.<br>
 | |
| 	 * The return value can be described as how much this object has to turn<br>
 | |
| 	 * to have the given object directly in front of it.
 | |
| 	 * @param target the object to which to calculate the angle
 | |
| 	 * @return the angle this object has to turn to have the given object in front of it
 | |
| 	 */
 | |
| 	public final double calculateDirectionTo(ILocational target)
 | |
| 	{
 | |
| 		int heading = Util.calculateHeadingFrom(this, target) - getHeading();
 | |
| 		if (heading < 0)
 | |
| 		{
 | |
| 			heading = 65535 + heading;
 | |
| 		}
 | |
| 		return Util.convertHeadingToDegree(heading);
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Sends an instance update for player.
 | |
| 	 * @param instance the instance to update
 | |
| 	 * @param hide if {@code true} hide the player
 | |
| 	 */
 | |
| 	private final void sendInstanceUpdate(Instance instance, boolean hide)
 | |
| 	{
 | |
| 		final int startTime = (int) ((System.currentTimeMillis() - instance.getInstanceStartTime()) / 1000);
 | |
| 		final int endTime = (int) ((instance.getInstanceEndTime() - instance.getInstanceStartTime()) / 1000);
 | |
| 		if (instance.isTimerIncrease())
 | |
| 		{
 | |
| 			sendPacket(new ExSendUIEvent(getActingPlayer(), hide, true, startTime, endTime, instance.getTimerText()));
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 			sendPacket(new ExSendUIEvent(getActingPlayer(), hide, false, endTime - startTime, 0, instance.getTimerText()));
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * @return {@code true} if this object is invisible, {@code false} otherwise.
 | |
| 	 */
 | |
| 	public boolean isInvisible()
 | |
| 	{
 | |
| 		return _isInvisible;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Sets this object as invisible or not
 | |
| 	 * @param invis
 | |
| 	 */
 | |
| 	public void setInvisible(boolean invis)
 | |
| 	{
 | |
| 		_isInvisible = invis;
 | |
| 		if (invis)
 | |
| 		{
 | |
| 			final DeleteObject deletePacket = new DeleteObject(this);
 | |
| 			for (L2Object obj : getKnownList().getKnownObjects().values())
 | |
| 			{
 | |
| 				if ((obj != null) && obj.isPlayer())
 | |
| 				{
 | |
| 					final L2PcInstance player = obj.getActingPlayer();
 | |
| 					if (!isVisibleFor(player))
 | |
| 					{
 | |
| 						obj.sendPacket(deletePacket);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		// Broadcast information regarding the object to those which are suppose to see.
 | |
| 		broadcastInfo();
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * @param player
 | |
| 	 * @return {@code true} if player can see an invisible object if it's invisible, {@code false} otherwise.
 | |
| 	 */
 | |
| 	public boolean isVisibleFor(L2PcInstance player)
 | |
| 	{
 | |
| 		return !isInvisible() || player.canOverrideCond(PcCondOverride.SEE_ALL_PLAYERS);
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * Broadcasts describing info to known players.
 | |
| 	 */
 | |
| 	public void broadcastInfo()
 | |
| 	{
 | |
| 		for (L2Object obj : getKnownList().getKnownObjects().values())
 | |
| 		{
 | |
| 			if ((obj != null) && obj.isPlayer() && isVisibleFor(obj.getActingPlayer()))
 | |
| 			{
 | |
| 				sendInfo(obj.getActingPlayer());
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	public boolean isInvul()
 | |
| 	{
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	/**
 | |
| 	 * @param player
 | |
| 	 * @return {@code true} if player can ignore an invulnerable object if it's invulnerable, {@code false} otherwise.
 | |
| 	 */
 | |
| 	public boolean isVulnerableFor(L2Character player)
 | |
| 	{
 | |
| 		return !isInvul() || player.canOverrideCond(PcCondOverride.VULNERABLE_ALL_PLAYERS);
 | |
| 	}
 | |
| 	
 | |
| 	@Override
 | |
| 	public boolean equals(Object obj)
 | |
| 	{
 | |
| 		return ((obj instanceof L2Object) && (((L2Object) obj).getObjectId() == getObjectId()));
 | |
| 	}
 | |
| 	
 | |
| 	@Override
 | |
| 	public String toString()
 | |
| 	{
 | |
| 		return (getClass().getSimpleName() + ":" + getName() + "[" + getObjectId() + "]");
 | |
| 	}
 | |
| }
 |