Advertisement
Tammy-Street

L2Character

Mar 29th, 2023
985
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 309.81 KB | None | 0 0
  1. /*
  2.  * l2jlegacy Project - www.l2jlegacy.com
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2, or (at your option)
  7.  * any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  17.  * 02111-1307, USA.
  18.  *
  19.  * http://www.gnu.org/copyleft/gpl.html
  20.  */
  21. package com.l2jlegacy.gameserver.model;
  22.  
  23. import static com.l2jlegacy.gameserver.ai.CtrlIntention.AI_INTENTION_ATTACK;
  24. import static com.l2jlegacy.gameserver.ai.CtrlIntention.AI_INTENTION_FOLLOW;
  25.  
  26. import java.util.Collections;
  27. import java.util.Iterator;
  28. import java.util.List;
  29. import java.util.Map;
  30. import java.util.concurrent.Future;
  31.  
  32. import javolution.util.FastList;
  33. import javolution.util.FastMap;
  34. import javolution.util.FastTable;
  35.  
  36. import org.apache.log4j.Logger;
  37.  
  38. import com.l2jlegacy.Config;
  39. import com.l2jlegacy.gameserver.ai.CtrlEvent;
  40. import com.l2jlegacy.gameserver.ai.CtrlIntention;
  41. import com.l2jlegacy.gameserver.ai.L2AttackableAI;
  42. import com.l2jlegacy.gameserver.ai.L2CharacterAI;
  43. import com.l2jlegacy.gameserver.controllers.GameTimeController;
  44. import com.l2jlegacy.gameserver.datatables.HeroSkillTable;
  45. import com.l2jlegacy.gameserver.datatables.SkillTable;
  46. import com.l2jlegacy.gameserver.datatables.csv.DoorTable;
  47. import com.l2jlegacy.gameserver.datatables.csv.MapRegionTable;
  48. import com.l2jlegacy.gameserver.datatables.csv.MapRegionTable.TeleportWhereType;
  49. import com.l2jlegacy.gameserver.datatables.sql.NpcTable;
  50. import com.l2jlegacy.gameserver.geo.GeoData;
  51. import com.l2jlegacy.gameserver.geo.pathfinding.Node;
  52. import com.l2jlegacy.gameserver.geo.pathfinding.PathFinding;
  53. import com.l2jlegacy.gameserver.handler.ISkillHandler;
  54. import com.l2jlegacy.gameserver.handler.SkillHandler;
  55. import com.l2jlegacy.gameserver.handler.itemhandlers.Potions;
  56. import com.l2jlegacy.gameserver.managers.DimensionalRiftManager;
  57. import com.l2jlegacy.gameserver.managers.DuelManager;
  58. import com.l2jlegacy.gameserver.managers.GrandBossManager;
  59. import com.l2jlegacy.gameserver.managers.RaidBossSpawnManager;
  60. import com.l2jlegacy.gameserver.managers.TownManager;
  61. import com.l2jlegacy.gameserver.model.L2Skill.SkillTargetType;
  62. import com.l2jlegacy.gameserver.model.L2Skill.SkillType;
  63. import com.l2jlegacy.gameserver.model.actor.instance.L2BoatInstance;
  64. import com.l2jlegacy.gameserver.model.actor.instance.L2ControlTowerInstance;
  65. import com.l2jlegacy.gameserver.model.actor.instance.L2DoorInstance;
  66. import com.l2jlegacy.gameserver.model.actor.instance.L2EffectPointInstance;
  67. import com.l2jlegacy.gameserver.model.actor.instance.L2GrandBossInstance;
  68. import com.l2jlegacy.gameserver.model.actor.instance.L2GuardInstance;
  69. import com.l2jlegacy.gameserver.model.actor.instance.L2ItemInstance;
  70. import com.l2jlegacy.gameserver.model.actor.instance.L2MinionInstance;
  71. import com.l2jlegacy.gameserver.model.actor.instance.L2MonsterInstance;
  72. import com.l2jlegacy.gameserver.model.actor.instance.L2NpcInstance;
  73. import com.l2jlegacy.gameserver.model.actor.instance.L2NpcWalkerInstance;
  74. import com.l2jlegacy.gameserver.model.actor.instance.L2PcInstance;
  75. import com.l2jlegacy.gameserver.model.actor.instance.L2PetInstance;
  76. import com.l2jlegacy.gameserver.model.actor.instance.L2PlayableInstance;
  77. import com.l2jlegacy.gameserver.model.actor.instance.L2RaidBossInstance;
  78. import com.l2jlegacy.gameserver.model.actor.instance.L2RiftInvaderInstance;
  79. import com.l2jlegacy.gameserver.model.actor.instance.L2SiegeFlagInstance;
  80. import com.l2jlegacy.gameserver.model.actor.instance.L2SummonInstance;
  81. import com.l2jlegacy.gameserver.model.actor.instance.L2PcInstance.SkillDat;
  82. import com.l2jlegacy.gameserver.model.actor.knownlist.CharKnownList;
  83. import com.l2jlegacy.gameserver.model.actor.knownlist.ObjectKnownList.KnownListAsynchronousUpdateTask;
  84. import com.l2jlegacy.gameserver.model.actor.position.L2CharPosition;
  85. import com.l2jlegacy.gameserver.model.actor.position.ObjectPosition;
  86. import com.l2jlegacy.gameserver.model.actor.stat.CharStat;
  87. import com.l2jlegacy.gameserver.model.actor.status.CharStatus;
  88. import com.l2jlegacy.gameserver.model.entity.Duel;
  89. import com.l2jlegacy.gameserver.model.entity.event.CTF;
  90. import com.l2jlegacy.gameserver.model.entity.event.DM;
  91. import com.l2jlegacy.gameserver.model.entity.event.L2Event;
  92. import com.l2jlegacy.gameserver.model.entity.event.TvT;
  93. import com.l2jlegacy.gameserver.model.entity.event.VIP;
  94. import com.l2jlegacy.gameserver.model.entity.olympiad.Olympiad;
  95. import com.l2jlegacy.gameserver.model.extender.BaseExtender.EventType;
  96. import com.l2jlegacy.gameserver.model.quest.Quest;
  97. import com.l2jlegacy.gameserver.model.quest.QuestState;
  98. import com.l2jlegacy.gameserver.model.zone.type.L2BossZone;
  99. import com.l2jlegacy.gameserver.model.zone.type.L2TownZone;
  100. import com.l2jlegacy.gameserver.network.SystemMessageId;
  101. import com.l2jlegacy.gameserver.network.serverpackets.ActionFailed;
  102. import com.l2jlegacy.gameserver.network.serverpackets.Attack;
  103. import com.l2jlegacy.gameserver.network.serverpackets.BeginRotation;
  104. import com.l2jlegacy.gameserver.network.serverpackets.ChangeMoveType;
  105. import com.l2jlegacy.gameserver.network.serverpackets.ChangeWaitType;
  106. import com.l2jlegacy.gameserver.network.serverpackets.CharInfo;
  107. import com.l2jlegacy.gameserver.network.serverpackets.CharMoveToLocation;
  108. import com.l2jlegacy.gameserver.network.serverpackets.ExOlympiadSpelledInfo;
  109. import com.l2jlegacy.gameserver.network.serverpackets.L2GameServerPacket;
  110. import com.l2jlegacy.gameserver.network.serverpackets.MagicEffectIcons;
  111. import com.l2jlegacy.gameserver.network.serverpackets.MagicSkillCanceld;
  112. import com.l2jlegacy.gameserver.network.serverpackets.MagicSkillLaunched;
  113. import com.l2jlegacy.gameserver.network.serverpackets.MagicSkillUser;
  114. import com.l2jlegacy.gameserver.network.serverpackets.MyTargetSelected;
  115. import com.l2jlegacy.gameserver.network.serverpackets.NpcInfo;
  116. import com.l2jlegacy.gameserver.network.serverpackets.PartySpelled;
  117. import com.l2jlegacy.gameserver.network.serverpackets.PetInfo;
  118. import com.l2jlegacy.gameserver.network.serverpackets.RelationChanged;
  119. import com.l2jlegacy.gameserver.network.serverpackets.Revive;
  120. import com.l2jlegacy.gameserver.network.serverpackets.SetupGauge;
  121. import com.l2jlegacy.gameserver.network.serverpackets.StatusUpdate;
  122. import com.l2jlegacy.gameserver.network.serverpackets.StopMove;
  123. import com.l2jlegacy.gameserver.network.serverpackets.SystemMessage;
  124. import com.l2jlegacy.gameserver.network.serverpackets.TargetUnselected;
  125. import com.l2jlegacy.gameserver.network.serverpackets.TeleportToLocation;
  126. import com.l2jlegacy.gameserver.network.serverpackets.ValidateLocation;
  127. import com.l2jlegacy.gameserver.network.serverpackets.ValidateLocationInVehicle;
  128. import com.l2jlegacy.gameserver.skills.Calculator;
  129. import com.l2jlegacy.gameserver.skills.Formulas;
  130. import com.l2jlegacy.gameserver.skills.Stats;
  131. import com.l2jlegacy.gameserver.skills.effects.EffectCharge;
  132. import com.l2jlegacy.gameserver.skills.funcs.Func;
  133. import com.l2jlegacy.gameserver.skills.holders.ISkillsHolder;
  134. import com.l2jlegacy.gameserver.templates.L2CharTemplate;
  135. import com.l2jlegacy.gameserver.templates.L2NpcTemplate;
  136. import com.l2jlegacy.gameserver.templates.L2Weapon;
  137. import com.l2jlegacy.gameserver.templates.L2WeaponType;
  138. import com.l2jlegacy.gameserver.templates.StatsSet;
  139. import com.l2jlegacy.gameserver.thread.ThreadPoolManager;
  140. import com.l2jlegacy.gameserver.util.Util;
  141. import com.l2jlegacy.util.Point3D;
  142. import com.l2jlegacy.util.random.Rnd;
  143.  
  144. /**
  145.  * Mother class of all character objects of the world (PC, NPC...)<BR>
  146.  * <BR>
  147.  * L2Character :<BR>
  148.  * <BR>
  149.  * <li>L2CastleGuardInstance</li> <li>L2DoorInstance</li> <li>L2NpcInstance</li> <li>L2PlayableInstance</li><BR>
  150.  * <BR>
  151.  * <B><U> Concept of L2CharTemplate</U> :</B><BR>
  152.  * <BR>
  153.  * Each L2Character owns generic and static properties (ex : all Keltir have the same number of HP...). All of those properties are stored in a different template for each type of L2Character. Each template is loaded once in the server cache memory (reduce memory use). When a new instance of
  154.  * L2Character is spawned, server just create a link between the instance and the template. This link is stored in <B>_template</B><BR>
  155.  * <BR>
  156.  * @version $Revision: 1.5.5 $ $Date: 2009/05/12 19:45:27 $
  157.  * @authors eX1steam, programmos, L2Scoria dev&sword dev
  158.  */
  159. public abstract class L2Character extends L2Object implements ISkillsHolder
  160. {
  161.     /** The Constant LOGGER. */
  162.     protected static final Logger LOGGER = Logger.getLogger(L2Character.class);
  163.    
  164.     // =========================================================
  165.     // Data Field
  166.     /** The attack stance. */
  167.     private long attackStance;
  168.    
  169.     /** The _attack by list. */
  170.     private List<L2Character> _attackByList;
  171.     // private L2Character _attackingChar;
  172.     /** The _last skill cast. */
  173.     private L2Skill _lastSkillCast;
  174.    
  175.     /** The _last potion cast. */
  176.     private L2Skill _lastPotionCast;
  177.    
  178.     /** The _is buff protected. */
  179.     private boolean _isBuffProtected = false; // Protect From Debuffs
  180.    
  181.     /** The _is afraid. */
  182.     private boolean _isAfraid = false; // Flee in a random direction
  183.    
  184.     /** The _is confused. */
  185.     private boolean _isConfused = false; // Attack anyone randomly
  186.    
  187.     /** The _is fake death. */
  188.     private boolean _isFakeDeath = false; // Fake death
  189.    
  190.     /** The _is flying. */
  191.     private boolean _isFlying = false; // Is flying Wyvern?
  192.    
  193.     /** The _is fallsdown. */
  194.     private boolean _isFallsdown = false; // Falls down
  195.    
  196.     /** The _is muted. */
  197.     private boolean _isMuted = false; // Cannot use magic
  198.    
  199.     /** The _is psychical muted. */
  200.     private boolean _isPsychicalMuted = false; // Cannot use psychical skills
  201.    
  202.     /** The _is killed already. */
  203.     private boolean _isKilledAlready = false;
  204.    
  205.     /** The _is imobilised. */
  206.     private int _isImmobilized = 0;
  207.    
  208.     /** The _is overloaded. */
  209.     private boolean _isOverloaded = false; // the char is carrying too much
  210.    
  211.     /** The _is paralyzed. */
  212.     private boolean _isParalyzed = false;
  213.    
  214.     /** The _is riding. */
  215.     private boolean _isRiding = false; // Is Riding strider?
  216.    
  217.     /** The _is pending revive. */
  218.     private boolean _isPendingRevive = false;
  219.    
  220.     /** The _is rooted. */
  221.     private boolean _isRooted = false; // Cannot move until root timed out
  222.    
  223.     /** The _is running. */
  224.     private boolean _isRunning = false;
  225.    
  226.     /** The _is immobile until attacked. */
  227.     private boolean _isImmobileUntilAttacked = false; // Is in immobile until attacked.
  228.    
  229.     /** The _is sleeping. */
  230.     private boolean _isSleeping = false; // Cannot move/attack until sleep timed out or monster is attacked
  231.    
  232.     /** The _is stunned. */
  233.     private boolean _isStunned = false; // Cannot move/attack until stun timed out
  234.    
  235.     /** The _is betrayed. */
  236.     private boolean _isBetrayed = false; // Betrayed by own summon
  237.    
  238.     /** The _is block buff. */
  239.     private boolean _isBlockBuff = false; // Got blocked buff bar
  240.    
  241.     /** The _is block debuff. */
  242.     private boolean _isBlockDebuff = false; // Got blocked debuff bar
  243.    
  244.     /** The _is teleporting. */
  245.     protected boolean _isTeleporting = false;
  246.    
  247.     /** The _is invul. */
  248.     protected boolean _isInvul = false;
  249.    
  250.     /** The _is killable */
  251.     protected boolean _isUnkillable = false;
  252.    
  253.     /** The attackDisabled */
  254.     protected boolean _isAttackDisabled = false;
  255.    
  256.     /** The _last heal amount. */
  257.     private int _lastHealAmount = 0;
  258.    
  259.     /** The _stat. */
  260.     private CharStat _stat;
  261.    
  262.     /** The _status. */
  263.     private CharStatus _status;
  264.    
  265.     /** The _template. */
  266.     private L2CharTemplate _template; // The link on the L2CharTemplate object containing generic and static properties of this L2Character type (ex : Max HP, Speed...)
  267.    
  268.     /** The _title. */
  269.     private String _title;
  270.    
  271.     /** The _ai class. */
  272.     private String _aiClass = "default";
  273.    
  274.     /** The _hp update inc check. */
  275.     private double _hpUpdateIncCheck = .0;
  276.    
  277.     /** The _hp update dec check. */
  278.     private double _hpUpdateDecCheck = .0;
  279.    
  280.     /** The _hp update interval. */
  281.     private double _hpUpdateInterval = .0;
  282.    
  283.     /** The _champion. */
  284.     private boolean _champion = false;
  285.    
  286.     /** Table of Calculators containing all used calculator. */
  287.     private Calculator[] _calculators;
  288.    
  289.     /** FastMap(Integer, L2Skill) containing all skills of the L2Character. */
  290.     protected final Map<Integer, L2Skill> _skills;
  291.    
  292.     /** FastMap(Integer, L2Skill) containing all triggered skills of the L2PcInstance. */
  293.     protected final Map<Integer, L2Skill> _triggeredSkills;
  294.    
  295.     /** FastMap containing the active chance skills on this character. */
  296.     protected ChanceSkillList _chanceSkills;
  297.    
  298.     /** Current force buff this caster is casting to a target. */
  299.     protected ForceBuff _forceBuff;
  300.    
  301.     /** The _blocked. */
  302.     private boolean _blocked;
  303.    
  304.     /** The _meditated. */
  305.     private boolean _meditated;
  306.    
  307.     /**
  308.      * Zone system<br>
  309.      * x^2 or x*x.
  310.      */
  311.     public static final int ZONE_PVP = 1;
  312.    
  313.     /** The Constant ZONE_PEACE. */
  314.     public static final int ZONE_PEACE = 2;
  315.    
  316.     /** The Constant ZONE_SIEGE. */
  317.     public static final int ZONE_SIEGE = 4;
  318.    
  319.     /** The Constant ZONE_MOTHERTREE. */
  320.     public static final int ZONE_MOTHERTREE = 8;
  321.    
  322.     /** The Constant ZONE_CLANHALL. */
  323.     public static final int ZONE_CLANHALL = 16;
  324.    
  325.     /** The Constant ZONE_UNUSED. */
  326.     public static final int ZONE_UNUSED = 32;
  327.    
  328.     /** The Constant ZONE_NOLANDING. */
  329.     public static final int ZONE_NOLANDING = 64;
  330.    
  331.     /** The Constant ZONE_WATER. */
  332.     public static final int ZONE_WATER = 128;
  333.    
  334.     /** The Constant ZONE_JAIL. */
  335.     public static final int ZONE_JAIL = 256;
  336.    
  337.     /** The Constant ZONE_MONSTERTRACK. */
  338.     public static final int ZONE_MONSTERTRACK = 512;
  339.    
  340.     /** The Constant ZONE_SWAMP. */
  341.     public static final int ZONE_SWAMP = 1024;
  342.    
  343.     /** The Constant ZONE_NOSUMMONFRIEND. */
  344.     public static final int ZONE_NOSUMMONFRIEND = 2048;
  345.    
  346.     /** The Constant ZONE_OLY. */
  347.     public static final int ZONE_OLY = 4096;
  348.    
  349.     /** The Constant ZONE_NOHQ. */
  350.     public static final int ZONE_NOHQ = 8192;
  351.    
  352.     /** The Constant ZONE_DANGERAREA. */
  353.     public static final int ZONE_DANGERAREA = 16384;
  354.    
  355.     /** The Constant ZONE_NOSTORE. */
  356.     public static final int ZONE_NOSTORE = 32768;
  357.    
  358.     /** The _current zones. */
  359.     private int _currentZones = 0;
  360.    
  361.     /** Advance Headquarters */
  362.     private boolean _advanceFlag = false;
  363.     private int _advanceMultiplier = 1;
  364.    
  365.     /**
  366.      * Checks if is inside zone.
  367.      * @param zone the zone
  368.      * @return true, if is inside zone
  369.      */
  370.     public boolean isInsideZone(final int zone)
  371.     {
  372.         return (_currentZones & zone) != 0;
  373.     }
  374.    
  375.     /**
  376.      * Sets the inside zone.
  377.      * @param zone the zone
  378.      * @param state the state
  379.      */
  380.     public void setInsideZone(final int zone, final boolean state)
  381.     {
  382.         if (state)
  383.         {
  384.             _currentZones |= zone;
  385.         }
  386.         else if (isInsideZone(zone))
  387.         {
  388.             _currentZones ^= zone;
  389.         }
  390.     }
  391.    
  392.     /**
  393.      * This will return true if the player is GM,<br>
  394.      * but if the player is not GM it will return false.
  395.      * @return GM status
  396.      */
  397.     public boolean charIsGM()
  398.     {
  399.         if (this instanceof L2PcInstance)
  400.         {
  401.             if (((L2PcInstance) this).isGM())
  402.             {
  403.                 return true;
  404.             }
  405.         }
  406.         return false;
  407.     }
  408.    
  409.     // =========================================================
  410.     // Constructor
  411.     /**
  412.      * Constructor of L2Character.<BR>
  413.      * <BR>
  414.      * <B><U> Concept</U> :</B><BR>
  415.      * <BR>
  416.      * Each L2Character owns generic and static properties (ex : all Keltir have the same number of HP...). All of those properties are stored in a different template for each type of L2Character. Each template is loaded once in the server cache memory (reduce memory use). When a new instance of
  417.      * L2Character is spawned, server just create a link between the instance and the template This link is stored in <B>_template</B><BR>
  418.      * <BR>
  419.      * <B><U> Actions</U> :</B><BR>
  420.      * <BR>
  421.      * <li>Set the _template of the L2Character</li> <li>Set _overloaded to false (the charcater can take more items)</li> <BR>
  422.      * <BR>
  423.      * <li>If L2Character is a L2NPCInstance, copy skills from template to object</li> <li>If L2Character is a L2NPCInstance, link _calculators to NPC_STD_CALCULATOR</li><BR>
  424.      * <BR>
  425.      * <li>If L2Character is NOT a L2NPCInstance, create an empty _skills slot</li> <li>If L2Character is a L2PcInstance or L2Summon, copy basic Calculator set to object</li><BR>
  426.      * <BR>
  427.      * @param objectId Identifier of the object to initialized
  428.      * @param template The L2CharTemplate to apply to the object
  429.      */
  430.     // MAKE TO US From DREAM
  431.     // int attackcountmax = (int) Math.round(calcStat(Stats.POLE_TARGERT_COUNT, 3, null, null));
  432.     public L2Character(final int objectId, final L2CharTemplate template)
  433.     {
  434.         super(objectId);
  435.         getKnownList();
  436.        
  437.         // Set its template to the new L2Character
  438.         _template = template;
  439.        
  440.         _triggeredSkills = new FastMap<>();
  441.        
  442.         if (template != null && this instanceof L2NpcInstance)
  443.         {
  444.             // Copy the Standard Calcultors of the L2NPCInstance in _calculators
  445.             _calculators = NPC_STD_CALCULATOR;
  446.            
  447.             // Copy the skills of the L2NPCInstance from its template to the L2Character Instance
  448.             // The skills list can be affected by spell effects so it's necessary to make a copy
  449.             // to avoid that a spell affecting a L2NPCInstance, affects others L2NPCInstance of the same type too.
  450.             _skills = ((L2NpcTemplate) template).getSkills();
  451.            
  452.             for (final Map.Entry<Integer, L2Skill> skill : _skills.entrySet())
  453.             {
  454.                 addStatFuncs(skill.getValue().getStatFuncs(null, this));
  455.             }
  456.            
  457.             if (!Config.NPC_ATTACKABLE || !(this instanceof L2Attackable) && !(this instanceof L2ControlTowerInstance) && !(this instanceof L2SiegeFlagInstance) && !(this instanceof L2EffectPointInstance))
  458.             {
  459.                 setIsInvul(true);
  460.             }
  461.         }
  462.         else
  463.         // not L2NpcInstance
  464.         {
  465.             // Initialize the FastMap _skills to null
  466.             _skills = new FastMap<Integer, L2Skill>().shared();
  467.            
  468.             // If L2Character is a L2PcInstance or a L2Summon, create the basic calculator set
  469.             _calculators = new Calculator[Stats.NUM_STATS];
  470.             Formulas.getInstance().addFuncsToNewCharacter(this);
  471.            
  472.             if (!(this instanceof L2Attackable) && !this.isAttackable() && !(this instanceof L2DoorInstance))
  473.                 setIsInvul(true);
  474.         }
  475.        
  476.         /*
  477.          * if(!(this instanceof L2PcInstance) && !(this instanceof L2MonsterInstance) && !(this instanceof L2GuardInstance) && !(this instanceof L2SiegeGuardInstance) && !(this instanceof L2ControlTowerInstance) && !(this instanceof L2DoorInstance) && !(this instanceof L2FriendlyMobInstance) &&
  478.          * !(this instanceof L2SiegeSummonInstance) && !(this instanceof L2PetInstance) && !(this instanceof L2SummonInstance) && !(this instanceof L2SiegeFlagInstance) && !(this instanceof L2EffectPointInstance) && !(this instanceof L2CommanderInstance) && !(this instanceof
  479.          * L2FortSiegeGuardInstance)) { ///////////////////////////////////////////////////////////////////////////////////////////// setIsInvul(true); }
  480.          */
  481.     }
  482.    
  483.     /**
  484.      * Inits the char status update values.
  485.      */
  486.     protected void initCharStatusUpdateValues()
  487.     {
  488.         _hpUpdateInterval = getMaxHp() / 352.0; // MAX_HP div MAX_HP_BAR_PX
  489.         _hpUpdateIncCheck = getMaxHp();
  490.         _hpUpdateDecCheck = getMaxHp() - _hpUpdateInterval;
  491.     }
  492.    
  493.     // =========================================================
  494.     // Event - Public
  495.     /**
  496.      * Remove the L2Character from the world when the decay task is launched.<BR>
  497.      * <BR>
  498.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T REMOVE the object from _allObjects of L2World </B></FONT><BR>
  499.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T SEND Server->Client packets to players</B></FONT><BR>
  500.      * <BR>
  501.      */
  502.     public void onDecay()
  503.     {
  504.         L2WorldRegion reg = getWorldRegion();
  505.        
  506.         if (reg != null)
  507.         {
  508.             reg.removeFromZones(this);
  509.         }
  510.        
  511.         decayMe();
  512.        
  513.         reg = null;
  514.     }
  515.    
  516.     /*
  517.      * (non-Javadoc)
  518.      * @see com.l2jlegacy.gameserver.model.L2Object#onSpawn()
  519.      */
  520.     @Override
  521.     public void onSpawn()
  522.     {
  523.         super.onSpawn();
  524.         revalidateZone();
  525.     }
  526.    
  527.     /**
  528.      * On teleported.
  529.      */
  530.     public void onTeleported()
  531.     {
  532.         if (!isTeleporting())
  533.             return;
  534.        
  535.         final ObjectPosition pos = getPosition();
  536.        
  537.         if (pos != null)
  538.             spawnMe(getPosition().getX(), getPosition().getY(), getPosition().getZ());
  539.        
  540.         setIsTeleporting(false);
  541.        
  542.         if (_isPendingRevive)
  543.         {
  544.             doRevive();
  545.         }
  546.        
  547.         final L2Summon pet = getPet();
  548.        
  549.         // Modify the position of the pet if necessary
  550.         if (pet != null && pos != null)
  551.         {
  552.             pet.setFollowStatus(false);
  553.             pet.teleToLocation(pos.getX() + Rnd.get(-100, 100), pos.getY() + Rnd.get(-100, 100), pos.getZ(), false);
  554.             pet.setFollowStatus(true);
  555.         }
  556.        
  557.     }
  558.    
  559.     // =========================================================
  560.     // Method - Public
  561.     /**
  562.      * Add L2Character instance that is attacking to the attacker list.<BR>
  563.      * <BR>
  564.      * @param player The L2Character that attcks this one
  565.      */
  566.     public void addAttackerToAttackByList(final L2Character player)
  567.     {
  568.         if (player == null || player == this || getAttackByList() == null || getAttackByList().contains(player))
  569.             return;
  570.        
  571.         getAttackByList().add(player);
  572.     }
  573.    
  574.     /**
  575.      * Send a packet to the L2Character AND to all L2PcInstance in the _KnownPlayers of the L2Character.<BR>
  576.      * <BR>
  577.      * <B><U> Concept</U> :</B><BR>
  578.      * <BR>
  579.      * L2PcInstance in the detection area of the L2Character are identified in <B>_knownPlayers</B>. In order to inform other players of state modification on the L2Character, server just need to go through _knownPlayers to send Server->Client Packet<BR>
  580.      * <BR>
  581.      */
  582.    
  583.     protected byte _startingRotationCounter = 4;
  584.    
  585.     /**
  586.      * Checks if is starting rotation allowed.
  587.      * @return true, if is starting rotation allowed
  588.      */
  589.     public synchronized boolean isStartingRotationAllowed()
  590.     {
  591.         // This function is called too often from movement arrow
  592.         _startingRotationCounter--;
  593.         if (_startingRotationCounter < 0)
  594.             _startingRotationCounter = 4;
  595.        
  596.         if (_startingRotationCounter == 4)
  597.         {
  598.             return true;
  599.         }
  600.         return false;
  601.     }
  602.    
  603.     /**
  604.      * Broadcast packet.
  605.      * @param mov the mov
  606.      */
  607.     public final void broadcastPacket(final L2GameServerPacket mov)
  608.     {
  609.         if (!(mov instanceof CharInfo))
  610.         {
  611.             sendPacket(mov);
  612.         }
  613.        
  614.         // don't broadcast anytime the rotating packet
  615.         if (mov instanceof BeginRotation && !isStartingRotationAllowed())
  616.         {
  617.             return;
  618.         }
  619.        
  620.         // if (Config.DEBUG) LOGGER.fine("players to notify:" + knownPlayers.size() + " packet:"+mov.getType());
  621.        
  622.         for (final L2PcInstance player : getKnownList().getKnownPlayers().values())
  623.         {
  624.             if (player != null)
  625.             {
  626.                 /*
  627.                  * TEMP FIX: If player is not visible don't send packets broadcast to all his KnowList. This will avoid GM detection with l2net and olympiad's crash. We can now find old problems with invisible mode.
  628.                  */
  629.                 if (this instanceof L2PcInstance && !player.isGM() && (((L2PcInstance) this).getAppearance().getInvisible() || ((L2PcInstance) this).inObserverMode()))
  630.                     return;
  631.                
  632.                 try
  633.                 {
  634.                     player.sendPacket(mov);
  635.                    
  636.                     if (mov instanceof CharInfo && this instanceof L2PcInstance)
  637.                     {
  638.                         final int relation = ((L2PcInstance) this).getRelation(player);
  639.                         if (getKnownList().getKnownRelations().get(player.getObjectId()) != null && getKnownList().getKnownRelations().get(player.getObjectId()) != relation)
  640.                         {
  641.                             player.sendPacket(new RelationChanged((L2PcInstance) this, relation, player.isAutoAttackable(this)));
  642.                         }
  643.                     }
  644.                     // if(Config.DEVELOPER && !isInsideRadius(player, 3500, false, false)) LOGGER.warn("broadcastPacket: Too far player see event!");
  645.                 }
  646.                 catch (final NullPointerException e)
  647.                 {
  648.                     e.printStackTrace();
  649.                 }
  650.             }
  651.         }
  652.     }
  653.    
  654.     /**
  655.      * Send a packet to the L2Character AND to all L2PcInstance in the radius (max knownlist radius) from the L2Character.<BR>
  656.      * <BR>
  657.      * <B><U> Concept</U> :</B><BR>
  658.      * <BR>
  659.      * L2PcInstance in the detection area of the L2Character are identified in <B>_knownPlayers</B>. In order to inform other players of state modification on the L2Character, server just need to go through _knownPlayers to send Server->Client Packet<BR>
  660.      * <BR>
  661.      * @param mov the mov
  662.      * @param radiusInKnownlist the radius in knownlist
  663.      */
  664.     public final void broadcastPacket(final L2GameServerPacket mov, final int radiusInKnownlist)
  665.     {
  666.         if (!(mov instanceof CharInfo))
  667.         {
  668.             sendPacket(mov);
  669.         }
  670.        
  671.         // if (Config.DEBUG) LOGGER.fine("players to notify:" + knownPlayers.size() + " packet:"+mov.getType());
  672.        
  673.         for (final L2PcInstance player : getKnownList().getKnownPlayers().values())
  674.         {
  675.             try
  676.             {
  677.                 if (!isInsideRadius(player, radiusInKnownlist, false, false))
  678.                 {
  679.                     continue;
  680.                 }
  681.                
  682.                 player.sendPacket(mov);
  683.                
  684.                 if (mov instanceof CharInfo && this instanceof L2PcInstance)
  685.                 {
  686.                     final int relation = ((L2PcInstance) this).getRelation(player);
  687.                     if (getKnownList().getKnownRelations().get(player.getObjectId()) != null && getKnownList().getKnownRelations().get(player.getObjectId()) != relation)
  688.                     {
  689.                         player.sendPacket(new RelationChanged((L2PcInstance) this, relation, player.isAutoAttackable(this)));
  690.                     }
  691.                 }
  692.             }
  693.             catch (final NullPointerException e)
  694.             {
  695.                 e.printStackTrace();
  696.             }
  697.         }
  698.     }
  699.    
  700.     /**
  701.      * Need hp update.
  702.      * @param barPixels the bar pixels
  703.      * @return true if hp update should be done, false if not
  704.      */
  705.     protected boolean needHpUpdate(final int barPixels)
  706.     {
  707.         final double currentHp = getCurrentHp();
  708.        
  709.         if (currentHp <= 1.0 || getMaxHp() < barPixels)
  710.             return true;
  711.        
  712.         if (currentHp <= _hpUpdateDecCheck || currentHp >= _hpUpdateIncCheck)
  713.         {
  714.             if (currentHp == getMaxHp())
  715.             {
  716.                 _hpUpdateIncCheck = currentHp + 1;
  717.                 _hpUpdateDecCheck = currentHp - _hpUpdateInterval;
  718.             }
  719.             else
  720.             {
  721.                 final double doubleMulti = currentHp / _hpUpdateInterval;
  722.                 int intMulti = (int) doubleMulti;
  723.                
  724.                 _hpUpdateDecCheck = _hpUpdateInterval * (doubleMulti < intMulti ? intMulti-- : intMulti);
  725.                 _hpUpdateIncCheck = _hpUpdateDecCheck + _hpUpdateInterval;
  726.             }
  727.             return true;
  728.         }
  729.        
  730.         return false;
  731.     }
  732.    
  733.     /**
  734.      * Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform.<BR>
  735.      * <BR>
  736.      * <B><U> Actions</U> :</B><BR>
  737.      * <BR>
  738.      * <li>Create the Server->Client packet StatusUpdate with current HP and MP</li> <li>Send the Server->Client packet StatusUpdate with current HP and MP to all L2Character called _statusListener that must be informed of HP/MP updates of this L2Character</li><BR>
  739.      * <BR>
  740.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T SEND CP information</B></FONT><BR>
  741.      * <BR>
  742.      * <B><U> Overriden in </U> :</B><BR>
  743.      * <BR>
  744.      * <li>L2PcInstance : Send current HP,MP and CP to the L2PcInstance and only current HP, MP and Level to all other L2PcInstance of the Party</li><BR>
  745.      * <BR>
  746.      */
  747.     public void broadcastStatusUpdate()
  748.     {
  749.         if (getStatus().getStatusListener().isEmpty())
  750.             return;
  751.        
  752.         if (!needHpUpdate(352))
  753.             return;
  754.        
  755.         if (Config.DEBUG)
  756.         {
  757.             LOGGER.debug("Broadcast Status Update for " + getObjectId() + "(" + getName() + "). HP: " + getCurrentHp());
  758.         }
  759.        
  760.         // Create the Server->Client packet StatusUpdate with current HP and MP
  761.         StatusUpdate su = null;
  762.         if (Config.FORCE_COMPLETE_STATUS_UPDATE && this instanceof L2PcInstance)
  763.         {
  764.             su = new StatusUpdate((L2PcInstance) this);
  765.         }
  766.         else
  767.         {
  768.             su = new StatusUpdate(getObjectId());
  769.             su.addAttribute(StatusUpdate.CUR_HP, (int) getCurrentHp());
  770.             su.addAttribute(StatusUpdate.CUR_MP, (int) getCurrentMp());
  771.         }
  772.        
  773.         // Go through the StatusListener
  774.         // Send the Server->Client packet StatusUpdate with current HP and MP
  775.         for (final L2Character temp : getStatus().getStatusListener())
  776.         {
  777.             if (temp != null)
  778.                 temp.sendPacket(su);
  779.         }
  780.         /*
  781.          * synchronized (getStatus().getStatusListener()) { for(L2Character temp : getStatus().getStatusListener()) { try { temp.sendPacket(su); } catch(NullPointerException e) { e.printStackTrace(); } } }
  782.          */
  783.     }
  784.    
  785.     /**
  786.      * Not Implemented.<BR>
  787.      * <BR>
  788.      * <B><U> Overridden in </U> :</B><BR>
  789.      * <BR>
  790.      * <li>L2PcInstance</li><BR>
  791.      * <BR>
  792.      * @param mov the mov
  793.      */
  794.     public void sendPacket(final L2GameServerPacket mov)
  795.     {
  796.         // default implementation
  797.     }
  798.    
  799.     /** The _in town war. */
  800.     private boolean _inTownWar;
  801.    
  802.     /**
  803.      * Checks if is in town war.
  804.      * @return true, if is in town war
  805.      */
  806.     public final boolean isinTownWar()
  807.     {
  808.         return _inTownWar;
  809.     }
  810.    
  811.     /**
  812.      * Sets the in town war.
  813.      * @param value the new in town war
  814.      */
  815.     public final void setInTownWar(final boolean value)
  816.     {
  817.         _inTownWar = value;
  818.     }
  819.    
  820.     /*
  821.      * public void teleToLocation(int x, int y, int z, boolean allowRandomOffset) { if(Config.TW_DISABLE_GK) { int x1,y1,z1; x1 = getX(); y1 = getY(); z1 = getZ(); L2TownZone Town; Town = TownManager.getInstance().getTown(x1,y1,z1); if(Town != null && isinTownWar() ) { if(Town.getTownId() ==
  822.      * Config.TW_TOWN_ID && !Config.TW_ALL_TOWNS) { return; } else if(Config.TW_ALL_TOWNS) { return; } } } // Stop movement stopMove(null, false); abortAttack(); abortCast(); setIsTeleporting(true); setTarget(null); // Remove from world regions zones if(getWorldRegion() != null) {
  823.      * getWorldRegion().removeFromZones(this); } getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE); if(Config.RESPAWN_RANDOM_ENABLED && allowRandomOffset) { x += Rnd.get(-Config.RESPAWN_RANDOM_MAX_OFFSET, Config.RESPAWN_RANDOM_MAX_OFFSET); y += Rnd.get(-Config.RESPAWN_RANDOM_MAX_OFFSET,
  824.      * Config.RESPAWN_RANDOM_MAX_OFFSET); } //z = GeoData.getInstance().getHeight(x, y, z); z += 5; if(Config.DEBUG) { LOGGER.fine("Teleporting to: " + x + ", " + y + ", " + z); } // Send a Server->Client packet TeleportToLocationt to the L2Character AND to all L2PcInstance in the _KnownPlayers of
  825.      * the L2Character broadcastPacket(new TeleportToLocation(this, x, y, z)); // Set the x,y,z position of the L2Object and if necessary modify its _worldRegion getPosition().setXYZ(x, y, z); decayMe(); // Set the x, y, z coords of the object, but do not update it's world region yet -
  826.      * onTeleported() will do it getPosition().setWorldPosition(x, y, z); if(!(this instanceof L2PcInstance)) { onTeleported(); } }
  827.      */
  828.    
  829.     /**
  830.      * Teleport a L2Character and its pet if necessary.<BR>
  831.      * <BR>
  832.      * <B><U> Actions</U> :</B><BR>
  833.      * <BR>
  834.      * <li>Stop the movement of the L2Character</li> <li>Set the x,y,z position of the L2Object and if necessary modify its _worldRegion</li> <li>Send a Server->Client packet TeleportToLocationt to the L2Character AND to all L2PcInstance in its _KnownPlayers</li> <li>Modify the position of the pet
  835.      * if necessary</li><BR>
  836.      * <BR>
  837.      * @param x the x
  838.      * @param y the y
  839.      * @param z the z
  840.      * @param allowRandomOffset the allow random offset
  841.      */
  842.     public void teleToLocation(int x, int y, int z, final boolean allowRandomOffset)
  843.     {
  844.         if (Config.TW_DISABLE_GK)
  845.         {
  846.             int x1, y1, z1;
  847.             x1 = getX();
  848.             y1 = getY();
  849.             z1 = getZ();
  850.             L2TownZone Town;
  851.             Town = TownManager.getInstance().getTown(x1, y1, z1);
  852.             if (Town != null && isinTownWar())
  853.             {
  854.                 if (Town.getTownId() == Config.TW_TOWN_ID && !Config.TW_ALL_TOWNS)
  855.                 {
  856.                     return;
  857.                 }
  858.                 else if (Config.TW_ALL_TOWNS)
  859.                 {
  860.                     return;
  861.                 }
  862.             }
  863.         }
  864.        
  865.         // Stop movement
  866.         stopMove(null, false);
  867.         abortAttack();
  868.         abortCast();
  869.        
  870.         setIsTeleporting(true);
  871.         setTarget(null);
  872.        
  873.         // Remove from world regions zones
  874.         final L2WorldRegion region = getWorldRegion();
  875.         if (region != null)
  876.             region.removeFromZones(this);
  877.        
  878.         getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  879.        
  880.         if (Config.RESPAWN_RANDOM_ENABLED && allowRandomOffset)
  881.         {
  882.             x += Rnd.get(-Config.RESPAWN_RANDOM_MAX_OFFSET, Config.RESPAWN_RANDOM_MAX_OFFSET);
  883.             y += Rnd.get(-Config.RESPAWN_RANDOM_MAX_OFFSET, Config.RESPAWN_RANDOM_MAX_OFFSET);
  884.         }
  885.        
  886.         z += 5;
  887.        
  888.         if (Config.DEBUG)
  889.             LOGGER.debug("Teleporting to: " + x + ", " + y + ", " + z);
  890.        
  891.         // Send a Server->Client packet TeleportToLocationt to the L2Character AND to all L2PcInstance in the _KnownPlayers of the L2Character
  892.         broadcastPacket(new TeleportToLocation(this, x, y, z));
  893.        
  894.         // remove the object from its old location
  895.         decayMe();
  896.        
  897.         // Set the x,y,z position of the L2Object and if necessary modify its _worldRegion
  898.         getPosition().setXYZ(x, y, z);
  899.        
  900.         // if (!(this instanceof L2PcInstance) || (((L2PcInstance)this).isOffline()))/*.getClient() != null && ((L2PcInstance)this).getClient().isDetached()))*/
  901.         if (!(this instanceof L2PcInstance))
  902.             onTeleported();
  903.        
  904.         revalidateZone(true);
  905.     }
  906.    
  907.     /** The _zone validate counter. */
  908.     protected byte _zoneValidateCounter = 4;
  909.    
  910.     /**
  911.      * Revalidate zone.
  912.      * @param force the force
  913.      */
  914.     public void revalidateZone(final boolean force)
  915.     {
  916.         final L2WorldRegion region = getWorldRegion();
  917.         if (region == null)
  918.             return;
  919.        
  920.         // This function is called too often from movement code
  921.         if (force)
  922.             _zoneValidateCounter = 4;
  923.         else
  924.         {
  925.             _zoneValidateCounter--;
  926.             if (_zoneValidateCounter < 0)
  927.                 _zoneValidateCounter = 4;
  928.             else
  929.                 return;
  930.         }
  931.         region.revalidateZones(this);
  932.     }
  933.    
  934.     /**
  935.      * Tele to location.
  936.      * @param x the x
  937.      * @param y the y
  938.      * @param z the z
  939.      */
  940.     public void teleToLocation(final int x, final int y, final int z)
  941.     {
  942.         teleToLocation(x, y, z, false);
  943.     }
  944.    
  945.     /**
  946.      * Tele to location.
  947.      * @param loc the loc
  948.      * @param allowRandomOffset the allow random offset
  949.      */
  950.     public void teleToLocation(final Location loc, final boolean allowRandomOffset)
  951.     {
  952.         int x = loc.getX();
  953.         int y = loc.getY();
  954.         int z = loc.getZ();
  955.        
  956.         if (this instanceof L2PcInstance && DimensionalRiftManager.getInstance().checkIfInRiftZone(getX(), getY(), getZ(), true))
  957.         { // true -> ignore waiting room :)
  958.             L2PcInstance player = (L2PcInstance) this;
  959.             player.sendMessage("You have been sent to the waiting room.");
  960.            
  961.             if (player.isInParty() && player.getParty().isInDimensionalRift())
  962.             {
  963.                 player.getParty().getDimensionalRift().usedTeleport(player);
  964.             }
  965.            
  966.             final int[] newCoords = DimensionalRiftManager.getInstance().getRoom((byte) 0, (byte) 0).getTeleportCoords();
  967.            
  968.             x = newCoords[0];
  969.             y = newCoords[1];
  970.             z = newCoords[2];
  971.            
  972.             player = null;
  973.         }
  974.         teleToLocation(x, y, z, allowRandomOffset);
  975.     }
  976.    
  977.     /**
  978.      * Tele to location.
  979.      * @param teleportWhere the teleport where
  980.      */
  981.     public void teleToLocation(final TeleportWhereType teleportWhere)
  982.     {
  983.         teleToLocation(MapRegionTable.getInstance().getTeleToLocation(this, teleportWhere), true);
  984.     }
  985.    
  986.     /*
  987.      * // Fall Damage public void Falling(int fallHeight) { if(isDead() || isFlying() || isInvul() || (this instanceof L2PcInstance && isInFunEvent())) return; final int maxHp = getMaxHp(); final int curHp = (int) getCurrentHp(); final int damage = (int) calcStat(Stats.FALL, maxHp / 1000 *
  988.      * fallHeight, null, null); if(curHp - damage < 1) setCurrentHp(1); else setCurrentHp(curHp - damage); sendPacket(new SystemMessage(SystemMessageId.FALL_DAMAGE_S1).addNumber(damage)); //YOU_RECEIVED_S1_DAMAGE_FROM_TAKING_A_HIGH_FALL }
  989.      */
  990.    
  991.     // =========================================================
  992.     // Method - Private
  993.     /**
  994.      * Launch a physical attack against a target (Simple, Bow, Pole or Dual).<BR>
  995.      * <BR>
  996.      * <B><U> Actions</U> :</B><BR>
  997.      * <BR>
  998.      * <li>Get the active weapon (always equiped in the right hand)</li><BR>
  999.      * <BR>
  1000.      * <li>If weapon is a bow, check for arrows, MP and bow re-use delay (if necessary, equip the L2PcInstance with arrows in left hand)</li> <li>If weapon is a bow, consume MP and set the new period of bow non re-use</li><BR>
  1001.      * <BR>
  1002.      * <li>Get the Attack Speed of the L2Character (delay (in milliseconds) before next attack)</li> <li>Select the type of attack to start (Simple, Bow, Pole or Dual) and verify if SoulShot are charged then start calculation</li> <li>If the Server->Client packet Attack contains at least 1 hit, send
  1003.      * the Server->Client packet Attack to the L2Character AND to all L2PcInstance in the _KnownPlayers of the L2Character</li> <li>Notify AI with EVT_READY_TO_ACT</li><BR>
  1004.      * <BR>
  1005.      * @param target The L2Character targeted
  1006.      */
  1007.     protected void doAttack(final L2Character target)
  1008.     {
  1009.         if (Config.DEBUG)
  1010.         {
  1011.             LOGGER.debug(getName() + " doAttack: target=" + target);
  1012.         }
  1013.        
  1014.         if (target == null)
  1015.             return;
  1016.        
  1017.         // Like L2OFF wait that the hit task finish and then player can move
  1018.         if (this instanceof L2PcInstance && ((L2PcInstance) this).isMovingTaskDefined() && !((L2PcInstance) this).isAttackingNow())
  1019.         {
  1020.             final L2ItemInstance rhand = ((L2PcInstance) this).getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
  1021.             if ((rhand != null && rhand.getItemType() != L2WeaponType.BOW) || (rhand == null))
  1022.             {
  1023.                 ((L2PcInstance) this).startMovingTask();
  1024.                 return;
  1025.             }
  1026.         }
  1027.        
  1028.         if (isAlikeDead())
  1029.         {
  1030.             // If L2PcInstance is dead or the target is dead, the action is stoped
  1031.             getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  1032.            
  1033.             sendPacket(ActionFailed.STATIC_PACKET);
  1034.             return;
  1035.         }
  1036.        
  1037.         if (this instanceof L2NpcInstance && target.isAlikeDead())
  1038.         {
  1039.             // If L2PcInstance is dead or the target is dead, the action is stoped
  1040.             getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  1041.            
  1042.             sendPacket(ActionFailed.STATIC_PACKET);
  1043.             return;
  1044.         }
  1045.        
  1046.         if (this instanceof L2PcInstance && target.isDead() && !target.isFakeDeath())
  1047.         {
  1048.             // If L2PcInstance is dead or the target is dead, the action is stoped
  1049.             getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  1050.            
  1051.             sendPacket(ActionFailed.STATIC_PACKET);
  1052.             return;
  1053.         }
  1054.        
  1055.         if (!getKnownList().knowsObject(target))
  1056.         {
  1057.             // If L2PcInstance is dead or the target is dead, the action is stoped
  1058.             getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  1059.            
  1060.             sendPacket(ActionFailed.STATIC_PACKET);
  1061.             return;
  1062.         }
  1063.        
  1064.         if (this instanceof L2PcInstance && isDead())
  1065.         {
  1066.             // If L2PcInstance is dead or the target is dead, the action is stoped
  1067.             getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  1068.            
  1069.             sendPacket(ActionFailed.STATIC_PACKET);
  1070.             return;
  1071.         }
  1072.        
  1073.         if (target instanceof L2PcInstance && ((L2PcInstance) target).getDuelState() == Duel.DUELSTATE_DEAD)
  1074.         {
  1075.             // If L2PcInstance is dead or the target is dead, the action is stoped
  1076.             getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  1077.            
  1078.             sendPacket(ActionFailed.STATIC_PACKET);
  1079.             return;
  1080.         }
  1081.        
  1082.         if (target instanceof L2DoorInstance && !((L2DoorInstance) target).isAttackable(this))
  1083.             return;
  1084.        
  1085.         if (isAttackingDisabled())
  1086.             return;
  1087.        
  1088.         if (this instanceof L2PcInstance)
  1089.         {
  1090.             if (((L2PcInstance) this).inObserverMode())
  1091.             {
  1092.                 sendPacket(new SystemMessage(SystemMessageId.OBSERVERS_CANNOT_PARTICIPATE));
  1093.                 sendPacket(ActionFailed.STATIC_PACKET);
  1094.                 return;
  1095.             }
  1096.            
  1097.             if (target instanceof L2PcInstance)
  1098.             {
  1099.                 if (((L2PcInstance) target).isCursedWeaponEquiped() && ((L2PcInstance) this).getLevel() <= Config.MAX_LEVEL_NEWBIE)
  1100.                 {
  1101.                     ((L2PcInstance) this).sendMessage("Can't attack a cursed player when under level 21.");
  1102.                     sendPacket(ActionFailed.STATIC_PACKET);
  1103.                     return;
  1104.                 }
  1105.                
  1106.                 if (((L2PcInstance) this).isCursedWeaponEquiped() && ((L2PcInstance) target).getLevel() <= Config.MAX_LEVEL_NEWBIE)
  1107.                 {
  1108.                     ((L2PcInstance) this).sendMessage("Can't attack a newbie player using a cursed weapon.");
  1109.                     sendPacket(ActionFailed.STATIC_PACKET);
  1110.                     return;
  1111.                 }
  1112.             }
  1113.            
  1114.             // thank l2dot
  1115.             if (getObjectId() == target.getObjectId())
  1116.             {
  1117.                 sendPacket(ActionFailed.STATIC_PACKET);
  1118.                 return;
  1119.             }
  1120.            
  1121.             if (target instanceof L2NpcInstance && Config.DISABLE_ATTACK_NPC_TYPE)
  1122.             {
  1123.                 final String mobtype = ((L2NpcInstance) target).getTemplate().type;
  1124.                 if (!Config.LIST_ALLOWED_NPC_TYPES.contains(mobtype))
  1125.                 {
  1126.                     final SystemMessage sm = new SystemMessage(SystemMessageId.S1_S2);
  1127.                     sm.addString("Npc Type " + mobtype + " has Protection - No Attack Allowed!");
  1128.                     ((L2PcInstance) this).sendPacket(sm);
  1129.                     ((L2PcInstance) this).sendPacket(ActionFailed.STATIC_PACKET);
  1130.                     return;
  1131.                 }
  1132.             }
  1133.         }
  1134.        
  1135.         // Get the active weapon instance (always equiped in the right hand)
  1136.         L2ItemInstance weaponInst = getActiveWeaponInstance();
  1137.        
  1138.         // Get the active weapon item corresponding to the active weapon instance (always equiped in the right hand)
  1139.         L2Weapon weaponItem = getActiveWeaponItem();
  1140.        
  1141.         if (weaponItem != null && weaponItem.getItemType() == L2WeaponType.ROD)
  1142.         {
  1143.             // You can't make an attack with a fishing pole.
  1144.             ((L2PcInstance) this).sendPacket(new SystemMessage(SystemMessageId.CANNOT_ATTACK_WITH_FISHING_POLE));
  1145.             getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  1146.            
  1147.             sendPacket(ActionFailed.STATIC_PACKET);
  1148.             return;
  1149.         }
  1150.        
  1151.         /*
  1152.          * TEMPFIX: Check client Z coordinate instead of server z to avoid exploit killing Zaken from others floor
  1153.          */
  1154.         if ((target instanceof L2GrandBossInstance) && ((L2GrandBossInstance) target).getNpcId() == 29022)
  1155.         {
  1156.             if (Math.abs(this.getClientZ() - target.getZ()) > 200)
  1157.             {
  1158.                 sendPacket(new SystemMessage(SystemMessageId.CANT_SEE_TARGET));
  1159.                 getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  1160.                 sendPacket(ActionFailed.STATIC_PACKET);
  1161.                 return;
  1162.             }
  1163.         }
  1164.        
  1165.         // GeoData Los Check here (or dz > 1000)
  1166.         if (!GeoData.getInstance().canSeeTarget(this, target))
  1167.         {
  1168.             sendPacket(new SystemMessage(SystemMessageId.CANT_SEE_TARGET));
  1169.             getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  1170.             sendPacket(ActionFailed.STATIC_PACKET);
  1171.             return;
  1172.         }
  1173.        
  1174.         // Check for a bow
  1175.         if (weaponItem != null && weaponItem.getItemType() == L2WeaponType.BOW)
  1176.         {
  1177.             // Equip arrows needed in left hand and send a Server->Client packet ItemList to the L2PcINstance then return True
  1178.             if (!checkAndEquipArrows())
  1179.             {
  1180.                 // Cancel the action because the L2PcInstance have no arrow
  1181.                 getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  1182.                
  1183.                 sendPacket(ActionFailed.STATIC_PACKET);
  1184.                 sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ARROWS));
  1185.                 return;
  1186.             }
  1187.            
  1188.             // Check for arrows and MP
  1189.             if (this instanceof L2PcInstance)
  1190.             {
  1191.                 // Checking if target has moved to peace zone - only for player-bow attacks at the moment
  1192.                 // Other melee is checked in movement code and for offensive spells a check is done every time
  1193.                 if (target.isInsidePeaceZone((L2PcInstance) this))
  1194.                 {
  1195.                     getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  1196.                     sendPacket(ActionFailed.STATIC_PACKET);
  1197.                     return;
  1198.                 }
  1199.                
  1200.                 // Verify if the bow can be use
  1201.                 if (_disableBowAttackEndTime <= GameTimeController.getGameTicks())
  1202.                 {
  1203.                     // Verify if L2PcInstance owns enough MP
  1204.                     final int saMpConsume = (int) getStat().calcStat(Stats.MP_CONSUME, 0, null, null);
  1205.                     final int mpConsume = saMpConsume == 0 ? weaponItem.getMpConsume() : saMpConsume;
  1206.                    
  1207.                     if (getCurrentMp() < mpConsume)
  1208.                     {
  1209.                         // If L2PcInstance doesn't have enough MP, stop the attack
  1210.                         ThreadPoolManager.getInstance().scheduleAi(new NotifyAITask(CtrlEvent.EVT_READY_TO_ACT), 1000);
  1211.                        
  1212.                         sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_MP));
  1213.                         sendPacket(ActionFailed.STATIC_PACKET);
  1214.                         return;
  1215.                     }
  1216.                     // If L2PcInstance have enough MP, the bow consummes it
  1217.                     getStatus().reduceMp(mpConsume);
  1218.                    
  1219.                     // Set the period of bow non re-use
  1220.                     _disableBowAttackEndTime = 5 * GameTimeController.TICKS_PER_SECOND + GameTimeController.getGameTicks();
  1221.                 }
  1222.                 else
  1223.                 {
  1224.                     // Cancel the action because the bow can't be re-use at this moment
  1225.                     ThreadPoolManager.getInstance().scheduleAi(new NotifyAITask(CtrlEvent.EVT_READY_TO_ACT), 1000);
  1226.                    
  1227.                     sendPacket(ActionFailed.STATIC_PACKET);
  1228.                     return;
  1229.                 }
  1230.                
  1231.             }
  1232.             else if (this instanceof L2NpcInstance)
  1233.             {
  1234.                 if (_disableBowAttackEndTime > GameTimeController.getGameTicks())
  1235.                     return;
  1236.             }
  1237.         }
  1238.        
  1239.         // Add the L2PcInstance to _knownObjects and _knownPlayer of the target
  1240.         target.getKnownList().addKnownObject(this);
  1241.        
  1242.         // Reduce the current CP if TIREDNESS configuration is activated
  1243.         if (Config.ALT_GAME_TIREDNESS)
  1244.         {
  1245.             setCurrentCp(getCurrentCp() - 10);
  1246.         }
  1247.        
  1248.         final int timeAtk = calculateTimeBetweenAttacks(target, weaponItem);
  1249.        
  1250.         // Recharge any active auto soulshot tasks for player (or player's summon if one exists).
  1251.         if (this instanceof L2PcInstance)
  1252.         {
  1253.             ((L2PcInstance) this).rechargeAutoSoulShot(true, false, false, timeAtk);
  1254.         }
  1255.         else if (this instanceof L2Summon)
  1256.         {
  1257.             ((L2Summon) this).getOwner().rechargeAutoSoulShot(true, false, true, timeAtk);
  1258.         }
  1259.        
  1260.         // Verify if soulshots are charged.
  1261.         boolean wasSSCharged;
  1262.        
  1263.         if (this instanceof L2Summon && !(this instanceof L2PetInstance))
  1264.         {
  1265.             wasSSCharged = ((L2Summon) this).getChargedSoulShot() != L2ItemInstance.CHARGED_NONE;
  1266.         }
  1267.         else
  1268.         {
  1269.             wasSSCharged = weaponInst != null && weaponInst.getChargedSoulshot() != L2ItemInstance.CHARGED_NONE;
  1270.         }
  1271.        
  1272.         // Get the Attack Speed of the L2Character (delay (in milliseconds) before next attack)
  1273.         // the hit is calculated to happen halfway to the animation - might need further tuning e.g. in bow case
  1274.         final int timeToHit = timeAtk / 2;
  1275.         _attackEndTime = GameTimeController.getGameTicks();
  1276.         _attackEndTime += (timeAtk / GameTimeController.MILLIS_IN_TICK);
  1277.         _attackEndTime -= 1;
  1278.        
  1279.         int ssGrade = 0;
  1280.        
  1281.         if (weaponItem != null)
  1282.         {
  1283.             ssGrade = weaponItem.getCrystalType();
  1284.         }
  1285.        
  1286.         // Create a Server->Client packet Attack
  1287.         Attack attack = new Attack(this, wasSSCharged, ssGrade);
  1288.        
  1289.         boolean hitted;
  1290.        
  1291.         // Set the Attacking Body part to CHEST
  1292.         setAttackingBodypart();
  1293.        
  1294.         // Heading calculation on every attack
  1295.         this.setHeading(Util.calculateHeadingFrom(this.getX(), this.getY(), target.getX(), target.getY()));
  1296.        
  1297.         // Get the Attack Reuse Delay of the L2Weapon
  1298.         final int reuse = calculateReuseTime(target, weaponItem);
  1299.        
  1300.         // Select the type of attack to start
  1301.         if (weaponItem == null)
  1302.         {
  1303.             hitted = doAttackHitSimple(attack, target, timeToHit);
  1304.         }
  1305.         else if (weaponItem.getItemType() == L2WeaponType.BOW)
  1306.         {
  1307.             hitted = doAttackHitByBow(attack, target, timeAtk, reuse);
  1308.         }
  1309.         else if (weaponItem.getItemType() == L2WeaponType.POLE)
  1310.         {
  1311.             hitted = doAttackHitByPole(attack, timeToHit);
  1312.         }
  1313.         else if (isUsingDualWeapon())
  1314.         {
  1315.             hitted = doAttackHitByDual(attack, target, timeToHit);
  1316.         }
  1317.         else
  1318.         {
  1319.             hitted = doAttackHitSimple(attack, target, timeToHit);
  1320.         }
  1321.        
  1322.         // Flag the attacker if it's a L2PcInstance outside a PvP area
  1323.         L2PcInstance player = null;
  1324.        
  1325.         if (this instanceof L2PcInstance)
  1326.         {
  1327.             player = (L2PcInstance) this;
  1328.         }
  1329.         else if (this instanceof L2Summon)
  1330.         {
  1331.             player = ((L2Summon) this).getOwner();
  1332.         }
  1333.        
  1334.         if (player != null)
  1335.         {
  1336.             player.updatePvPStatus(target);
  1337.         }
  1338.        
  1339.         // Check if hit isn't missed
  1340.         if (!hitted)
  1341.         {
  1342.             // MAJAX fix
  1343.             sendPacket(new SystemMessage(SystemMessageId.MISSED_TARGET));
  1344.             // Abort the attack of the L2Character and send Server->Client ActionFailed packet
  1345.             abortAttack();
  1346.         }
  1347.         else
  1348.         {
  1349.             /*
  1350.              * ADDED BY nexus - 2006-08-17 As soon as we know that our hit landed, we must discharge any active soulshots. This must be done so to avoid unwanted soulshot consumption.
  1351.              */
  1352.            
  1353.             // If we didn't miss the hit, discharge the shoulshots, if any
  1354.             if (this instanceof L2Summon && !(this instanceof L2PetInstance))
  1355.             {
  1356.                 ((L2Summon) this).setChargedSoulShot(L2ItemInstance.CHARGED_NONE);
  1357.             }
  1358.             else if (weaponInst != null)
  1359.             {
  1360.                 weaponInst.setChargedSoulshot(L2ItemInstance.CHARGED_NONE);
  1361.             }
  1362.            
  1363.             if (player != null)
  1364.             {
  1365.                 if (player.isCursedWeaponEquiped())
  1366.                 {
  1367.                     // If hitted by a cursed weapon, Cp is reduced to 0
  1368.                     if (!target.isInvul())
  1369.                     {
  1370.                         target.setCurrentCp(0);
  1371.                     }
  1372.                 }
  1373.                 else if (player.isHero())
  1374.                 {
  1375.                     if (target instanceof L2PcInstance && ((L2PcInstance) target).isCursedWeaponEquiped())
  1376.                     {
  1377.                         // If a cursed weapon is hitted by a Hero, Cp is reduced to 0
  1378.                         target.setCurrentCp(0);
  1379.                     }
  1380.                 }
  1381.             }
  1382.            
  1383.             weaponInst = null;
  1384.             weaponItem = null;
  1385.         }
  1386.        
  1387.         // If the Server->Client packet Attack contains at least 1 hit, send the Server->Client packet Attack
  1388.         // to the L2Character AND to all L2PcInstance in the _KnownPlayers of the L2Character
  1389.         if (attack.hasHits())
  1390.         {
  1391.             broadcastPacket(attack);
  1392.             fireEvent(EventType.ATTACK.name, new Object[]
  1393.             {
  1394.                 getTarget()
  1395.             });
  1396.         }
  1397.        
  1398.         // Like L2OFF mobs id 27181 can teleport players near cabrio
  1399.         if (this instanceof L2MonsterInstance && ((L2MonsterInstance) this).getNpcId() == 27181)
  1400.         {
  1401.             final int rndNum = Rnd.get(100);
  1402.             final L2PcInstance gettarget = (L2PcInstance) this.getTarget();
  1403.            
  1404.             if (rndNum < 5 && gettarget != null)
  1405.                 gettarget.teleToLocation(179768, 6364, -2734);
  1406.         }
  1407.        
  1408.         // Like L2OFF if target is not auto attackable you give only one hit
  1409.         if (this instanceof L2PcInstance && target instanceof L2PcInstance && !target.isAutoAttackable(this))
  1410.         {
  1411.             ((L2PcInstance) this).getAI().clientStopAutoAttack();
  1412.             ((L2PcInstance) this).getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, this);
  1413.         }
  1414.        
  1415.         // Notify AI with EVT_READY_TO_ACT
  1416.         ThreadPoolManager.getInstance().scheduleAi(new NotifyAITask(CtrlEvent.EVT_READY_TO_ACT), timeAtk + reuse);
  1417.        
  1418.         attack = null;
  1419.         player = null;
  1420.     }
  1421.    
  1422.     /**
  1423.      * Launch a Bow attack.<BR>
  1424.      * <BR>
  1425.      * <B><U> Actions</U> :</B><BR>
  1426.      * <BR>
  1427.      * <li>Calculate if hit is missed or not</li> <li>Consumme arrows</li> <li>If hit isn't missed, calculate if shield defense is efficient</li> <li>If hit isn't missed, calculate if hit is critical</li> <li>If hit isn't missed, calculate physical damages</li> <li>If the L2Character is a
  1428.      * L2PcInstance, Send a Server->Client packet SetupGauge</li> <li>Create a new hit task with Medium priority</li> <li>Calculate and set the disable delay of the bow in function of the Attack Speed</li> <li>Add this hit to the Server-Client packet Attack</li><BR>
  1429.      * <BR>
  1430.      * @param attack Server->Client packet Attack in which the hit will be added
  1431.      * @param target The L2Character targeted
  1432.      * @param sAtk The Attack Speed of the attacker
  1433.      * @param reuse the reuse
  1434.      * @return True if the hit isn't missed
  1435.      */
  1436.     private boolean doAttackHitByBow(final Attack attack, final L2Character target, final int sAtk, final int reuse)
  1437.     {
  1438.         int damage1 = 0;
  1439.         boolean shld1 = false;
  1440.         boolean crit1 = false;
  1441.        
  1442.         // Calculate if hit is missed or not
  1443.         final boolean miss1 = Formulas.calcHitMiss(this, target);
  1444.        
  1445.         // Consumme arrows
  1446.         reduceArrowCount();
  1447.        
  1448.         _move = null;
  1449.        
  1450.         // Check if hit isn't missed
  1451.         if (!miss1)
  1452.         {
  1453.             // Calculate if shield defense is efficient
  1454.             shld1 = Formulas.calcShldUse(this, target);
  1455.            
  1456.             // Calculate if hit is critical
  1457.             crit1 = Formulas.calcCrit(getStat().getCriticalHit(target, null));
  1458.            
  1459.             // Calculate physical damages
  1460.             damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, false, attack.soulshot);
  1461.         }
  1462.        
  1463.         // Check if the L2Character is a L2PcInstance
  1464.         if (this instanceof L2PcInstance)
  1465.         {
  1466.             // Send a system message
  1467.             sendPacket(new SystemMessage(SystemMessageId.GETTING_READY_TO_SHOOT_AN_ARROW));
  1468.            
  1469.             // Send a Server->Client packet SetupGauge
  1470.             SetupGauge sg = new SetupGauge(SetupGauge.RED, sAtk + reuse);
  1471.             sendPacket(sg);
  1472.             sg = null;
  1473.         }
  1474.        
  1475.         // Create a new hit task with Medium priority
  1476.         ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage1, crit1, miss1, attack.soulshot, shld1), sAtk);
  1477.        
  1478.         // Calculate and set the disable delay of the bow in function of the Attack Speed
  1479.         _disableBowAttackEndTime = (sAtk + reuse) / GameTimeController.MILLIS_IN_TICK + GameTimeController.getGameTicks();
  1480.        
  1481.         // Add this hit to the Server-Client packet Attack
  1482.         attack.addHit(target, damage1, miss1, crit1, shld1);
  1483.        
  1484.         // Return true if hit isn't missed
  1485.         return !miss1;
  1486.     }
  1487.    
  1488.     /**
  1489.      * Launch a Dual attack.<BR>
  1490.      * <BR>
  1491.      * <B><U> Actions</U> :</B><BR>
  1492.      * <BR>
  1493.      * <li>Calculate if hits are missed or not</li> <li>If hits aren't missed, calculate if shield defense is efficient</li> <li>If hits aren't missed, calculate if hit is critical</li> <li>If hits aren't missed, calculate physical damages</li> <li>Create 2 new hit tasks with Medium priority</li>
  1494.      * <li>Add those hits to the Server-Client packet Attack</li><BR>
  1495.      * <BR>
  1496.      * @param attack Server->Client packet Attack in which the hit will be added
  1497.      * @param target The L2Character targeted
  1498.      * @param sAtk the s atk
  1499.      * @return True if hit 1 or hit 2 isn't missed
  1500.      */
  1501.     private boolean doAttackHitByDual(final Attack attack, final L2Character target, final int sAtk)
  1502.     {
  1503.         int damage1 = 0;
  1504.         int damage2 = 0;
  1505.         boolean shld1 = false;
  1506.         boolean shld2 = false;
  1507.         boolean crit1 = false;
  1508.         boolean crit2 = false;
  1509.        
  1510.         // Calculate if hits are missed or not
  1511.         final boolean miss1 = Formulas.calcHitMiss(this, target);
  1512.         final boolean miss2 = Formulas.calcHitMiss(this, target);
  1513.        
  1514.         // Check if hit 1 isn't missed
  1515.         if (!miss1)
  1516.         {
  1517.             // Calculate if shield defense is efficient against hit 1
  1518.             shld1 = Formulas.calcShldUse(this, target);
  1519.            
  1520.             // Calculate if hit 1 is critical
  1521.             crit1 = Formulas.calcCrit(getStat().getCriticalHit(target, null));
  1522.            
  1523.             // Calculate physical damages of hit 1
  1524.             damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, true, attack.soulshot);
  1525.             damage1 /= 2;
  1526.         }
  1527.        
  1528.         // Check if hit 2 isn't missed
  1529.         if (!miss2)
  1530.         {
  1531.             // Calculate if shield defense is efficient against hit 2
  1532.             shld2 = Formulas.calcShldUse(this, target);
  1533.            
  1534.             // Calculate if hit 2 is critical
  1535.             crit2 = Formulas.calcCrit(getStat().getCriticalHit(target, null));
  1536.            
  1537.             // Calculate physical damages of hit 2
  1538.             damage2 = (int) Formulas.calcPhysDam(this, target, null, shld2, crit2, true, attack.soulshot);
  1539.             damage2 /= 2;
  1540.         }
  1541.        
  1542.         // Create a new hit task with Medium priority for hit 1
  1543.         ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage1, crit1, miss1, attack.soulshot, shld1), sAtk / 2);
  1544.        
  1545.         // Create a new hit task with Medium priority for hit 2 with a higher delay
  1546.         ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage2, crit2, miss2, attack.soulshot, shld2), sAtk);
  1547.        
  1548.         // Add those hits to the Server-Client packet Attack
  1549.         attack.addHit(target, damage1, miss1, crit1, shld1);
  1550.         attack.addHit(target, damage2, miss2, crit2, shld2);
  1551.        
  1552.         // Return true if hit 1 or hit 2 isn't missed
  1553.         return !miss1 || !miss2;
  1554.     }
  1555.    
  1556.     /**
  1557.      * Launch a Pole attack.<BR>
  1558.      * <BR>
  1559.      * <B><U> Actions</U> :</B><BR>
  1560.      * <BR>
  1561.      * <li>Get all visible objects in a spheric area near the L2Character to obtain possible targets</li> <li>If possible target is the L2Character targeted, launch a simple attack against it</li> <li>If possible target isn't the L2Character targeted but is attakable, launch a simple attack against
  1562.      * it</li><BR>
  1563.      * <BR>
  1564.      * @param attack Server->Client packet Attack in which the hit will be added
  1565.      * @param sAtk the s atk
  1566.      * @return True if one hit isn't missed
  1567.      */
  1568.     private boolean doAttackHitByPole(final Attack attack, final int sAtk)
  1569.     {
  1570.         boolean hitted = false;
  1571.        
  1572.         double angleChar, angleTarget;
  1573.         final int maxRadius = (int) getStat().calcStat(Stats.POWER_ATTACK_RANGE, 66, null, null);
  1574.         final int maxAngleDiff = (int) getStat().calcStat(Stats.POWER_ATTACK_ANGLE, 120, null, null);
  1575.        
  1576.         if (getTarget() == null)
  1577.             return false;
  1578.        
  1579.         angleTarget = Util.calculateAngleFrom(this, getTarget());
  1580.         setHeading((int) (angleTarget / 9.0 * 1610.0));
  1581.        
  1582.         angleChar = Util.convertHeadingToDegree(getHeading());
  1583.         double attackpercent = 85;
  1584.         final int attackcountmax = (int) getStat().calcStat(Stats.ATTACK_COUNT_MAX, 3, null, null);
  1585.         int attackcount = 0;
  1586.        
  1587.         if (angleChar <= 0)
  1588.             angleChar += 360;
  1589.        
  1590.         L2Character target;
  1591.         for (final L2Object obj : getKnownList().getKnownObjects().values())
  1592.         {
  1593.             if (obj instanceof L2Character)
  1594.             {
  1595.                 if (obj instanceof L2PetInstance && this instanceof L2PcInstance && ((L2PetInstance) obj).getOwner() == (L2PcInstance) this)
  1596.                 {
  1597.                     continue;
  1598.                 }
  1599.                
  1600.                 if (!Util.checkIfInRange(maxRadius, this, obj, false))
  1601.                 {
  1602.                     continue;
  1603.                 }
  1604.                
  1605.                 if (Math.abs(obj.getZ() - getZ()) > Config.DIFFERENT_Z_CHANGE_OBJECT)
  1606.                 {
  1607.                     continue;
  1608.                 }
  1609.                
  1610.                 angleTarget = Util.calculateAngleFrom(this, obj);
  1611.                
  1612.                 if (Math.abs(angleChar - angleTarget) > maxAngleDiff && Math.abs(angleChar + 360 - angleTarget) > maxAngleDiff && Math.abs(angleChar - (angleTarget + 360)) > maxAngleDiff)
  1613.                 {
  1614.                     continue;
  1615.                 }
  1616.                
  1617.                 target = (L2Character) obj;
  1618.                
  1619.                 if (!target.isAlikeDead())
  1620.                 {
  1621.                     attackcount += 1;
  1622.                    
  1623.                     if (attackcount <= attackcountmax)
  1624.                     {
  1625.                         if (target == getAI().getAttackTarget() || target.isAutoAttackable(this))
  1626.                         {
  1627.                             hitted |= doAttackHitSimple(attack, target, attackpercent, sAtk);
  1628.                             attackpercent /= 1.15;
  1629.                            
  1630.                             // Flag player if the target is another player
  1631.                             if (this instanceof L2PcInstance && obj instanceof L2PcInstance)
  1632.                                 ((L2PcInstance) this).updatePvPStatus(target);
  1633.                         }
  1634.                     }
  1635.                 }
  1636.             }
  1637.         }
  1638.         target = null;
  1639.         // Return true if one hit isn't missed
  1640.         return hitted;
  1641.     }
  1642.    
  1643.     /**
  1644.      * Launch a simple attack.<BR>
  1645.      * <BR>
  1646.      * <B><U> Actions</U> :</B><BR>
  1647.      * <BR>
  1648.      * <li>Calculate if hit is missed or not</li> <li>If hit isn't missed, calculate if shield defense is efficient</li> <li>If hit isn't missed, calculate if hit is critical</li> <li>If hit isn't missed, calculate physical damages</li> <li>Create a new hit task with Medium priority</li> <li>Add
  1649.      * this hit to the Server-Client packet Attack</li><BR>
  1650.      * <BR>
  1651.      * @param attack Server->Client packet Attack in which the hit will be added
  1652.      * @param target The L2Character targeted
  1653.      * @param sAtk the s atk
  1654.      * @return True if the hit isn't missed
  1655.      */
  1656.     private boolean doAttackHitSimple(final Attack attack, final L2Character target, final int sAtk)
  1657.     {
  1658.         return doAttackHitSimple(attack, target, 100, sAtk);
  1659.     }
  1660.    
  1661.     /**
  1662.      * Do attack hit simple.
  1663.      * @param attack the attack
  1664.      * @param target the target
  1665.      * @param attackpercent the attackpercent
  1666.      * @param sAtk the s atk
  1667.      * @return true, if successful
  1668.      */
  1669.     private boolean doAttackHitSimple(final Attack attack, final L2Character target, final double attackpercent, final int sAtk)
  1670.     {
  1671.         int damage1 = 0;
  1672.         boolean shld1 = false;
  1673.         boolean crit1 = false;
  1674.        
  1675.         // Calculate if hit is missed or not
  1676.         final boolean miss1 = Formulas.calcHitMiss(this, target);
  1677.        
  1678.         // Check if hit isn't missed
  1679.         if (!miss1)
  1680.         {
  1681.             // Calculate if shield defense is efficient
  1682.             shld1 = Formulas.calcShldUse(this, target);
  1683.            
  1684.             // Calculate if hit is critical
  1685.             crit1 = Formulas.calcCrit(getStat().getCriticalHit(target, null));
  1686.            
  1687.             // Calculate physical damages
  1688.             damage1 = (int) Formulas.calcPhysDam(this, target, null, shld1, crit1, false, attack.soulshot);
  1689.            
  1690.             if (attackpercent != 100)
  1691.             {
  1692.                 damage1 = (int) (damage1 * attackpercent / 100);
  1693.             }
  1694.         }
  1695.        
  1696.         // Create a new hit task with Medium priority
  1697.         ThreadPoolManager.getInstance().scheduleAi(new HitTask(target, damage1, crit1, miss1, attack.soulshot, shld1), sAtk);
  1698.        
  1699.         // Add this hit to the Server-Client packet Attack
  1700.         attack.addHit(target, damage1, miss1, crit1, shld1);
  1701.        
  1702.         // Return true if hit isn't missed
  1703.         return !miss1;
  1704.     }
  1705.    
  1706.     /**
  1707.      * Manage the casting task (casting and interrupt time, re-use delay...) and display the casting bar and animation on client.<BR>
  1708.      * <BR>
  1709.      * <B><U> Actions</U> :</B><BR>
  1710.      * <BR>
  1711.      * <li>Verify the possibilty of the the cast : skill is a spell, caster isn't muted...</li> <li>Get the list of all targets (ex : area effects) and define the L2Charcater targeted (its stats will be used in calculation)</li> <li>Calculate the casting time (base + modifier of MAtkSpd), interrupt
  1712.      * time and re-use delay</li> <li>Send a Server->Client packet MagicSkillUser (to diplay casting animation), a packet SetupGauge (to display casting bar) and a system message</li> <li>Disable all skills during the casting time (create a task EnableAllSkills)</li> <li>Disable the skill during the
  1713.      * re-use delay (create a task EnableSkill)</li> <li>Create a task MagicUseTask (that will call method onMagicUseTimer) to launch the Magic Skill at the end of the casting time</li><BR>
  1714.      * <BR>
  1715.      * @param skill The L2Skill to use
  1716.      */
  1717.     public void doCast(final L2Skill skill)
  1718.     {
  1719.         final L2Character activeChar = this;
  1720.        
  1721.         if (skill == null)
  1722.         {
  1723.             getAI().notifyEvent(CtrlEvent.EVT_CANCEL);
  1724.             return;
  1725.         }
  1726.        
  1727.         // Check if the skill is a magic spell and if the L2Character is not muted
  1728.         if (skill.isMagic() && isMuted() && !skill.isPotion())
  1729.         {
  1730.             getAI().notifyEvent(CtrlEvent.EVT_CANCEL);
  1731.             return;
  1732.         }
  1733.  
  1734.         if (this instanceof L2PcInstance)
  1735.         {
  1736.             L2PcInstance player = (L2PcInstance) this;
  1737.             if (player.getTarget() != null && player.getTarget() == player)
  1738.                 if (skill.getSkillType() == SkillType.CHARGEDAM)
  1739.                 {
  1740.                     player.sendMessage("修理:");
  1741.                     return;
  1742.                 }  
  1743.         }
  1744.  
  1745.         // Check if the skill is psychical and if the L2Character is not psychical_muted
  1746.         if (!skill.isMagic() && isPsychicalMuted() && !skill.isPotion())
  1747.         {
  1748.             getAI().notifyEvent(CtrlEvent.EVT_CANCEL);
  1749.             return;
  1750.         }
  1751.        
  1752.         // Can't use Hero and resurrect skills during Olympiad
  1753.         if (activeChar instanceof L2PcInstance && ((L2PcInstance) activeChar).isInOlympiadMode() && (skill.isHeroSkill() || skill.getSkillType() == SkillType.RESURRECT))
  1754.         {
  1755.             SystemMessage sm = new SystemMessage(SystemMessageId.THIS_SKILL_IS_NOT_AVAILABLE_FOR_THE_OLYMPIAD_EVENT);
  1756.             sendPacket(sm);
  1757.             sm = null;
  1758.             return;
  1759.         }
  1760.        
  1761.         // Like L2OFF you can't use skills when you are attacking now
  1762.         if (activeChar instanceof L2PcInstance && !skill.isPotion())
  1763.         {
  1764.             final L2ItemInstance rhand = ((L2PcInstance) this).getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
  1765.             if ((rhand != null && rhand.getItemType() == L2WeaponType.BOW))
  1766.             {
  1767.                 if (isAttackingNow())
  1768.                     return;
  1769.             }
  1770.         }
  1771.        
  1772.         // prevent casting signets to peace zone
  1773.         if (skill.getSkillType() == SkillType.SIGNET || skill.getSkillType() == SkillType.SIGNET_CASTTIME)
  1774.         {
  1775.             /*
  1776.              * for (L2Effect effect : getAllEffects()) { if (effect.getEffectType() == L2Effect.EffectType.SIGNET_EFFECT || effect.getEffectType() == L2Effect.EffectType.SIGNET_GROUND) { SystemMessage sm = new SystemMessage(SystemMessageId.S1_CANNOT_BE_USED); sm.addSkillName(skill.getId());
  1777.              * sendPacket(sm); return; } }
  1778.              */
  1779.            
  1780.             final L2WorldRegion region = getWorldRegion();
  1781.             if (region == null)
  1782.                 return;
  1783.             boolean canCast = true;
  1784.             if (skill.getTargetType() == SkillTargetType.TARGET_GROUND && this instanceof L2PcInstance)
  1785.             {
  1786.                 final Point3D wp = ((L2PcInstance) this).getCurrentSkillWorldPosition();
  1787.                 if (!region.checkEffectRangeInsidePeaceZone(skill, wp.getX(), wp.getY(), wp.getZ()))
  1788.                     canCast = false;
  1789.             }
  1790.             else if (!region.checkEffectRangeInsidePeaceZone(skill, getX(), getY(), getZ()))
  1791.                 canCast = false;
  1792.             if (!canCast)
  1793.             {
  1794.                 final SystemMessage sm = new SystemMessage(SystemMessageId.S1_CANNOT_BE_USED);
  1795.                 sm.addSkillName(skill.getId());
  1796.                 sendPacket(sm);
  1797.                 return;
  1798.             }
  1799.         }
  1800.        
  1801.         // Recharge AutoSoulShot
  1802.        
  1803.         final int atkTime = Formulas.getInstance().calcMAtkSpd(activeChar, skill, skill.getHitTime());
  1804.         if (skill.useSoulShot())
  1805.         {
  1806.             if (activeChar instanceof L2PcInstance)
  1807.             {
  1808.                 ((L2PcInstance) activeChar).rechargeAutoSoulShot(true, false, false, atkTime);
  1809.             }
  1810.             else if (this instanceof L2Summon)
  1811.             {
  1812.                 ((L2Summon) activeChar).getOwner().rechargeAutoSoulShot(true, false, true, atkTime);
  1813.             }
  1814.         }
  1815.        
  1816.         // else if (skill.useFishShot())
  1817.         // {
  1818.         // if (this instanceof L2PcInstance)
  1819.         // ((L2PcInstance)this).rechargeAutoSoulShot(true, false, false);
  1820.         // }
  1821.        
  1822.         // Get all possible targets of the skill in a table in function of the skill target type
  1823.         final L2Object[] targets = skill.getTargetList(activeChar);
  1824.         // Set the target of the skill in function of Skill Type and Target Type
  1825.         L2Character target = null;
  1826.        
  1827.         if (skill.getTargetType() == SkillTargetType.TARGET_AURA || skill.getTargetType() == SkillTargetType.TARGET_GROUND || skill.isPotion())
  1828.         {
  1829.             target = this;
  1830.         }
  1831.         else if (targets == null || targets.length == 0)
  1832.         {
  1833.             getAI().notifyEvent(CtrlEvent.EVT_CANCEL);
  1834.             return;
  1835.         }
  1836.         else if ((skill.getSkillType() == SkillType.BUFF || skill.getSkillType() == SkillType.HEAL || skill.getSkillType() == SkillType.COMBATPOINTHEAL || skill.getSkillType() == SkillType.COMBATPOINTPERCENTHEAL || skill.getSkillType() == SkillType.MANAHEAL || skill.getSkillType() == SkillType.REFLECT || skill.getSkillType() == SkillType.SEED || skill.getTargetType() == L2Skill.SkillTargetType.TARGET_SELF || skill.getTargetType() == L2Skill.SkillTargetType.TARGET_PET || skill.getTargetType() == L2Skill.SkillTargetType.TARGET_PARTY || skill.getTargetType() == L2Skill.SkillTargetType.TARGET_CLAN || skill.getTargetType() == L2Skill.SkillTargetType.TARGET_ALLY) && !skill.isPotion())
  1837.         {
  1838.             target = (L2Character) targets[0];
  1839.            
  1840.             /*
  1841.              * if (this instanceof L2PcInstance && target instanceof L2PcInstance && target.getAI().getIntention() == CtrlIntention.AI_INTENTION_ATTACK) { if(skill.getSkillType() == SkillType.BUFF || skill.getSkillType() == SkillType.HOT || skill.getSkillType() == SkillType.HEAL ||
  1842.              * skill.getSkillType() == SkillType.HEAL_PERCENT || skill.getSkillType() == SkillType.MANAHEAL || skill.getSkillType() == SkillType.MANAHEAL_PERCENT || skill.getSkillType() == SkillType.BALANCE_LIFE) target.setLastBuffer(this); if (((L2PcInstance)this).isInParty() &&
  1843.              * skill.getTargetType() == L2Skill.SkillTargetType.TARGET_PARTY) { for (L2PcInstance member : ((L2PcInstance)this).getParty().getPartyMembers()) member.setLastBuffer(this); } }
  1844.              */
  1845.         }
  1846.         else
  1847.         {
  1848.             target = (L2Character) getTarget();
  1849.         }
  1850.        
  1851.         if (target == null)
  1852.         {
  1853.             getAI().notifyEvent(CtrlEvent.EVT_CANCEL);
  1854.             return;
  1855.         }
  1856.        
  1857.         // Player can't heal rb config
  1858.         if (!Config.PLAYERS_CAN_HEAL_RB && activeChar instanceof L2PcInstance && !((L2PcInstance) activeChar).isGM() && (target instanceof L2RaidBossInstance || target instanceof L2GrandBossInstance) && (skill.getSkillType() == SkillType.HEAL || skill.getSkillType() == SkillType.HEAL_PERCENT))
  1859.         {
  1860.             this.sendPacket(ActionFailed.STATIC_PACKET);
  1861.             return;
  1862.         }
  1863.        
  1864.         if (activeChar instanceof L2PcInstance && target instanceof L2NpcInstance && Config.DISABLE_ATTACK_NPC_TYPE)
  1865.         {
  1866.             final String mobtype = ((L2NpcInstance) target).getTemplate().type;
  1867.             if (!Config.LIST_ALLOWED_NPC_TYPES.contains(mobtype))
  1868.             {
  1869.                 final SystemMessage sm = new SystemMessage(SystemMessageId.S1_S2);
  1870.                 sm.addString("Npc Type " + mobtype + " has Protection - No Attack Allowed!");
  1871.                 ((L2PcInstance) activeChar).sendPacket(sm);
  1872.                 ((L2PcInstance) activeChar).sendPacket(ActionFailed.STATIC_PACKET);
  1873.                 return;
  1874.             }
  1875.         }
  1876.        
  1877.         if (skill.isPotion())
  1878.             setLastPotionCast(skill);
  1879.         else
  1880.             setLastSkillCast(skill);
  1881.        
  1882.         // Get the Identifier of the skill
  1883.         final int magicId = skill.getId();
  1884.        
  1885.         // Get the Display Identifier for a skill that client can't display
  1886.         final int displayId = skill.getDisplayId();
  1887.        
  1888.         // Get the level of the skill
  1889.         int level = skill.getLevel();
  1890.        
  1891.         if (level < 1)
  1892.         {
  1893.             level = 1;
  1894.         }
  1895.        
  1896.         // Get the casting time of the skill (base)
  1897.         int hitTime = skill.getHitTime();
  1898.         int coolTime = skill.getCoolTime();
  1899.         final boolean effectWhileCasting = skill.hasEffectWhileCasting();
  1900.        
  1901.         final boolean forceBuff = skill.getSkillType() == SkillType.FORCE_BUFF && target instanceof L2PcInstance;
  1902.        
  1903.         // Calculate the casting time of the skill (base + modifier of MAtkSpd)
  1904.         // Don't modify the skill time for FORCE_BUFF skills. The skill time for those skills represent the buff time.
  1905.         if (!effectWhileCasting && !forceBuff && !skill.isStaticHitTime())
  1906.         {
  1907.             hitTime = Formulas.getInstance().calcMAtkSpd(activeChar, skill, hitTime);
  1908.            
  1909.             if (coolTime > 0)
  1910.             {
  1911.                 coolTime = Formulas.getInstance().calcMAtkSpd(activeChar, skill, coolTime);
  1912.             }
  1913.         }
  1914.        
  1915.         // Calculate altered Cast Speed due to BSpS/SpS only for Magic skills
  1916.         if ((checkBss() || checkSps()) && !skill.isStaticHitTime() && !skill.isPotion() && skill.isMagic())
  1917.         {
  1918.            
  1919.             // Only takes 70% of the time to cast a BSpS/SpS cast
  1920.             hitTime = (int) (0.70 * hitTime);
  1921.             coolTime = (int) (0.70 * coolTime);
  1922.            
  1923.             // Because the following are magic skills that do not actively 'eat' BSpS/SpS,
  1924.             // I must 'eat' them here so players don't take advantage of infinite speed increase
  1925.             /* MANAHEAL, MANARECHARGE, RESURRECT, RECALL */
  1926.             // if (skill.getSkillType() == SkillType.MANAHEAL || skill.getSkillType() == SkillType.MANARECHARGE || skill.getSkillType() == SkillType.RESURRECT || skill.getSkillType() == SkillType.RECALL)
  1927.             // {
  1928.             // if (checkBss())
  1929.             // removeBss();
  1930.             // else
  1931.             // removeSps();
  1932.             // }
  1933.            
  1934.         }
  1935.        
  1936.         /*
  1937.          * // Calculate altered Cast Speed due to BSpS/SpS L2ItemInstance weaponInst = getActiveWeaponInstance(); if(weaponInst != null && skill.isMagic() && !forceBuff && skill.getTargetType() != SkillTargetType.TARGET_SELF && !skill.isStaticHitTime() && !skill.isPotion()) {
  1938.          * if(weaponInst.getChargedSpiritshot() == L2ItemInstance.CHARGED_BLESSED_SPIRITSHOT || weaponInst.getChargedSpiritshot() == L2ItemInstance.CHARGED_SPIRITSHOT) { //Only takes 70% of the time to cast a BSpS/SpS cast hitTime = (int) (0.70 * hitTime); coolTime = (int) (0.70 * coolTime);
  1939.          * //Because the following are magic skills that do not actively 'eat' BSpS/SpS, //I must 'eat' them here so players don't take advantage of infinite speed increase if(skill.getSkillType() == SkillType.BUFF || skill.getSkillType() == SkillType.MANAHEAL || skill.getSkillType() ==
  1940.          * SkillType.RESURRECT || skill.getSkillType() == SkillType.RECALL || skill.getSkillType() == SkillType.DOT) { weaponInst.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE); } } } weaponInst = null;
  1941.          */
  1942.        
  1943.         if (skill.isPotion())
  1944.         {
  1945.             // Set the _castEndTime and _castInterruptTim. +10 ticks for lag situations, will be reseted in onMagicFinalizer
  1946.             _castPotionEndTime = 10 + GameTimeController.getGameTicks() + (coolTime + hitTime) / GameTimeController.MILLIS_IN_TICK;
  1947.             _castPotionInterruptTime = -2 + GameTimeController.getGameTicks() + hitTime / GameTimeController.MILLIS_IN_TICK;
  1948.            
  1949.         }
  1950.         else
  1951.         {
  1952.             // Set the _castEndTime and _castInterruptTim. +10 ticks for lag situations, will be reseted in onMagicFinalizer
  1953.             _castEndTime = 10 + GameTimeController.getGameTicks() + (coolTime + hitTime) / GameTimeController.MILLIS_IN_TICK;
  1954.             _castInterruptTime = -2 + GameTimeController.getGameTicks() + hitTime / GameTimeController.MILLIS_IN_TICK;
  1955.            
  1956.         }
  1957.        
  1958.         // Init the reuse time of the skill
  1959.         // int reuseDelay = (int)(skill.getReuseDelay() * getStat().getMReuseRate(skill));
  1960.         // reuseDelay *= 333.0 / (skill.isMagic() ? getMAtkSpd() : getPAtkSpd());
  1961.         int reuseDelay = skill.getReuseDelay();
  1962.        
  1963.         if (activeChar instanceof L2PcInstance && Formulas.getInstance().calcSkillMastery(activeChar))
  1964.         {
  1965.             reuseDelay = 0;
  1966.         }
  1967.         else if (!skill.isStaticReuse() && !skill.isPotion())
  1968.         {
  1969.             if (skill.isMagic())
  1970.             {
  1971.                 reuseDelay *= getStat().getMReuseRate(skill);
  1972.             }
  1973.             else
  1974.             {
  1975.                 reuseDelay *= getStat().getPReuseRate(skill);
  1976.             }
  1977.            
  1978.             reuseDelay *= 333.0 / (skill.isMagic() ? getMAtkSpd() : getPAtkSpd());
  1979.         }
  1980.        
  1981.         // To turn local player in target direction
  1982.         setHeading(Util.calculateHeadingFrom(getX(), getY(), target.getX(), target.getY()));
  1983.        
  1984.         /*
  1985.          * if(skill.isOffensive() && skill.getTargetType() != SkillTargetType.TARGET_AURA && target.isBehind(this)) { moveToLocation(target.getX(), target.getY(), target.getZ(), 0); stopMove(null); }
  1986.          */
  1987.        
  1988.         // Like L2OFF after a skill the player must stop the movement, also with toggle
  1989.         if (!skill.isPotion() && this instanceof L2PcInstance)
  1990.             ((L2PcInstance) this).stopMove(null);
  1991.        
  1992.         // Start the effect as long as the player is casting.
  1993.         if (effectWhileCasting)
  1994.         {
  1995.             callSkill(skill, targets);
  1996.         }
  1997.        
  1998.         // Send a Server->Client packet MagicSkillUser with target, displayId, level, skillTime, reuseDelay
  1999.         // to the L2Character AND to all L2PcInstance in the _KnownPlayers of the L2Character
  2000.         broadcastPacket(new MagicSkillUser(this, target, displayId, level, hitTime, reuseDelay));
  2001.        
  2002.         // Send a system message USE_S1 to the L2Character
  2003.         if (activeChar instanceof L2PcInstance && magicId != 1312)
  2004.         {
  2005.             if (skill.isPotion())
  2006.             {
  2007.                 SystemMessage sm = new SystemMessage(SystemMessageId.USE_S1_);
  2008.                 if (magicId == 2005)
  2009.                     sm.addItemName(728);
  2010.                 else if (magicId == 2003)
  2011.                     sm.addItemName(726);
  2012.                 // Message greater cp potions like retail
  2013.                 else if (magicId == 2166 && skill.getLevel() == 2)
  2014.                     sm.addItemName(5592);
  2015.                 // Message cp potions like retail
  2016.                 else if (magicId == 2166 && skill.getLevel() == 1)
  2017.                     sm.addItemName(5591);
  2018.                 else
  2019.                     sm.addSkillName(magicId, skill.getLevel());
  2020.                 sendPacket(sm);
  2021.                 sm = null;
  2022.             }
  2023.             else
  2024.             {
  2025.                 SystemMessage sm = new SystemMessage(SystemMessageId.USE_S1);
  2026.                 if (magicId == 2005)
  2027.                     sm.addItemName(728);
  2028.                 else if (magicId == 2003)
  2029.                     sm.addItemName(726);
  2030.                 // Message greater cp potions like retail
  2031.                 else if (magicId == 2166 && skill.getLevel() == 2)
  2032.                     sm.addItemName(5592);
  2033.                 // Message cp potions like retail
  2034.                 else if (magicId == 2166 && skill.getLevel() == 1)
  2035.                     sm.addItemName(5591);
  2036.                 else
  2037.                     sm.addSkillName(magicId, skill.getLevel());
  2038.                
  2039.                 // Skill 2046 is used only for animation on pets
  2040.                 if (magicId != 2046)
  2041.                     sendPacket(sm);
  2042.                 sm = null;
  2043.             }
  2044.         }
  2045.        
  2046.         // Skill reuse check
  2047.         if (reuseDelay > 30000)
  2048.         {
  2049.             addTimeStamp(skill, reuseDelay);
  2050.         }
  2051.        
  2052.         // Check if this skill consume mp on start casting
  2053.         final int initmpcons = getStat().getMpInitialConsume(skill);
  2054.        
  2055.         if (initmpcons > 0)
  2056.         {
  2057.             StatusUpdate su = new StatusUpdate(getObjectId());
  2058.            
  2059.             if (skill.isDance())
  2060.             {
  2061.                 getStatus().reduceMp(calcStat(Stats.DANCE_MP_CONSUME_RATE, initmpcons, null, null));
  2062.             }
  2063.             else if (skill.isMagic())
  2064.             {
  2065.                 getStatus().reduceMp(calcStat(Stats.MAGICAL_MP_CONSUME_RATE, initmpcons, null, null));
  2066.             }
  2067.             else
  2068.             {
  2069.                 getStatus().reduceMp(calcStat(Stats.PHYSICAL_MP_CONSUME_RATE, initmpcons, null, null));
  2070.             }
  2071.            
  2072.             su.addAttribute(StatusUpdate.CUR_MP, (int) getCurrentMp());
  2073.             sendPacket(su);
  2074.             su = null;
  2075.         }
  2076.        
  2077.         // Disable the skill during the re-use delay and create a task EnableSkill with Medium priority to enable it at the end of the re-use delay
  2078.         if (reuseDelay > 10)
  2079.         {
  2080.             disableSkill(skill, reuseDelay);
  2081.         }
  2082.        
  2083.         // For force buff skills, start the effect as long as the player is casting.
  2084.         if (forceBuff)
  2085.         {
  2086.             startForceBuff(target, skill);
  2087.         }
  2088.        
  2089.         // launch the magic in hitTime milliseconds
  2090.         if (hitTime > 210)
  2091.         {
  2092.             // Send a Server->Client packet SetupGauge with the color of the gauge and the casting time
  2093.             if (activeChar instanceof L2PcInstance && !forceBuff)
  2094.             {
  2095.                 SetupGauge sg = new SetupGauge(SetupGauge.BLUE, hitTime);
  2096.                 sendPacket(sg);
  2097.                 sg = null;
  2098.             }
  2099.            
  2100.             // Disable all skills during the casting
  2101.             if (!skill.isPotion())
  2102.             { // for particular potion is the timestamp to disable particular skill
  2103.            
  2104.                 disableAllSkills();
  2105.                
  2106.                 if (_skillCast != null) // delete previous skill cast
  2107.                 {
  2108.                     _skillCast.cancel(true);
  2109.                     _skillCast = null;
  2110.                 }
  2111.                
  2112.             }
  2113.            
  2114.             // Create a task MagicUseTask to launch the MagicSkill at the end of the casting time (hitTime)
  2115.             // For client animation reasons (party buffs especially) 200 ms before!
  2116.             if (getForceBuff() != null || effectWhileCasting)
  2117.             {
  2118.                 if (skill.isPotion())
  2119.                     _potionCast = ThreadPoolManager.getInstance().scheduleEffect(new MagicUseTask(targets, skill, coolTime, 2), hitTime);
  2120.                
  2121.                 else
  2122.                     _skillCast = ThreadPoolManager.getInstance().scheduleEffect(new MagicUseTask(targets, skill, coolTime, 2), hitTime);
  2123.             }
  2124.             else
  2125.             {
  2126.                 if (skill.isPotion())
  2127.                     _potionCast = ThreadPoolManager.getInstance().scheduleEffect(new MagicUseTask(targets, skill, coolTime, 1), hitTime - 200);
  2128.                
  2129.                 else
  2130.                     _skillCast = ThreadPoolManager.getInstance().scheduleEffect(new MagicUseTask(targets, skill, coolTime, 1), hitTime - 200);
  2131.             }
  2132.         }
  2133.         else
  2134.         {
  2135.             onMagicLaunchedTimer(targets, skill, coolTime, true);
  2136.         }
  2137.         fireEvent(EventType.CAST.name, new Object[]
  2138.         {
  2139.             skill,
  2140.             target,
  2141.             targets
  2142.         });
  2143.        
  2144.     }
  2145.    
  2146.     /**
  2147.      * Index according to skill id the current timestamp of use.<br>
  2148.      * @param skill the s
  2149.      * @param r the r
  2150.      */
  2151.     public void addTimeStamp(final L2Skill skill, final int r)
  2152.     {
  2153.        
  2154.     }
  2155.    
  2156.     /**
  2157.      * Index according to skill id the current timestamp of use.<br>
  2158.      * @param _skill the s
  2159.      */
  2160.     public void removeTimeStamp(final L2Skill _skill)
  2161.     {
  2162.        
  2163.     }
  2164.    
  2165.     /**
  2166.      * Starts a force buff on target.<br>
  2167.      * @param target the target
  2168.      * @param skill the skill
  2169.      */
  2170.     public void startForceBuff(final L2Character target, final L2Skill skill)
  2171.     {
  2172.         if (skill.getSkillType() != SkillType.FORCE_BUFF)
  2173.             return;
  2174.        
  2175.         if (_forceBuff == null)
  2176.         {
  2177.             _forceBuff = new ForceBuff(this, target, skill);
  2178.         }
  2179.     }
  2180.    
  2181.     /**
  2182.      * Kill the L2Character.<BR>
  2183.      * <BR>
  2184.      * <B><U> Actions</U> :</B><BR>
  2185.      * <BR>
  2186.      * <li>Set target to null and cancel Attack or Cast</li> <li>Stop movement</li> <li>Stop HP/MP/CP Regeneration task</li> <li>Stop all active skills effects in progress on the L2Character</li> <li>Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to
  2187.      * inform</li> <li>Notify L2Character AI</li><BR>
  2188.      * <BR>
  2189.      * <B><U> Overriden in </U> :</B><BR>
  2190.      * <BR>
  2191.      * <li>L2NpcInstance : Create a DecayTask to remove the corpse of the L2NpcInstance after 7 seconds</li> <li>L2Attackable : Distribute rewards (EXP, SP, Drops...) and notify Quest Engine</li> <li>L2PcInstance : Apply Death Penalty, Manage gain/loss Karma and Item Drop</li><BR>
  2192.      * <BR>
  2193.      * @param killer The L2Character who killed it
  2194.      * @return true, if successful
  2195.      */
  2196.     public boolean doDie(final L2Character killer)
  2197.     {
  2198.         // killing is only possible one time
  2199.         synchronized (this)
  2200.         {
  2201.             if (isKilledAlready())
  2202.                 return false;
  2203.            
  2204.             setIsKilledAlready(true);
  2205.         }
  2206.         // Set target to null and cancel Attack or Cast
  2207.         setTarget(null);
  2208.        
  2209.         // Stop fear to avoid possible bug with char position after death
  2210.         if (isAfraid())
  2211.             stopFear(null);
  2212.        
  2213.         // Stop movement
  2214.         stopMove(null);
  2215.        
  2216.         // Stop HP/MP/CP Regeneration task
  2217.         getStatus().stopHpMpRegeneration();
  2218.        
  2219.         // Stop all active skills effects in progress on the L2Character,
  2220.         // if the Character isn't affected by Soul of The Phoenix or Salvation
  2221.         if (this instanceof L2PlayableInstance && ((L2PlayableInstance) this).isPhoenixBlessed())
  2222.         {
  2223.             if (((L2PlayableInstance) this).isNoblesseBlessed())
  2224.             {
  2225.                 ((L2PlayableInstance) this).stopNoblesseBlessing(null);
  2226.             }
  2227.             if (((L2PlayableInstance) this).getCharmOfLuck())
  2228.             {
  2229.                 ((L2PlayableInstance) this).stopCharmOfLuck(null);
  2230.             }
  2231.         }
  2232.         // Same thing if the Character isn't a Noblesse Blessed L2PlayableInstance
  2233.         else if (this instanceof L2PlayableInstance && ((L2PlayableInstance) this).isNoblesseBlessed())
  2234.         {
  2235.             ((L2PlayableInstance) this).stopNoblesseBlessing(null);
  2236.            
  2237.             if (((L2PlayableInstance) this).getCharmOfLuck())
  2238.             {
  2239.                 ((L2PlayableInstance) this).stopCharmOfLuck(null);
  2240.             }
  2241.         }
  2242.         else
  2243.         {
  2244.             if (this instanceof L2PcInstance)
  2245.             {
  2246.                
  2247.                 final L2PcInstance player = (L2PcInstance) this;
  2248.                
  2249.                 // to avoid Event Remove buffs on die
  2250.                 if (player._inEventDM && DM.is_started())
  2251.                 {
  2252.                     if (Config.DM_REMOVE_BUFFS_ON_DIE)
  2253.                         stopAllEffects();
  2254.                 }
  2255.                 else if (player._inEventTvT && TvT.is_started())
  2256.                 {
  2257.                     if (Config.TVT_REMOVE_BUFFS_ON_DIE)
  2258.                         stopAllEffects();
  2259.                 }
  2260.                 else if (player._inEventCTF && CTF.is_started())
  2261.                 {
  2262.                     if (Config.CTF_REMOVE_BUFFS_ON_DIE)
  2263.                         stopAllEffects();
  2264.                 }
  2265.                 else if (Config.LEAVE_BUFFS_ON_DIE) // this means that the player is not in event
  2266.                 {
  2267.                     stopAllEffects();
  2268.                 }
  2269.             }
  2270.             else
  2271.             // this means all other characters, including Summons
  2272.             {
  2273.                 stopAllEffects();
  2274.             }
  2275.         }
  2276.        
  2277.         // if killer is the same then the most damager/hated
  2278.         L2Character mostHated = null;
  2279.         if (this instanceof L2Attackable)
  2280.         {
  2281.             mostHated = ((L2Attackable) this)._mostHated;
  2282.         }
  2283.        
  2284.         if (mostHated != null && isInsideRadius(mostHated, 200, false, false))
  2285.         {
  2286.             calculateRewards(mostHated);
  2287.         }
  2288.         else
  2289.         {
  2290.             calculateRewards(killer);
  2291.         }
  2292.        
  2293.         // Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform
  2294.         broadcastStatusUpdate();
  2295.        
  2296.         // Notify L2Character AI
  2297.         getAI().notifyEvent(CtrlEvent.EVT_DEAD, null);
  2298.        
  2299.         if (getWorldRegion() != null)
  2300.         {
  2301.             getWorldRegion().onDeath(this);
  2302.         }
  2303.        
  2304.         // Notify Quest of character's death
  2305.         for (final QuestState qs : getNotifyQuestOfDeath())
  2306.         {
  2307.             qs.getQuest().notifyDeath((killer == null ? this : killer), this, qs);
  2308.         }
  2309.        
  2310.         getNotifyQuestOfDeath().clear();
  2311.        
  2312.         getAttackByList().clear();
  2313.        
  2314.         // If character is PhoenixBlessed a resurrection popup will show up
  2315.         if (this instanceof L2PlayableInstance && ((L2PlayableInstance) this).isPhoenixBlessed())
  2316.         {
  2317.             ((L2PcInstance) this).reviveRequest(((L2PcInstance) this), null, false);
  2318.         }
  2319.         fireEvent(EventType.DIE.name, new Object[]
  2320.         {
  2321.             killer
  2322.         });
  2323.        
  2324.         // Update active skills in progress (In Use and Not In Use because stacked) icones on client
  2325.         updateEffectIcons();
  2326.        
  2327.         // After dead mob check if the killer got a moving task actived
  2328.         if (killer instanceof L2PcInstance)
  2329.         {
  2330.             if (((L2PcInstance) killer).isMovingTaskDefined())
  2331.             {
  2332.                 ((L2PcInstance) killer).startMovingTask();
  2333.             }
  2334.         }
  2335.        
  2336.         return true;
  2337.     }
  2338.    
  2339.     /**
  2340.      * Calculate rewards.
  2341.      * @param killer the killer
  2342.      */
  2343.     protected void calculateRewards(final L2Character killer)
  2344.     {
  2345.     }
  2346.    
  2347.     /** Sets HP, MP and CP and revives the L2Character. */
  2348.     public void doRevive()
  2349.     {
  2350.         if (!isTeleporting())
  2351.         {
  2352.             setIsPendingRevive(false);
  2353.            
  2354.             if (this instanceof L2PlayableInstance && ((L2PlayableInstance) this).isPhoenixBlessed())
  2355.             {
  2356.                 ((L2PlayableInstance) this).stopPhoenixBlessing(null);
  2357.                
  2358.                 // Like L2OFF Soul of The Phoenix and Salvation restore all hp,cp,mp.
  2359.                 _status.setCurrentCp(getMaxCp());
  2360.                 _status.setCurrentHp(getMaxHp());
  2361.                 _status.setCurrentMp(getMaxMp());
  2362.             }
  2363.             else
  2364.             {
  2365.                 _status.setCurrentCp(getMaxCp() * Config.RESPAWN_RESTORE_CP);
  2366.                 _status.setCurrentHp(getMaxHp() * Config.RESPAWN_RESTORE_HP);
  2367.             }
  2368.         }
  2369.         // Start broadcast status
  2370.         broadcastPacket(new Revive(this));
  2371.        
  2372.         if (getWorldRegion() != null)
  2373.         {
  2374.             getWorldRegion().onRevive(this);
  2375.         }
  2376.         else
  2377.         {
  2378.             setIsPendingRevive(true);
  2379.         }
  2380.         fireEvent(EventType.REVIVE.name, (Object[]) null);
  2381.     }
  2382.    
  2383.     /**
  2384.      * Revives the L2Character using skill.
  2385.      * @param revivePower the revive power
  2386.      */
  2387.     public void doRevive(final double revivePower)
  2388.     {
  2389.         doRevive();
  2390.     }
  2391.    
  2392.     /**
  2393.      * Check if the active L2Skill can be casted.<BR>
  2394.      * <BR>
  2395.      * <B><U> Actions</U> :</B><BR>
  2396.      * <BR>
  2397.      * <li>Check if the L2Character can cast (ex : not sleeping...)</li> <li>Check if the target is correct</li> <li>Notify the AI with AI_INTENTION_CAST and target</li><BR>
  2398.      * <BR>
  2399.      * @param skill The L2Skill to use
  2400.      */
  2401.     protected void useMagic(final L2Skill skill)
  2402.     {
  2403.         if (skill == null || isDead())
  2404.             return;
  2405.        
  2406.         // Check if the L2Character can cast
  2407.         if (!skill.isPotion() && isAllSkillsDisabled())
  2408.             // must be checked by caller
  2409.             return;
  2410.        
  2411.         // Ignore the passive skill request. why does the client send it anyway ??
  2412.         if (skill.isPassive() || skill.isChance())
  2413.             return;
  2414.        
  2415.         // Get the target for the skill
  2416.         L2Object target = null;
  2417.        
  2418.         switch (skill.getTargetType())
  2419.         {
  2420.             case TARGET_AURA: // AURA, SELF should be cast even if no target has been found
  2421.             case TARGET_SELF:
  2422.                 target = this;
  2423.                 break;
  2424.             default:
  2425.                 // Get the first target of the list
  2426.                 target = skill.getFirstOfTargetList(this);
  2427.                 break;
  2428.         }
  2429.        
  2430.         // Notify the AI with AI_INTENTION_CAST and target
  2431.         getAI().setIntention(CtrlIntention.AI_INTENTION_CAST, skill, target);
  2432.         target = null;
  2433.     }
  2434.    
  2435.     // =========================================================
  2436.     // Property - Public
  2437.     /**
  2438.      * Return the L2CharacterAI of the L2Character and if its null create a new one.
  2439.      * @return the aI
  2440.      */
  2441.     public L2CharacterAI getAI()
  2442.     {
  2443.         if (_ai == null)
  2444.         {
  2445.             synchronized (this)
  2446.             {
  2447.                 if (_ai == null)
  2448.                 {
  2449.                     _ai = new L2CharacterAI(new AIAccessor());
  2450.                 }
  2451.             }
  2452.         }
  2453.        
  2454.         return _ai;
  2455.     }
  2456.    
  2457.     /**
  2458.      * Sets the aI.
  2459.      * @param newAI the new aI
  2460.      */
  2461.     public void setAI(final L2CharacterAI newAI)
  2462.     {
  2463.         L2CharacterAI oldAI = getAI();
  2464.        
  2465.         if (oldAI != null && oldAI != newAI && oldAI instanceof L2AttackableAI)
  2466.         {
  2467.             ((L2AttackableAI) oldAI).stopAITask();
  2468.         }
  2469.         _ai = newAI;
  2470.        
  2471.         oldAI = null;
  2472.     }
  2473.    
  2474.     /**
  2475.      * Return True if the L2Character has a L2CharacterAI.
  2476.      * @return true, if successful
  2477.      */
  2478.     public boolean hasAI()
  2479.     {
  2480.         return _ai != null;
  2481.     }
  2482.    
  2483.     /**
  2484.      * Return True if the L2Character is RaidBoss or his minion.
  2485.      * @return true, if is raid
  2486.      */
  2487.     @Override
  2488.     public boolean isRaid()
  2489.     {
  2490.         return false;
  2491.     }
  2492.    
  2493.     /**
  2494.      * Return True if the L2Character is an Npc.
  2495.      * @return true, if is npc
  2496.      */
  2497.     @Override
  2498.     public boolean isNpc()
  2499.     {
  2500.         return false;
  2501.     }
  2502.    
  2503.     /**
  2504.      * Return a list of L2Character that attacked.
  2505.      * @return the attack by list
  2506.      */
  2507.     public final List<L2Character> getAttackByList()
  2508.     {
  2509.         if (_attackByList == null)
  2510.         {
  2511.             _attackByList = new FastList<>();
  2512.         }
  2513.        
  2514.         return _attackByList;
  2515.     }
  2516.    
  2517.     /**
  2518.      * Gets the last skill cast.
  2519.      * @return the last skill cast
  2520.      */
  2521.     public final L2Skill getLastSkillCast()
  2522.     {
  2523.         return _lastSkillCast;
  2524.     }
  2525.    
  2526.     /**
  2527.      * Sets the last skill cast.
  2528.      * @param skill the new last skill cast
  2529.      */
  2530.     public void setLastSkillCast(final L2Skill skill)
  2531.     {
  2532.         _lastSkillCast = skill;
  2533.     }
  2534.    
  2535.     /**
  2536.      * Gets the last potion cast.
  2537.      * @return the last potion cast
  2538.      */
  2539.     public final L2Skill getLastPotionCast()
  2540.     {
  2541.         return _lastPotionCast;
  2542.     }
  2543.    
  2544.     /**
  2545.      * Sets the last potion cast.
  2546.      * @param skill the new last potion cast
  2547.      */
  2548.     public void setLastPotionCast(final L2Skill skill)
  2549.     {
  2550.         _lastPotionCast = skill;
  2551.     }
  2552.    
  2553.     /**
  2554.      * Checks if is afraid.
  2555.      * @return true, if is afraid
  2556.      */
  2557.     public final boolean isAfraid()
  2558.     {
  2559.         return _isAfraid;
  2560.     }
  2561.    
  2562.     /**
  2563.      * Sets the checks if is afraid.
  2564.      * @param value the new checks if is afraid
  2565.      */
  2566.     public final void setIsAfraid(final boolean value)
  2567.     {
  2568.         _isAfraid = value;
  2569.     }
  2570.    
  2571.     /**
  2572.      * Return True if the L2Character is dead or use fake death.
  2573.      * @return true, if is alike dead
  2574.      */
  2575.     public final boolean isAlikeDead()
  2576.     {
  2577.         return isFakeDeath() || !(getCurrentHp() > 0.01);
  2578.     }
  2579.    
  2580.     /**
  2581.      * Return True if the L2Character can't use its skills (ex : stun, sleep...).
  2582.      * @return true, if is all skills disabled
  2583.      */
  2584.     public final boolean isAllSkillsDisabled()
  2585.     {
  2586.         return _allSkillsDisabled || isImmobileUntilAttacked() || isStunned() || isSleeping() || isParalyzed();
  2587.     }
  2588.    
  2589.     /**
  2590.      * Return True if the L2Character can't attack (stun, sleep, attackEndTime, fakeDeath, paralyse).
  2591.      * @return true, if is attacking disabled
  2592.      */
  2593.     public boolean isAttackingDisabled()
  2594.     {
  2595.         return isImmobileUntilAttacked() || isStunned() || isSleeping() || isFallsdown() || _attackEndTime > GameTimeController.getGameTicks() || isFakeDeath() || isParalyzed() || isAttackDisabled();
  2596.     }
  2597.    
  2598.     /**
  2599.      * Gets the calculators.
  2600.      * @return the calculators
  2601.      */
  2602.     public final Calculator[] getCalculators()
  2603.     {
  2604.         return _calculators;
  2605.     }
  2606.    
  2607.     /**
  2608.      * Checks if is confused.
  2609.      * @return true, if is confused
  2610.      */
  2611.     public final boolean isConfused()
  2612.     {
  2613.         return _isConfused;
  2614.     }
  2615.    
  2616.     /**
  2617.      * Sets the checks if is confused.
  2618.      * @param value the new checks if is confused
  2619.      */
  2620.     public final void setIsConfused(final boolean value)
  2621.     {
  2622.         _isConfused = value;
  2623.     }
  2624.    
  2625.     /**
  2626.      * Return True if the L2Character is dead.
  2627.      * @return true, if is dead
  2628.      */
  2629.     public final boolean isDead()
  2630.     {
  2631.         return !isFakeDeath() && (getCurrentHp() < 0.5);
  2632.     }
  2633.    
  2634.     /**
  2635.      * Checks if is fake death.
  2636.      * @return true, if is fake death
  2637.      */
  2638.     public final boolean isFakeDeath()
  2639.     {
  2640.         return _isFakeDeath;
  2641.     }
  2642.    
  2643.     /**
  2644.      * Sets the checks if is fake death.
  2645.      * @param value the new checks if is fake death
  2646.      */
  2647.     public final void setIsFakeDeath(final boolean value)
  2648.     {
  2649.         _isFakeDeath = value;
  2650.     }
  2651.    
  2652.     /**
  2653.      * Return True if the L2Character is flying.
  2654.      * @return true, if is flying
  2655.      */
  2656.     public final boolean isFlying()
  2657.     {
  2658.         return _isFlying;
  2659.     }
  2660.    
  2661.     /**
  2662.      * Set the L2Character flying mode to True.
  2663.      * @param mode the new checks if is flying
  2664.      */
  2665.     public final void setIsFlying(final boolean mode)
  2666.     {
  2667.         _isFlying = mode;
  2668.     }
  2669.    
  2670.     /**
  2671.      * Checks if is fallsdown.
  2672.      * @return true, if is fallsdown
  2673.      */
  2674.     public final boolean isFallsdown()
  2675.     {
  2676.         return _isFallsdown;
  2677.     }
  2678.    
  2679.     /**
  2680.      * Sets the checks if is fallsdown.
  2681.      * @param value the new checks if is fallsdown
  2682.      */
  2683.     public final void setIsFallsdown(final boolean value)
  2684.     {
  2685.         _isFallsdown = value;
  2686.     }
  2687.    
  2688.     /**
  2689.      * Checks if is imobilised.
  2690.      * @return true, if is imobilised
  2691.      */
  2692.     public boolean isImobilised()
  2693.     {
  2694.         return _isImmobilized > 0;
  2695.     }
  2696.    
  2697.     /**
  2698.      * Sets the checks if is imobilised.
  2699.      * @param value the new checks if is imobilised
  2700.      */
  2701.     public void setIsImobilised(final boolean value)
  2702.     {
  2703.         // Stop this if he is moving
  2704.         this.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  2705.        
  2706.         if (value)
  2707.         {
  2708.             _isImmobilized++;
  2709.         }
  2710.         else
  2711.         {
  2712.             _isImmobilized--;
  2713.         }
  2714.     }
  2715.    
  2716.     /**
  2717.      * Checks if is block buff.
  2718.      * @return the _isBlockBuff
  2719.      */
  2720.     public boolean isBlockBuff()
  2721.     {
  2722.         return _isBlockBuff;
  2723.     }
  2724.    
  2725.     /**
  2726.      * Sets the block buff.
  2727.      * @param blockBuff the _isBlockBuff to set
  2728.      */
  2729.     public void setBlockBuff(final boolean blockBuff)
  2730.     {
  2731.         _isBlockBuff = blockBuff;
  2732.     }
  2733.    
  2734.     /**
  2735.      * Checks if is block debuff.
  2736.      * @return the _isBlockDebuff
  2737.      */
  2738.     public boolean isBlockDebuff()
  2739.     {
  2740.         return _isBlockDebuff;
  2741.     }
  2742.    
  2743.     /**
  2744.      * Sets the block debuff.
  2745.      * @param blockDebuff the _isBlockDebuff to set
  2746.      */
  2747.     public void setBlockDebuff(final boolean blockDebuff)
  2748.     {
  2749.         _isBlockDebuff = blockDebuff;
  2750.     }
  2751.    
  2752.     /**
  2753.      * Checks if is killed already.
  2754.      * @return true, if is killed already
  2755.      */
  2756.     public final boolean isKilledAlready()
  2757.     {
  2758.         return _isKilledAlready;
  2759.     }
  2760.    
  2761.     /**
  2762.      * Sets the checks if is killed already.
  2763.      * @param value the new checks if is killed already
  2764.      */
  2765.     public final void setIsKilledAlready(final boolean value)
  2766.     {
  2767.         _isKilledAlready = value;
  2768.     }
  2769.    
  2770.     /**
  2771.      * Checks if is muted.
  2772.      * @return true, if is muted
  2773.      */
  2774.     public final boolean isMuted()
  2775.     {
  2776.         return _isMuted;
  2777.     }
  2778.    
  2779.     /**
  2780.      * Sets the checks if is muted.
  2781.      * @param value the new checks if is muted
  2782.      */
  2783.     public final void setIsMuted(final boolean value)
  2784.     {
  2785.         _isMuted = value;
  2786.     }
  2787.    
  2788.     /**
  2789.      * Checks if is psychical muted.
  2790.      * @return true, if is psychical muted
  2791.      */
  2792.     public final boolean isPsychicalMuted()
  2793.     {
  2794.         return _isPsychicalMuted;
  2795.     }
  2796.    
  2797.     /**
  2798.      * Sets the checks if is psychical muted.
  2799.      * @param value the new checks if is psychical muted
  2800.      */
  2801.     public final void setIsPsychicalMuted(final boolean value)
  2802.     {
  2803.         _isPsychicalMuted = value;
  2804.     }
  2805.    
  2806.     /**
  2807.      * Return True if the L2Character can't move (stun, root, sleep, overload, paralyzed).
  2808.      * @return true, if is movement disabled
  2809.      */
  2810.     public boolean isMovementDisabled()
  2811.     {
  2812.         return isImmobileUntilAttacked() || isStunned() || isRooted() || isSleeping() || isOverloaded() || isParalyzed() || isImobilised() || isFakeDeath() || isFallsdown();
  2813.     }
  2814.    
  2815.     /**
  2816.      * Return True if the L2Character can be controlled by the player (confused, afraid).
  2817.      * @return true, if is out of control
  2818.      */
  2819.     public final boolean isOutOfControl()
  2820.     {
  2821.         return isConfused() || isAfraid() || isBlocked();
  2822.     }
  2823.    
  2824.     /**
  2825.      * Checks if is overloaded.
  2826.      * @return true, if is overloaded
  2827.      */
  2828.     public final boolean isOverloaded()
  2829.     {
  2830.         return _isOverloaded;
  2831.     }
  2832.    
  2833.     /**
  2834.      * Set the overloaded status of the L2Character is overloaded (if True, the L2PcInstance can't take more item).
  2835.      * @param value the new checks if is overloaded
  2836.      */
  2837.     public final void setIsOverloaded(final boolean value)
  2838.     {
  2839.         _isOverloaded = value;
  2840.     }
  2841.    
  2842.     /**
  2843.      * Checks if is paralyzed.
  2844.      * @return true, if is paralyzed
  2845.      */
  2846.     public final boolean isParalyzed()
  2847.     {
  2848.         return _isParalyzed;
  2849.     }
  2850.    
  2851.     /**
  2852.      * Sets the checks if is paralyzed.
  2853.      * @param value the new checks if is paralyzed
  2854.      */
  2855.     public final void setIsParalyzed(final boolean value)
  2856.     {
  2857.         if (_petrified)
  2858.             return;
  2859.         _isParalyzed = value;
  2860.     }
  2861.    
  2862.     /**
  2863.      * Checks if is pending revive.
  2864.      * @return true, if is pending revive
  2865.      */
  2866.     public final boolean isPendingRevive()
  2867.     {
  2868.         return isDead() && _isPendingRevive;
  2869.     }
  2870.    
  2871.     /**
  2872.      * Sets the checks if is pending revive.
  2873.      * @param value the new checks if is pending revive
  2874.      */
  2875.     public final void setIsPendingRevive(final boolean value)
  2876.     {
  2877.         _isPendingRevive = value;
  2878.     }
  2879.    
  2880.     /**
  2881.      * Return the L2Summon of the L2Character.<BR>
  2882.      * <BR>
  2883.      * <B><U> Overriden in </U> :</B><BR>
  2884.      * <BR>
  2885.      * <li>L2PcInstance</li><BR>
  2886.      * <BR>
  2887.      * @return the pet
  2888.      */
  2889.     public L2Summon getPet()
  2890.     {
  2891.         return null;
  2892.     }
  2893.    
  2894.     /**
  2895.      * Return True if the L2Character is ridding.
  2896.      * @return true, if is riding
  2897.      */
  2898.     public final boolean isRiding()
  2899.     {
  2900.         return _isRiding;
  2901.     }
  2902.    
  2903.     /**
  2904.      * Set the L2Character riding mode to True.
  2905.      * @param mode the new checks if is riding
  2906.      */
  2907.     public final void setIsRiding(final boolean mode)
  2908.     {
  2909.         _isRiding = mode;
  2910.     }
  2911.    
  2912.     /**
  2913.      * Checks if is rooted.
  2914.      * @return true, if is rooted
  2915.      */
  2916.     public final boolean isRooted()
  2917.     {
  2918.         return _isRooted;
  2919.     }
  2920.    
  2921.     /**
  2922.      * Sets the checks if is rooted.
  2923.      * @param value the new checks if is rooted
  2924.      */
  2925.     public final void setIsRooted(final boolean value)
  2926.     {
  2927.         _isRooted = value;
  2928.     }
  2929.    
  2930.     /**
  2931.      * Return True if the L2Character is running.
  2932.      * @return true, if is running
  2933.      */
  2934.     public final boolean isRunning()
  2935.     {
  2936.         return _isRunning;
  2937.     }
  2938.    
  2939.     /**
  2940.      * Sets the checks if is running.
  2941.      * @param value the new checks if is running
  2942.      */
  2943.     public final void setIsRunning(final boolean value)
  2944.     {
  2945.         _isRunning = value;
  2946.         broadcastPacket(new ChangeMoveType(this));
  2947.     }
  2948.    
  2949.     /**
  2950.      * Set the L2Character movement type to run and send Server->Client packet ChangeMoveType to all others L2PcInstance.
  2951.      */
  2952.     public final void setRunning()
  2953.     {
  2954.         if (!isRunning())
  2955.         {
  2956.             setIsRunning(true);
  2957.         }
  2958.     }
  2959.    
  2960.     /**
  2961.      * Checks if is immobile until attacked.
  2962.      * @return true, if is immobile until attacked
  2963.      */
  2964.     public final boolean isImmobileUntilAttacked()
  2965.     {
  2966.         return _isImmobileUntilAttacked;
  2967.     }
  2968.    
  2969.     /**
  2970.      * Sets the checks if is immobile until attacked.
  2971.      * @param value the new checks if is immobile until attacked
  2972.      */
  2973.     public final void setIsImmobileUntilAttacked(final boolean value)
  2974.     {
  2975.         _isImmobileUntilAttacked = value;
  2976.     }
  2977.    
  2978.     /**
  2979.      * Checks if is sleeping.
  2980.      * @return true, if is sleeping
  2981.      */
  2982.     public final boolean isSleeping()
  2983.     {
  2984.         return _isSleeping;
  2985.     }
  2986.    
  2987.     /**
  2988.      * Sets the checks if is sleeping.
  2989.      * @param value the new checks if is sleeping
  2990.      */
  2991.     public final void setIsSleeping(final boolean value)
  2992.     {
  2993.         _isSleeping = value;
  2994.     }
  2995.    
  2996.     /**
  2997.      * Checks if is stunned.
  2998.      * @return true, if is stunned
  2999.      */
  3000.     public final boolean isStunned()
  3001.     {
  3002.         return _isStunned;
  3003.     }
  3004.    
  3005.     /**
  3006.      * Sets the checks if is stunned.
  3007.      * @param value the new checks if is stunned
  3008.      */
  3009.     public final void setIsStunned(final boolean value)
  3010.     {
  3011.         _isStunned = value;
  3012.     }
  3013.    
  3014.     /**
  3015.      * Checks if is betrayed.
  3016.      * @return true, if is betrayed
  3017.      */
  3018.     public final boolean isBetrayed()
  3019.     {
  3020.         return _isBetrayed;
  3021.     }
  3022.    
  3023.     /**
  3024.      * Sets the checks if is betrayed.
  3025.      * @param value the new checks if is betrayed
  3026.      */
  3027.     public final void setIsBetrayed(final boolean value)
  3028.     {
  3029.         _isBetrayed = value;
  3030.     }
  3031.    
  3032.     /**
  3033.      * Checks if is teleporting.
  3034.      * @return true, if is teleporting
  3035.      */
  3036.     public final boolean isTeleporting()
  3037.     {
  3038.         return _isTeleporting;
  3039.     }
  3040.    
  3041.     /**
  3042.      * Sets the checks if is teleporting.
  3043.      * @param value the new checks if is teleporting
  3044.      */
  3045.     public void setIsTeleporting(final boolean value)
  3046.     {
  3047.         _isTeleporting = value;
  3048.     }
  3049.    
  3050.     /**
  3051.      * Sets the checks if is invul.
  3052.      * @param b the new checks if is invul
  3053.      */
  3054.     public void setIsInvul(final boolean b)
  3055.     {
  3056.         if (_petrified)
  3057.             return;
  3058.        
  3059.         _isInvul = b;
  3060.     }
  3061.    
  3062.     /**
  3063.      * Checks if is invul.
  3064.      * @return true, if is invul
  3065.      */
  3066.     public boolean isInvul()
  3067.     {
  3068.         return _isInvul || _isTeleporting;
  3069.     }
  3070.    
  3071.     /**
  3072.      * Checks if is undead.
  3073.      * @return true, if is undead
  3074.      */
  3075.     public boolean isUndead()
  3076.     {
  3077.         return _template.isUndead;
  3078.     }
  3079.    
  3080.     /*
  3081.      * (non-Javadoc)
  3082.      * @see com.l2jlegacy.gameserver.model.L2Object#getKnownList()
  3083.      */
  3084.     @Override
  3085.     public CharKnownList getKnownList()
  3086.     {
  3087.         if (super.getKnownList() == null || !(super.getKnownList() instanceof CharKnownList))
  3088.         {
  3089.             setKnownList(new CharKnownList(this));
  3090.         }
  3091.        
  3092.         return (CharKnownList) super.getKnownList();
  3093.     }
  3094.    
  3095.     /**
  3096.      * Gets the stat.
  3097.      * @return the stat
  3098.      */
  3099.     public CharStat getStat()
  3100.     {
  3101.         if (_stat == null)
  3102.         {
  3103.             _stat = new CharStat(this);
  3104.         }
  3105.        
  3106.         return _stat;
  3107.     }
  3108.    
  3109.     /**
  3110.      * Sets the stat.
  3111.      * @param value the new stat
  3112.      */
  3113.     public final void setStat(final CharStat value)
  3114.     {
  3115.         _stat = value;
  3116.     }
  3117.    
  3118.     /**
  3119.      * Gets the status.
  3120.      * @return the status
  3121.      */
  3122.     public CharStatus getStatus()
  3123.     {
  3124.         if (_status == null)
  3125.         {
  3126.             _status = new CharStatus(this);
  3127.         }
  3128.        
  3129.         return _status;
  3130.     }
  3131.    
  3132.     /**
  3133.      * Sets the status.
  3134.      * @param value the new status
  3135.      */
  3136.     public final void setStatus(final CharStatus value)
  3137.     {
  3138.         _status = value;
  3139.     }
  3140.    
  3141.     /**
  3142.      * Gets the template.
  3143.      * @return the template
  3144.      */
  3145.     public L2CharTemplate getTemplate()
  3146.     {
  3147.         return _template;
  3148.     }
  3149.    
  3150.     /**
  3151.      * Set the template of the L2Character.<BR>
  3152.      * <BR>
  3153.      * <B><U> Concept</U> :</B><BR>
  3154.      * <BR>
  3155.      * Each L2Character owns generic and static properties (ex : all Keltir have the same number of HP...). All of those properties are stored in a different template for each type of L2Character. Each template is loaded once in the server cache memory (reduce memory use). When a new instance of
  3156.      * L2Character is spawned, server just create a link between the instance and the template This link is stored in <B>_template</B><BR>
  3157.      * <BR>
  3158.      * <B><U> Assert </U> :</B><BR>
  3159.      * <BR>
  3160.      * <li>this instanceof L2Character</li><BR>
  3161.      * <BR
  3162.      * @param template the new template
  3163.      */
  3164.     protected synchronized final void setTemplate(final L2CharTemplate template)
  3165.     {
  3166.         _template = template;
  3167.     }
  3168.    
  3169.     /**
  3170.      * Return the Title of the L2Character.
  3171.      * @return the title
  3172.      */
  3173.     public final String getTitle()
  3174.     {
  3175.         if (_title == null)
  3176.             return "";
  3177.        
  3178.         return _title;
  3179.     }
  3180.    
  3181.     /**
  3182.      * Set the Title of the L2Character.
  3183.      * @param value the new title
  3184.      */
  3185.     public final void setTitle(String value)
  3186.     {
  3187.         if (value == null)
  3188.             value = "";
  3189.        
  3190.         if (this instanceof L2PcInstance && value.length() > 16)
  3191.         {
  3192.             value = value.substring(0, 15);
  3193.         }
  3194.        
  3195.         _title = value; // public final void setTitle(String value) { _title = value; }
  3196.     }
  3197.    
  3198.     /**
  3199.      * Set the L2Character movement type to walk and send Server->Client packet ChangeMoveType to all others L2PcInstance.
  3200.      */
  3201.     public final void setWalking()
  3202.     {
  3203.         if (isRunning())
  3204.         {
  3205.             setIsRunning(false);
  3206.         }
  3207.     }
  3208.    
  3209.     /**
  3210.      * Task lauching the function enableSkill().
  3211.      */
  3212.     class EnableSkill implements Runnable
  3213.     {
  3214.        
  3215.         /** The _skill id. */
  3216.         L2Skill _skillId;
  3217.        
  3218.         /**
  3219.          * Instantiates a new enable skill.
  3220.          * @param skill the skill
  3221.          */
  3222.         public EnableSkill(final L2Skill skill)
  3223.         {
  3224.             _skillId = skill;
  3225.         }
  3226.        
  3227.         /*
  3228.          * (non-Javadoc)
  3229.          * @see java.lang.Runnable#run()
  3230.          */
  3231.         @Override
  3232.         public void run()
  3233.         {
  3234.             try
  3235.             {
  3236.                 enableSkill(_skillId);
  3237.             }
  3238.             catch (final Throwable e)
  3239.             {
  3240.                 LOGGER.error("", e);
  3241.             }
  3242.         }
  3243.     }
  3244.    
  3245.     /**
  3246.      * Task lauching the function onHitTimer().<BR>
  3247.      * <BR>
  3248.      * <B><U> Actions</U> :</B><BR>
  3249.      * <BR>
  3250.      * <li>If the attacker/target is dead or use fake death, notify the AI with EVT_CANCEL and send a Server->Client packet ActionFailed (if attacker is a L2PcInstance)</li> <li>If attack isn't aborted, send a message system (critical hit, missed...) to attacker/target if they are L2PcInstance</li>
  3251.      * <li>If attack isn't aborted and hit isn't missed, reduce HP of the target and calculate reflection damage to reduce HP of attacker if necessary</li> <li>if attack isn't aborted and hit isn't missed, manage attack or cast break of the target (calculating rate, sending message...)</li><BR>
  3252.      * <BR>
  3253.      */
  3254.     class HitTask implements Runnable
  3255.     {
  3256.        
  3257.         /** The _hit target. */
  3258.         L2Character _hitTarget;
  3259.        
  3260.         /** The _damage. */
  3261.         int _damage;
  3262.        
  3263.         /** The _crit. */
  3264.         boolean _crit;
  3265.        
  3266.         /** The _miss. */
  3267.         boolean _miss;
  3268.        
  3269.         /** The _shld. */
  3270.         boolean _shld;
  3271.        
  3272.         /** The _soulshot. */
  3273.         boolean _soulshot;
  3274.        
  3275.         /**
  3276.          * Instantiates a new hit task.
  3277.          * @param target the target
  3278.          * @param damage the damage
  3279.          * @param crit the crit
  3280.          * @param miss the miss
  3281.          * @param soulshot the soulshot
  3282.          * @param shld the shld
  3283.          */
  3284.         public HitTask(final L2Character target, final int damage, final boolean crit, final boolean miss, final boolean soulshot, final boolean shld)
  3285.         {
  3286.             _hitTarget = target;
  3287.             _damage = damage;
  3288.             _crit = crit;
  3289.             _shld = shld;
  3290.             _miss = miss;
  3291.             _soulshot = soulshot;
  3292.         }
  3293.        
  3294.         /*
  3295.          * (non-Javadoc)
  3296.          * @see java.lang.Runnable#run()
  3297.          */
  3298.         @Override
  3299.         public void run()
  3300.         {
  3301.             try
  3302.             {
  3303.                 onHitTimer(_hitTarget, _damage, _crit, _miss, _soulshot, _shld);
  3304.             }
  3305.             catch (final Throwable e)
  3306.             {
  3307.                 LOGGER.error("fixme:hit task unhandled exception", e);
  3308.             }
  3309.         }
  3310.     }
  3311.    
  3312.     /**
  3313.      * Task lauching the magic skill phases.
  3314.      */
  3315.     class MagicUseTask implements Runnable
  3316.     {
  3317.        
  3318.         /** The _targets. */
  3319.         L2Object[] _targets;
  3320.        
  3321.         /** The _skill. */
  3322.         L2Skill _skill;
  3323.        
  3324.         /** The _cool time. */
  3325.         int _coolTime;
  3326.        
  3327.         /** The _phase. */
  3328.         int _phase;
  3329.        
  3330.         /**
  3331.          * Instantiates a new magic use task.
  3332.          * @param targets the targets
  3333.          * @param skill the skill
  3334.          * @param coolTime the cool time
  3335.          * @param phase the phase
  3336.          */
  3337.         public MagicUseTask(final L2Object[] targets, final L2Skill skill, final int coolTime, final int phase)
  3338.         {
  3339.             _targets = targets;
  3340.             _skill = skill;
  3341.             _coolTime = coolTime;
  3342.             _phase = phase;
  3343.         }
  3344.        
  3345.         /*
  3346.          * (non-Javadoc)
  3347.          * @see java.lang.Runnable#run()
  3348.          */
  3349.         @Override
  3350.         public void run()
  3351.         {
  3352.             try
  3353.             {
  3354.                 switch (_phase)
  3355.                 {
  3356.                     case 1:
  3357.                         onMagicLaunchedTimer(_targets, _skill, _coolTime, false);
  3358.                         break;
  3359.                     case 2:
  3360.                         onMagicHitTimer(_targets, _skill, _coolTime, false);
  3361.                         break;
  3362.                     case 3:
  3363.                         onMagicFinalizer(_targets, _skill);
  3364.                         break;
  3365.                     default:
  3366.                         break;
  3367.                 }
  3368.             }
  3369.             catch (final Throwable e)
  3370.             {
  3371.                 LOGGER.error("", e);
  3372.                 e.printStackTrace();
  3373.                 enableAllSkills();
  3374.             }
  3375.         }
  3376.     }
  3377.    
  3378.     /**
  3379.      * Task lauching the function useMagic().
  3380.      */
  3381.     class QueuedMagicUseTask implements Runnable
  3382.     {
  3383.        
  3384.         /** The _curr player. */
  3385.         L2PcInstance _currPlayer;
  3386.        
  3387.         /** The _queued skill. */
  3388.         L2Skill _queuedSkill;
  3389.        
  3390.         /** The _is ctrl pressed. */
  3391.         boolean _isCtrlPressed;
  3392.        
  3393.         /** The _is shift pressed. */
  3394.         boolean _isShiftPressed;
  3395.        
  3396.         /**
  3397.          * Instantiates a new queued magic use task.
  3398.          * @param currPlayer the curr player
  3399.          * @param queuedSkill the queued skill
  3400.          * @param isCtrlPressed the is ctrl pressed
  3401.          * @param isShiftPressed the is shift pressed
  3402.          */
  3403.         public QueuedMagicUseTask(final L2PcInstance currPlayer, final L2Skill queuedSkill, final boolean isCtrlPressed, final boolean isShiftPressed)
  3404.         {
  3405.             _currPlayer = currPlayer;
  3406.             _queuedSkill = queuedSkill;
  3407.             _isCtrlPressed = isCtrlPressed;
  3408.             _isShiftPressed = isShiftPressed;
  3409.         }
  3410.        
  3411.         /*
  3412.          * (non-Javadoc)
  3413.          * @see java.lang.Runnable#run()
  3414.          */
  3415.         @Override
  3416.         public void run()
  3417.         {
  3418.             try
  3419.             {
  3420.                 _currPlayer.useMagic(_queuedSkill, _isCtrlPressed, _isShiftPressed);
  3421.             }
  3422.             catch (final Throwable e)
  3423.             {
  3424.                 LOGGER.error("", e);
  3425.             }
  3426.         }
  3427.     }
  3428.    
  3429.     /**
  3430.      * Task of AI notification.
  3431.      */
  3432.     public class NotifyAITask implements Runnable
  3433.     {
  3434.        
  3435.         /** The _evt. */
  3436.         private final CtrlEvent _evt;
  3437.        
  3438.         /**
  3439.          * Instantiates a new notify ai task.
  3440.          * @param evt the evt
  3441.          */
  3442.         NotifyAITask(final CtrlEvent evt)
  3443.         {
  3444.             _evt = evt;
  3445.         }
  3446.        
  3447.         /*
  3448.          * (non-Javadoc)
  3449.          * @see java.lang.Runnable#run()
  3450.          */
  3451.         @Override
  3452.         public void run()
  3453.         {
  3454.             try
  3455.             {
  3456.                 getAI().notifyEvent(_evt, null);
  3457.             }
  3458.             catch (final Throwable t)
  3459.             {
  3460.                 LOGGER.warn("", t);
  3461.             }
  3462.         }
  3463.     }
  3464.    
  3465.     /**
  3466.      * Task lauching the function stopPvPFlag().
  3467.      */
  3468.     class PvPFlag implements Runnable
  3469.     {
  3470.        
  3471.         /**
  3472.          * Instantiates a new pvp flag.
  3473.          */
  3474.         public PvPFlag()
  3475.         {
  3476.             // null
  3477.         }
  3478.        
  3479.         /*
  3480.          * (non-Javadoc)
  3481.          * @see java.lang.Runnable#run()
  3482.          */
  3483.         @Override
  3484.         public void run()
  3485.         {
  3486.             try
  3487.             {
  3488.                 // LOGGER.fine("Checking pvp time: " + getlastPvpAttack());
  3489.                 // "lastattack: " _lastAttackTime "currenttime: "
  3490.                 // System.currentTimeMillis());
  3491.                 if (System.currentTimeMillis() > getPvpFlagLasts())
  3492.                 {
  3493.                     // LOGGER.fine("Stopping PvP");
  3494.                     stopPvPFlag();
  3495.                 }
  3496.                 else if (System.currentTimeMillis() > getPvpFlagLasts() - 5000)
  3497.                 {
  3498.                     updatePvPFlag(2);
  3499.                 }
  3500.                 else
  3501.                 {
  3502.                     updatePvPFlag(1);
  3503.                     // Start a new PvP timer check
  3504.                     // checkPvPFlag();
  3505.                 }
  3506.             }
  3507.             catch (final Exception e)
  3508.             {
  3509.                 LOGGER.warn("error in pvp flag task:", e);
  3510.             }
  3511.         }
  3512.     }
  3513.    
  3514.     // =========================================================
  3515.    
  3516.     // =========================================================
  3517.     // Abnormal Effect - NEED TO REMOVE ONCE L2CHARABNORMALEFFECT IS COMPLETE
  3518.     // Data Field
  3519.     /** Map 32 bits (0x0000) containing all abnormal effect in progress. */
  3520.     private int _AbnormalEffects;
  3521.    
  3522.     /**
  3523.      * FastTable containing all active skills effects in progress of a L2Character.
  3524.      */
  3525.     private final FastTable<L2Effect> _effects = new FastTable<>();
  3526.    
  3527.     /** The table containing the List of all stacked effect in progress for each Stack group Identifier. */
  3528.     protected Map<String, List<L2Effect>> _stackedEffects = new FastMap<>();
  3529.    
  3530.     /** The Constant ABNORMAL_EFFECT_BLEEDING. */
  3531.     public static final int ABNORMAL_EFFECT_BLEEDING = 0x000001;
  3532.    
  3533.     /** The Constant ABNORMAL_EFFECT_POISON. */
  3534.     public static final int ABNORMAL_EFFECT_POISON = 0x000002;
  3535.    
  3536.     /** The Constant ABNORMAL_EFFECT_REDCIRCLE. */
  3537.     public static final int ABNORMAL_EFFECT_REDCIRCLE = 0x000004;
  3538.    
  3539.     /** The Constant ABNORMAL_EFFECT_ICE. */
  3540.     public static final int ABNORMAL_EFFECT_ICE = 0x000008;
  3541.    
  3542.     /** The Constant ABNORMAL_EFFECT_WIND. */
  3543.     public static final int ABNORMAL_EFFECT_WIND = 0x0000010;
  3544.    
  3545.     /** The Constant ABNORMAL_EFFECT_FEAR. */
  3546.     public static final int ABNORMAL_EFFECT_FEAR = 0x0000020;
  3547.    
  3548.     /** The Constant ABNORMAL_EFFECT_STUN. */
  3549.     public static final int ABNORMAL_EFFECT_STUN = 0x000040;
  3550.    
  3551.     /** The Constant ABNORMAL_EFFECT_SLEEP. */
  3552.     public static final int ABNORMAL_EFFECT_SLEEP = 0x000080;
  3553.    
  3554.     /** The Constant ABNORMAL_EFFECT_MUTED. */
  3555.     public static final int ABNORMAL_EFFECT_MUTED = 0x000100;
  3556.    
  3557.     /** The Constant ABNORMAL_EFFECT_ROOT. */
  3558.     public static final int ABNORMAL_EFFECT_ROOT = 0x000200;
  3559.    
  3560.     /** The Constant ABNORMAL_EFFECT_HOLD_1. */
  3561.     public static final int ABNORMAL_EFFECT_HOLD_1 = 0x000400;
  3562.    
  3563.     /** The Constant ABNORMAL_EFFECT_HOLD_2. */
  3564.     public static final int ABNORMAL_EFFECT_HOLD_2 = 0x000800;
  3565.    
  3566.     /** The Constant ABNORMAL_EFFECT_UNKNOWN_13. */
  3567.     public static final int ABNORMAL_EFFECT_UNKNOWN_13 = 0x001000;
  3568.    
  3569.     /** The Constant ABNORMAL_EFFECT_BIG_HEAD. */
  3570.     public static final int ABNORMAL_EFFECT_BIG_HEAD = 0x002000;
  3571.    
  3572.     /** The Constant ABNORMAL_EFFECT_FLAME. */
  3573.     public static final int ABNORMAL_EFFECT_FLAME = 0x004000;
  3574.    
  3575.     /** The Constant ABNORMAL_EFFECT_UNKNOWN_16. */
  3576.     public static final int ABNORMAL_EFFECT_UNKNOWN_16 = 0x008000;
  3577.    
  3578.     /** The Constant ABNORMAL_EFFECT_GROW. */
  3579.     public static final int ABNORMAL_EFFECT_GROW = 0x010000;
  3580.    
  3581.     /** The Constant ABNORMAL_EFFECT_FLOATING_ROOT. */
  3582.     public static final int ABNORMAL_EFFECT_FLOATING_ROOT = 0x020000;
  3583.    
  3584.     /** The Constant ABNORMAL_EFFECT_DANCE_STUNNED. */
  3585.     public static final int ABNORMAL_EFFECT_DANCE_STUNNED = 0x040000;
  3586.  
  3587.     /** The Constant ABNORMAL_EFFECT_PARALYZE. */
  3588.     public static final int ABNORMAL_EFFECT_PARALYZE = 0x0400;
  3589.  
  3590.     /** The Constant ABNORMAL_EFFECT_FIREROOT_STUN. */
  3591.     public static final int ABNORMAL_EFFECT_FIREROOT_STUN = 0x080000;
  3592.    
  3593.     /** The Constant ABNORMAL_EFFECT_STEALTH. */
  3594.     public static final int ABNORMAL_EFFECT_STEALTH = 0x100000;
  3595.    
  3596.     /** The Constant ABNORMAL_EFFECT_IMPRISIONING_1. */
  3597.     public static final int ABNORMAL_EFFECT_IMPRISIONING_1 = 0x200000;
  3598.    
  3599.     /** The Constant ABNORMAL_EFFECT_IMPRISIONING_2. */
  3600.     public static final int ABNORMAL_EFFECT_IMPRISIONING_2 = 0x400000;
  3601.    
  3602.     /** The Constant ABNORMAL_EFFECT_MAGIC_CIRCLE. */
  3603.     public static final int ABNORMAL_EFFECT_MAGIC_CIRCLE = 0x800000;
  3604.    
  3605.     /** The Constant ABNORMAL_EFFECT_CONFUSED. */
  3606.     public static final int ABNORMAL_EFFECT_CONFUSED = 0x0020;
  3607.    
  3608.     /** The Constant ABNORMAL_EFFECT_AFRAID. */
  3609.     public static final int ABNORMAL_EFFECT_AFRAID = 0x0010;
  3610.    
  3611.     // Method - Public
  3612.     /**
  3613.      * Launch and add L2Effect (including Stack Group management) to L2Character and update client magic icone.<BR>
  3614.      * <BR>
  3615.      * <B><U> Concept</U> :</B><BR>
  3616.      * <BR>
  3617.      * All active skills effects in progress on the L2Character are identified in ConcurrentHashMap(Integer,L2Effect) <B>_effects</B>. The Integer key of _effects is the L2Skill Identifier that has created the L2Effect.<BR>
  3618.      * <BR>
  3619.      * Several same effect can't be used on a L2Character at the same time. Indeed, effects are not stackable and the last cast will replace the previous in progress. More, some effects belong to the same Stack Group (ex WindWald and Haste Potion). If 2 effects of a same group are used at the same
  3620.      * time on a L2Character, only the more efficient (identified by its priority order) will be preserve.<BR>
  3621.      * <BR>
  3622.      * <B><U> Actions</U> :</B><BR>
  3623.      * <BR>
  3624.      * <li>Add the L2Effect to the L2Character _effects</li> <li>If this effect doesn't belong to a Stack Group, add its Funcs to the Calculator set of the L2Character (remove the old one if necessary)</li> <li>If this effect has higher priority in its Stack Group, add its Funcs to the Calculator
  3625.      * set of the L2Character (remove previous stacked effect Funcs if necessary)</li> <li>If this effect has NOT higher priority in its Stack Group, set the effect to Not In Use</li> <li>Update active skills in progress icones on player client</li><BR>
  3626.      * @param newEffect the new effect
  3627.      */
  3628.     public synchronized void addEffect(final L2Effect newEffect)
  3629.     {
  3630.         if (newEffect == null)
  3631.             return;
  3632.        
  3633.         final L2Effect[] effects = getAllEffects();
  3634.        
  3635.         // Make sure there's no same effect previously
  3636.         for (final L2Effect effect : effects)
  3637.         {
  3638.             if (effect == null)
  3639.             {
  3640.                
  3641.                 synchronized (_effects)
  3642.                 {
  3643.                     _effects.remove(effect);
  3644.                 }
  3645.                 continue;
  3646.             }
  3647.            
  3648.             if (effect.getSkill().getId() == newEffect.getSkill().getId() && effect.getEffectType() == newEffect.getEffectType() && effect.getStackType() == newEffect.getStackType())
  3649.             {
  3650.                 if (this instanceof L2PcInstance)
  3651.                 {
  3652.                    
  3653.                     final L2PcInstance player = (L2PcInstance) this;
  3654.                    
  3655.                     if (player.isInDuel())
  3656.                     {
  3657.                         DuelManager.getInstance().getDuel(player.getDuelId()).onBuffStop(player, effect);
  3658.                     }
  3659.                    
  3660.                 }
  3661.                
  3662.                 if ((newEffect.getSkill().getSkillType() == SkillType.BUFF || newEffect.getEffectType() == L2Effect.EffectType.BUFF || newEffect.getEffectType() == L2Effect.EffectType.HEAL_OVER_TIME) && newEffect.getStackOrder() >= effect.getStackOrder())
  3663.                 {
  3664.                     effect.exit(false);
  3665.                 }
  3666.                 else
  3667.                 {
  3668.                     // newEffect.exit(false);
  3669.                     newEffect.stopEffectTask();
  3670.                     return;
  3671.                 }
  3672.             }
  3673.         }
  3674.  
  3675.         final L2Skill tempskill = newEffect.getSkill();
  3676.        
  3677.         // Remove first Buff if number of buffs > BUFFS_MAX_AMOUNT
  3678.         if (getBuffCount() >= getMaxBuffCount() && !doesStack(tempskill) && (tempskill.getSkillType() == L2Skill.SkillType.BUFF || tempskill.getSkillType() == L2Skill.SkillType.REFLECT || tempskill.getSkillType() == L2Skill.SkillType.HEAL_PERCENT || tempskill.getSkillType() == L2Skill.SkillType.MANAHEAL_PERCENT) && !(tempskill.getId() > 4360 && tempskill.getId() < 4367) && !(tempskill.getId() > 4550 && tempskill.getId() < 4555))
  3679.         {
  3680.             if (newEffect.isHerbEffect())
  3681.             {
  3682.                 newEffect.exit(false);
  3683.                 return;
  3684.             }
  3685.             removeFirstBuff(tempskill.getId());
  3686.         }
  3687.  
  3688.         // Remove first DeBuff if number of debuffs > DEBUFFS_MAX_AMOUNT
  3689.         if (getDeBuffCount() >= Config.DEBUFFS_MAX_AMOUNT && !doesStack(tempskill) && tempskill.is_Debuff())
  3690.         {
  3691.             removeFirstDeBuff(tempskill.getId());
  3692.         }
  3693.        
  3694.         synchronized (_effects)
  3695.         {
  3696.             // Add the L2Effect to all effect in progress on the L2Character
  3697.             if (!newEffect.getSkill().isToggle())
  3698.             {
  3699.                 int pos = 0;
  3700.                
  3701.                 for (int i = 0; i < _effects.size(); i++)
  3702.                 {
  3703.                     if (_effects.get(i) == null)
  3704.                     {
  3705.                         _effects.remove(i);
  3706.                         i--;
  3707.                         continue;
  3708.                     }
  3709.                    
  3710.                     if (_effects.get(i) != null)
  3711.                     {
  3712.                         final int skillid = _effects.get(i).getSkill().getId();
  3713.                        
  3714.                         if (!_effects.get(i).getSkill().isToggle() && !(skillid > 4360 && skillid < 4367))
  3715.                         {
  3716.                             pos++;
  3717.                         }
  3718.                     }
  3719.                     else
  3720.                     {
  3721.                         break;
  3722.                     }
  3723.                 }
  3724.                 _effects.add(pos, newEffect);
  3725.             }
  3726.             else
  3727.             {
  3728.                 _effects.addLast(newEffect);
  3729.             }
  3730.            
  3731.         }
  3732.        
  3733.         // Check if a stack group is defined for this effect
  3734.         if (newEffect.getStackType().equals("none"))
  3735.         {
  3736.             // Set this L2Effect to In Use
  3737.             newEffect.setInUse(true);
  3738.            
  3739.             // Add Funcs of this effect to the Calculator set of the L2Character
  3740.             addStatFuncs(newEffect.getStatFuncs());
  3741.            
  3742.             // Update active skills in progress icones on player client
  3743.             updateEffectIcons();
  3744.             return;
  3745.         }
  3746.        
  3747.         // Get the list of all stacked effects corresponding to the stack type of the L2Effect to add
  3748.         List<L2Effect> stackQueue = _stackedEffects.get(newEffect.getStackType());
  3749.        
  3750.         if (stackQueue == null)
  3751.         {
  3752.             stackQueue = new FastList<>();
  3753.         }
  3754.        
  3755.         // L2Effect tempEffect = null;
  3756.        
  3757.         if (stackQueue.size() > 0)
  3758.         {
  3759.             // Get the first stacked effect of the Stack group selected
  3760.             if (_effects.contains(stackQueue.get(0)))
  3761.             {
  3762.                 // Remove all Func objects corresponding to this stacked effect from the Calculator set of the L2Character
  3763.                 removeStatsOwner(stackQueue.get(0));
  3764.                
  3765.                 // Set the L2Effect to Not In Use
  3766.                 stackQueue.get(0).setInUse(false);
  3767.             }
  3768.         }
  3769.        
  3770.         // Add the new effect to the stack group selected at its position
  3771.         stackQueue = effectQueueInsert(newEffect, stackQueue);
  3772.        
  3773.         if (stackQueue == null)
  3774.             return;
  3775.        
  3776.         // Update the Stack Group table _stackedEffects of the L2Character
  3777.         _stackedEffects.put(newEffect.getStackType(), stackQueue);
  3778.        
  3779.         // Get the first stacked effect of the Stack group selected
  3780.         if (_effects.contains(stackQueue.get(0)))
  3781.         {
  3782.             // Set this L2Effect to In Use
  3783.             stackQueue.get(0).setInUse(true);
  3784.            
  3785.             // Add all Func objects corresponding to this stacked effect to the Calculator set of the L2Character
  3786.             addStatFuncs(stackQueue.get(0).getStatFuncs());
  3787.         }
  3788.        
  3789.         // Update active skills in progress (In Use and Not In Use because stacked) icones on client
  3790.         updateEffectIcons();
  3791.     }
  3792.    
  3793.     /**
  3794.      * Insert an effect at the specified position in a Stack Group.<BR>
  3795.      * <BR>
  3796.      * <B><U> Concept</U> :</B><BR>
  3797.      * <BR>
  3798.      * Several same effect can't be used on a L2Character at the same time. Indeed, effects are not stackable and the last cast will replace the previous in progress. More, some effects belong to the same Stack Group (ex WindWald and Haste Potion). If 2 effects of a same group are used at the same
  3799.      * time on a L2Character, only the more efficient (identified by its priority order) will be preserve.<BR>
  3800.      * <BR>
  3801.      * @param newStackedEffect the new stacked effect
  3802.      * @param stackQueue The Stack Group in wich the effect must be added
  3803.      * @return the list
  3804.      */
  3805.     private List<L2Effect> effectQueueInsert(final L2Effect newStackedEffect, final List<L2Effect> stackQueue)
  3806.     {
  3807.         // Create an Iterator to go through the list of stacked effects in progress on the L2Character
  3808.         Iterator<L2Effect> queueIterator = stackQueue.iterator();
  3809.        
  3810.         int i = 0;
  3811.         while (queueIterator.hasNext())
  3812.         {
  3813.             final L2Effect cur = queueIterator.next();
  3814.             if (newStackedEffect.getStackOrder() < cur.getStackOrder())
  3815.             {
  3816.                 i++;
  3817.             }
  3818.             else
  3819.             {
  3820.                 break;
  3821.             }
  3822.         }
  3823.        
  3824.         // Add the new effect to the Stack list in function of its position in the Stack group
  3825.         stackQueue.add(i, newStackedEffect);
  3826.        
  3827.         // skill.exit() could be used, if the users don't wish to see "effect
  3828.         // removed" always when a timer goes off, even if the buff isn't active
  3829.         // any more (has been replaced). but then check e.g. npc hold and raid petrify.
  3830.         if (Config.EFFECT_CANCELING && !newStackedEffect.isHerbEffect() && stackQueue.size() > 1)
  3831.         {
  3832.             synchronized (_effects)
  3833.             {
  3834.                
  3835.                 _effects.remove(stackQueue.get(1));
  3836.                
  3837.             }
  3838.            
  3839.             stackQueue.remove(1);
  3840.         }
  3841.        
  3842.         queueIterator = null;
  3843.        
  3844.         return stackQueue;
  3845.     }
  3846.    
  3847.     /**
  3848.      * Stop and remove L2Effect (including Stack Group management) from L2Character and update client magic icone.<BR>
  3849.      * <BR>
  3850.      * <B><U> Concept</U> :</B><BR>
  3851.      * <BR>
  3852.      * All active skills effects in progress on the L2Character are identified in ConcurrentHashMap(Integer,L2Effect) <B>_effects</B>. The Integer key of _effects is the L2Skill Identifier that has created the L2Effect.<BR>
  3853.      * <BR>
  3854.      * Several same effect can't be used on a L2Character at the same time. Indeed, effects are not stackable and the last cast will replace the previous in progress. More, some effects belong to the same Stack Group (ex WindWald and Haste Potion). If 2 effects of a same group are used at the same
  3855.      * time on a L2Character, only the more efficient (identified by its priority order) will be preserve.<BR>
  3856.      * <BR>
  3857.      * <B><U> Actions</U> :</B><BR>
  3858.      * <BR>
  3859.      * <li>Remove Func added by this effect from the L2Character Calculator (Stop L2Effect)</li> <li>If the L2Effect belongs to a not empty Stack Group, replace theses Funcs by next stacked effect Funcs</li> <li>Remove the L2Effect from _effects of the L2Character</li> <li>Update active skills in
  3860.      * progress icones on player client</li><BR>
  3861.      * @param effect the effect
  3862.      */
  3863.     public final void removeEffect(final L2Effect effect)
  3864.     {
  3865.         if (effect == null/* || _effects == null */)
  3866.             return;
  3867.        
  3868.         if (effect.getStackType() == "none")
  3869.         {
  3870.             // Remove Func added by this effect from the L2Character Calculator
  3871.             removeStatsOwner(effect);
  3872.         }
  3873.         else
  3874.         {
  3875.             if (_stackedEffects == null)
  3876.                 return;
  3877.            
  3878.             // Get the list of all stacked effects corresponding to the stack type of the L2Effect to add
  3879.             final List<L2Effect> stackQueue = _stackedEffects.get(effect.getStackType());
  3880.            
  3881.             if (stackQueue == null || stackQueue.size() < 1)
  3882.                 return;
  3883.            
  3884.             // Get the Identifier of the first stacked effect of the Stack group selected
  3885.             final L2Effect frontEffect = stackQueue.get(0);
  3886.            
  3887.             // Remove the effect from the Stack Group
  3888.             final boolean removed = stackQueue.remove(effect);
  3889.            
  3890.             if (removed)
  3891.             {
  3892.                 // Check if the first stacked effect was the effect to remove
  3893.                 if (frontEffect == effect)
  3894.                 {
  3895.                     // Remove all its Func objects from the L2Character calculator set
  3896.                     removeStatsOwner(effect);
  3897.                    
  3898.                     // Check if there's another effect in the Stack Group
  3899.                     if (stackQueue.size() > 0)
  3900.                     {
  3901.                         // Add its list of Funcs to the Calculator set of the L2Character
  3902.                         if (_effects.contains(stackQueue.get(0)))
  3903.                         {
  3904.                            
  3905.                             // Add its list of Funcs to the Calculator set of the L2Character
  3906.                             addStatFuncs(stackQueue.get(0).getStatFuncs());
  3907.                             // Set the effect to In Use
  3908.                             stackQueue.get(0).setInUse(true);
  3909.                            
  3910.                         }
  3911.                        
  3912.                     }
  3913.                 }
  3914.                 if (stackQueue.isEmpty())
  3915.                 {
  3916.                     _stackedEffects.remove(effect.getStackType());
  3917.                 }
  3918.                 else
  3919.                 {
  3920.                     // Update the Stack Group table _stackedEffects of the L2Character
  3921.                     _stackedEffects.put(effect.getStackType(), stackQueue);
  3922.                 }
  3923.             }
  3924.            
  3925.         }
  3926.        
  3927.         synchronized (_effects)
  3928.         {
  3929.             // Remove the active skill L2effect from _effects of the L2Character
  3930.             _effects.remove(effect);
  3931.            
  3932.         }
  3933.        
  3934.         // Update active skills in progress (In Use and Not In Use because stacked) icones on client
  3935.         updateEffectIcons();
  3936.     }
  3937.    
  3938.     /**
  3939.      * Active abnormal effects flags in the binary mask and send Server->Client UserInfo/CharInfo packet.<BR>
  3940.      * <BR>
  3941.      * @param mask the mask
  3942.      */
  3943.     public final void startAbnormalEffect(final int mask)
  3944.     {
  3945.         _AbnormalEffects |= mask;
  3946.         updateAbnormalEffect();
  3947.     }
  3948.    
  3949.     /**
  3950.      * immobile start.
  3951.      */
  3952.     public final void startImmobileUntilAttacked()
  3953.     {
  3954.         setIsImmobileUntilAttacked(true);
  3955.         abortAttack();
  3956.         abortCast();
  3957.         getAI().notifyEvent(CtrlEvent.EVT_SLEEPING);
  3958.         updateAbnormalEffect();
  3959.     }
  3960.    
  3961.     /**
  3962.      * Active the abnormal effect Confused flag, notify the L2Character AI and send Server->Client UserInfo/CharInfo packet.<BR>
  3963.      * <BR>
  3964.      */
  3965.     public final void startConfused()
  3966.     {
  3967.         setIsConfused(true);
  3968.         getAI().notifyEvent(CtrlEvent.EVT_CONFUSED);
  3969.         updateAbnormalEffect();
  3970.     }
  3971.    
  3972.     /**
  3973.      * Active the abnormal effect Fake Death flag, notify the L2Character AI and send Server->Client UserInfo/CharInfo packet.<BR>
  3974.      * <BR>
  3975.      */
  3976.     public final void startFakeDeath()
  3977.     {
  3978.         setIsFallsdown(true);
  3979.         setIsFakeDeath(true);
  3980.         /* Aborts any attacks/casts if fake dead */
  3981.         abortAttack();
  3982.         abortCast();
  3983.         stopMove(null);
  3984.         getAI().notifyEvent(CtrlEvent.EVT_FAKE_DEATH, null);
  3985.         broadcastPacket(new ChangeWaitType(this, ChangeWaitType.WT_START_FAKEDEATH));
  3986.     }
  3987.    
  3988.     /**
  3989.      * Active the abnormal effect Fear flag, notify the L2Character AI and send Server->Client UserInfo/CharInfo packet.<BR>
  3990.      * <BR>
  3991.      */
  3992.     public final void startFear()
  3993.     {
  3994.         setIsAfraid(true);
  3995.         getAI().notifyEvent(CtrlEvent.EVT_AFFRAID);
  3996.         updateAbnormalEffect();
  3997.     }
  3998.    
  3999.     /**
  4000.      * Active the abnormal effect Muted flag, notify the L2Character AI and send Server->Client UserInfo/CharInfo packet.<BR>
  4001.      * <BR>
  4002.      */
  4003.     public final void startMuted()
  4004.     {
  4005.         setIsMuted(true);
  4006.         /* Aborts any casts if muted */
  4007.         abortCast();
  4008.         getAI().notifyEvent(CtrlEvent.EVT_MUTED);
  4009.         updateAbnormalEffect();
  4010.     }
  4011.    
  4012.     /**
  4013.      * Active the abnormal effect Psychical_Muted flag, notify the L2Character AI and send Server->Client UserInfo/CharInfo packet.<BR>
  4014.      * <BR>
  4015.      */
  4016.     public final void startPsychicalMuted()
  4017.     {
  4018.         setIsPsychicalMuted(true);
  4019.         getAI().notifyEvent(CtrlEvent.EVT_MUTED);
  4020.         updateAbnormalEffect();
  4021.     }
  4022.    
  4023.     /**
  4024.      * Active the abnormal effect Root flag, notify the L2Character AI and send Server->Client UserInfo/CharInfo packet.<BR>
  4025.      * <BR>
  4026.      */
  4027.     public final void startRooted()
  4028.     {
  4029.         setIsRooted(true);
  4030.         stopMove(null);
  4031.         getAI().notifyEvent(CtrlEvent.EVT_ROOTED, null);
  4032.         updateAbnormalEffect();
  4033.     }
  4034.    
  4035.     /**
  4036.      * Active the abnormal effect Sleep flag, notify the L2Character AI and send Server->Client UserInfo/CharInfo packet.<BR>
  4037.      * <BR>
  4038.      */
  4039.     public final void startSleeping()
  4040.     {
  4041.         setIsSleeping(true);
  4042.         /* Aborts any attacks/casts if sleeped */
  4043.         abortAttack();
  4044.         abortCast();
  4045.         stopMove(null);
  4046.         getAI().notifyEvent(CtrlEvent.EVT_SLEEPING, null);
  4047.         updateAbnormalEffect();
  4048.     }
  4049.    
  4050.     /**
  4051.      * Launch a Stun Abnormal Effect on the L2Character.<BR>
  4052.      * <BR>
  4053.      * <B><U> Actions</U> :</B><BR>
  4054.      * <BR>
  4055.      * <li>Calculate the success rate of the Stun Abnormal Effect on this L2Character</li> <li>If Stun succeed, active the abnormal effect Stun flag, notify the L2Character AI and send Server->Client UserInfo/CharInfo packet</li> <li>If Stun NOT succeed, send a system message Failed to the
  4056.      * L2PcInstance attacker</li><BR>
  4057.      * <BR>
  4058.      */
  4059.     public final void startStunning()
  4060.     {
  4061.         if (isStunned())
  4062.             return;
  4063.        
  4064.         setIsStunned(true);
  4065.         /* Aborts any attacks/casts if stunned */
  4066.         abortAttack();
  4067.         abortCast();
  4068.         getAI().stopFollow(); // Like L2OFF char stop to follow if sticked to another one
  4069.         stopMove(null);
  4070.         getAI().notifyEvent(CtrlEvent.EVT_STUNNED, null);
  4071.         updateAbnormalEffect();
  4072.     }
  4073.    
  4074.     /**
  4075.      * Start betray.
  4076.      */
  4077.     public final void startBetray()
  4078.     {
  4079.         setIsBetrayed(true);
  4080.         getAI().notifyEvent(CtrlEvent.EVT_BETRAYED, null);
  4081.         updateAbnormalEffect();
  4082.     }
  4083.    
  4084.     /**
  4085.      * Stop betray.
  4086.      */
  4087.     public final void stopBetray()
  4088.     {
  4089.         stopEffects(L2Effect.EffectType.BETRAY);
  4090.         setIsBetrayed(false);
  4091.         updateAbnormalEffect();
  4092.     }
  4093.    
  4094.     /**
  4095.      * Modify the abnormal effect map according to the mask.<BR>
  4096.      * <BR>
  4097.      * @param mask the mask
  4098.      */
  4099.     public final void stopAbnormalEffect(final int mask)
  4100.     {
  4101.         _AbnormalEffects &= ~mask;
  4102.         updateAbnormalEffect();
  4103.     }
  4104.    
  4105.     /**
  4106.      * Stop all active skills effects in progress on the L2Character.<BR>
  4107.      * <BR>
  4108.      */
  4109.     public final void stopAllEffects()
  4110.     {
  4111.        
  4112.         final L2Effect[] effects = getAllEffects();
  4113.        
  4114.         for (final L2Effect effect : effects)
  4115.         {
  4116.            
  4117.             if (effect != null)
  4118.             {
  4119.                 effect.exit(true);
  4120.             }
  4121.             else
  4122.             {
  4123.                 synchronized (_effects)
  4124.                 {
  4125.                     _effects.remove(effect);
  4126.                 }
  4127.             }
  4128.         }
  4129.        
  4130.         if (this instanceof L2PcInstance)
  4131.         {
  4132.             ((L2PcInstance) this).updateAndBroadcastStatus(2);
  4133.         }
  4134.        
  4135.     }
  4136.    
  4137.     /**
  4138.      * Stop immobilization until attacked abnormal L2Effect.<BR>
  4139.      * <BR>
  4140.      * <B><U> Actions</U> :</B><BR>
  4141.      * <BR>
  4142.      * <li>Delete a specified/all (if effect=null) immobilization until attacked abnormal L2Effect from L2Character and update client magic icon</li> <li>Set the abnormal effect flag _muted to False</li> <li>Notify the L2Character AI</li> <li>Send Server->Client UserInfo/CharInfo packet</li><BR>
  4143.      * <BR>
  4144.      * @param effect the effect
  4145.      */
  4146.     public final void stopImmobileUntilAttacked(final L2Effect effect)
  4147.     {
  4148.         if (effect == null)
  4149.         {
  4150.             stopEffects(L2Effect.EffectType.IMMOBILEUNTILATTACKED);
  4151.         }
  4152.         else
  4153.         {
  4154.             removeEffect(effect);
  4155.             stopSkillEffects(effect.getSkill().getNegateId());
  4156.         }
  4157.        
  4158.         setIsImmobileUntilAttacked(false);
  4159.         getAI().notifyEvent(CtrlEvent.EVT_THINK);
  4160.         updateAbnormalEffect();
  4161.     }
  4162.    
  4163.     /**
  4164.      * Stop a specified/all Confused abnormal L2Effect.<BR>
  4165.      * <BR>
  4166.      * <B><U> Actions</U> :</B><BR>
  4167.      * <BR>
  4168.      * <li>Delete a specified/all (if effect=null) Confused abnormal L2Effect from L2Character and update client magic icone</li> <li>Set the abnormal effect flag _confused to False</li> <li>Notify the L2Character AI</li> <li>Send Server->Client UserInfo/CharInfo packet</li><BR>
  4169.      * <BR>
  4170.      * @param effect the effect
  4171.      */
  4172.     public final void stopConfused(final L2Effect effect)
  4173.     {
  4174.         if (effect == null)
  4175.         {
  4176.             stopEffects(L2Effect.EffectType.CONFUSION);
  4177.         }
  4178.         else
  4179.         {
  4180.             removeEffect(effect);
  4181.         }
  4182.        
  4183.         setIsConfused(false);
  4184.         getAI().notifyEvent(CtrlEvent.EVT_THINK, null);
  4185.         updateAbnormalEffect();
  4186.     }
  4187.    
  4188.     /**
  4189.      * Stop and remove the L2Effects corresponding to the L2Skill Identifier and update client magic icone.<BR>
  4190.      * <BR>
  4191.      * <B><U> Concept</U> :</B><BR>
  4192.      * <BR>
  4193.      * All active skills effects in progress on the L2Character are identified in ConcurrentHashMap(Integer,L2Effect) <B>_effects</B>. The Integer key of _effects is the L2Skill Identifier that has created the L2Effect.<BR>
  4194.      * <BR>
  4195.      * @param skillId the skill id
  4196.      */
  4197.     public final void stopSkillEffects(final int skillId)
  4198.     {
  4199.         final L2Effect[] effects = getAllEffects();
  4200.        
  4201.         for (final L2Effect effect : effects)
  4202.         {
  4203.            
  4204.             if (effect == null || effect.getSkill() == null)
  4205.             {
  4206.                
  4207.                 synchronized (_effects)
  4208.                 {
  4209.                     _effects.remove(effect);
  4210.                 }
  4211.                 continue;
  4212.                
  4213.             }
  4214.            
  4215.             if (effect.getSkill().getId() == skillId)
  4216.             {
  4217.                 effect.exit(true);
  4218.             }
  4219.            
  4220.         }
  4221.        
  4222.     }
  4223.    
  4224.     /**
  4225.      * Stop and remove all L2Effect of the selected type (ex : BUFF, DMG_OVER_TIME...) from the L2Character and update client magic icone.<BR>
  4226.      * <BR>
  4227.      * <B><U> Concept</U> :</B><BR>
  4228.      * <BR>
  4229.      * All active skills effects in progress on the L2Character are identified in ConcurrentHashMap(Integer,L2Effect) <B>_effects</B>. The Integer key of _effects is the L2Skill Identifier that has created the L2Effect.<BR>
  4230.      * <BR>
  4231.      * <B><U> Actions</U> :</B><BR>
  4232.      * <BR>
  4233.      * <li>Remove Func added by this effect from the L2Character Calculator (Stop L2Effect)</li> <li>Remove the L2Effect from _effects of the L2Character</li> <li>Update active skills in progress icones on player client</li><BR>
  4234.      * <BR>
  4235.      * @param type The type of effect to stop ((ex : BUFF, DMG_OVER_TIME...)
  4236.      */
  4237.     public final void stopEffects(final L2Effect.EffectType type)
  4238.     {
  4239.         final L2Effect[] effects = getAllEffects();
  4240.        
  4241.         for (final L2Effect effect : effects)
  4242.         {
  4243.            
  4244.             if (effect == null)
  4245.             {
  4246.                
  4247.                 synchronized (_effects)
  4248.                 {
  4249.                     _effects.remove(effect);
  4250.                 }
  4251.                 continue;
  4252.                
  4253.             }
  4254.            
  4255.             // LOGGER.info("Character Effect Type: "+effects[i].getEffectType());
  4256.             if (effect.getEffectType() == type)
  4257.             {
  4258.                 effect.exit(true);
  4259.             }
  4260.            
  4261.         }
  4262.        
  4263.     }
  4264.    
  4265.     /**
  4266.      * Stop and remove the L2Effects corresponding to the L2SkillType and update client magic icon.<BR>
  4267.      * <BR>
  4268.      * <B><U> Concept</U> :</B><BR>
  4269.      * <BR>
  4270.      * All active skills effects in progress on the L2Character are identified in ConcurrentHashMap(Integer,L2Effect) <B>_effects</B>. The Integer key of _effects is the L2Skill Identifier that has created the L2Effect.<BR>
  4271.      * <BR>
  4272.      * @param skillType The L2SkillType of the L2Effect to remove from _effects
  4273.      * @param power the power
  4274.      */
  4275.     public final void stopSkillEffects(final SkillType skillType, final double power)
  4276.     {
  4277.         final L2Effect[] effects = getAllEffects();
  4278.        
  4279.         for (final L2Effect effect : effects)
  4280.         {
  4281.            
  4282.             if (effect == null || effect.getSkill() == null)
  4283.             {
  4284.                
  4285.                 synchronized (_effects)
  4286.                 {
  4287.                     _effects.remove(effect);
  4288.                 }
  4289.                 continue;
  4290.                
  4291.             }
  4292.            
  4293.             if (effect.getSkill().getSkillType() == skillType && (power == 0 || effect.getSkill().getPower() <= power))
  4294.             {
  4295.                 effect.exit(true);
  4296.             }
  4297.            
  4298.         }
  4299.        
  4300.     }
  4301.    
  4302.     /**
  4303.      * Stop skill effects.
  4304.      * @param skillType the skill type
  4305.      */
  4306.     public final void stopSkillEffects(final SkillType skillType)
  4307.     {
  4308.         stopSkillEffects(skillType, -1);
  4309.     }
  4310.    
  4311.     /**
  4312.      * Stop a specified/all Fake Death abnormal L2Effect.<BR>
  4313.      * <BR>
  4314.      * <B><U> Actions</U> :</B><BR>
  4315.      * <BR>
  4316.      * <li>Delete a specified/all (if effect=null) Fake Death abnormal L2Effect from L2Character and update client magic icone</li> <li>Set the abnormal effect flag _fake_death to False</li> <li>Notify the L2Character AI</li><BR>
  4317.      * <BR>
  4318.      * @param effect the effect
  4319.      */
  4320.     public final void stopFakeDeath(final L2Effect effect)
  4321.     {
  4322.         if (effect == null)
  4323.         {
  4324.             stopEffects(L2Effect.EffectType.FAKE_DEATH);
  4325.         }
  4326.         else
  4327.         {
  4328.             removeEffect(effect);
  4329.         }
  4330.        
  4331.         setIsFakeDeath(false);
  4332.         setIsFallsdown(false);
  4333.         // if this is a player instance, start the grace period for this character (grace from mobs only)!
  4334.         if (this instanceof L2PcInstance)
  4335.         {
  4336.             ((L2PcInstance) this).setRecentFakeDeath(true);
  4337.         }
  4338.        
  4339.         ChangeWaitType revive = new ChangeWaitType(this, ChangeWaitType.WT_STOP_FAKEDEATH);
  4340.         broadcastPacket(revive);
  4341.         broadcastPacket(new Revive(this));
  4342.         getAI().notifyEvent(CtrlEvent.EVT_THINK, null);
  4343.        
  4344.         revive = null;
  4345.     }
  4346.    
  4347.     /**
  4348.      * Stop a specified/all Fear abnormal L2Effect.<BR>
  4349.      * <BR>
  4350.      * <B><U> Actions</U> :</B><BR>
  4351.      * <BR>
  4352.      * <li>Delete a specified/all (if effect=null) Fear abnormal L2Effect from L2Character and update client magic icone</li> <li>Set the abnormal effect flag _affraid to False</li> <li>Notify the L2Character AI</li> <li>Send Server->Client UserInfo/CharInfo packet</li><BR>
  4353.      * <BR>
  4354.      * @param effect the effect
  4355.      */
  4356.     public final void stopFear(final L2Effect effect)
  4357.     {
  4358.         if (effect == null)
  4359.         {
  4360.             stopEffects(L2Effect.EffectType.FEAR);
  4361.         }
  4362.         else
  4363.         {
  4364.             removeEffect(effect);
  4365.         }
  4366.        
  4367.         setIsAfraid(false);
  4368.         updateAbnormalEffect();
  4369.     }
  4370.    
  4371.     /**
  4372.      * Stop a specified/all Muted abnormal L2Effect.<BR>
  4373.      * <BR>
  4374.      * <B><U> Actions</U> :</B><BR>
  4375.      * <BR>
  4376.      * <li>Delete a specified/all (if effect=null) Muted abnormal L2Effect from L2Character and update client magic icone</li> <li>Set the abnormal effect flag _muted to False</li> <li>Notify the L2Character AI</li> <li>Send Server->Client UserInfo/CharInfo packet</li><BR>
  4377.      * <BR>
  4378.      * @param effect the effect
  4379.      */
  4380.     public final void stopMuted(final L2Effect effect)
  4381.     {
  4382.         if (effect == null)
  4383.         {
  4384.             stopEffects(L2Effect.EffectType.MUTE);
  4385.         }
  4386.         else
  4387.         {
  4388.             removeEffect(effect);
  4389.         }
  4390.        
  4391.         setIsMuted(false);
  4392.         updateAbnormalEffect();
  4393.     }
  4394.    
  4395.     /**
  4396.      * Stop psychical muted.
  4397.      * @param effect the effect
  4398.      */
  4399.     public final void stopPsychicalMuted(final L2Effect effect)
  4400.     {
  4401.         if (effect == null)
  4402.         {
  4403.             stopEffects(L2Effect.EffectType.PSYCHICAL_MUTE);
  4404.         }
  4405.         else
  4406.         {
  4407.             removeEffect(effect);
  4408.         }
  4409.        
  4410.         setIsPsychicalMuted(false);
  4411.         updateAbnormalEffect();
  4412.     }
  4413.    
  4414.     /**
  4415.      * Stop a specified/all Root abnormal L2Effect.<BR>
  4416.      * <BR>
  4417.      * <B><U> Actions</U> :</B><BR>
  4418.      * <BR>
  4419.      * <li>Delete a specified/all (if effect=null) Root abnormal L2Effect from L2Character and update client magic icone</li> <li>Set the abnormal effect flag _rooted to False</li> <li>Notify the L2Character AI</li> <li>Send Server->Client UserInfo/CharInfo packet</li><BR>
  4420.      * <BR>
  4421.      * @param effect the effect
  4422.      */
  4423.     public final void stopRooting(final L2Effect effect)
  4424.     {
  4425.         if (effect == null)
  4426.         {
  4427.             stopEffects(L2Effect.EffectType.ROOT);
  4428.         }
  4429.         else
  4430.         {
  4431.             removeEffect(effect);
  4432.         }
  4433.        
  4434.         setIsRooted(false);
  4435.         getAI().notifyEvent(CtrlEvent.EVT_THINK, null);
  4436.         updateAbnormalEffect();
  4437.     }
  4438.    
  4439.     /**
  4440.      * Stop a specified/all Sleep abnormal L2Effect.<BR>
  4441.      * <BR>
  4442.      * <B><U> Actions</U> :</B><BR>
  4443.      * <BR>
  4444.      * <li>Delete a specified/all (if effect=null) Sleep abnormal L2Effect from L2Character and update client magic icone</li> <li>Set the abnormal effect flag _sleeping to False</li> <li>Notify the L2Character AI</li> <li>Send Server->Client UserInfo/CharInfo packet</li><BR>
  4445.      * <BR>
  4446.      * @param effect the effect
  4447.      */
  4448.     public final void stopSleeping(final L2Effect effect)
  4449.     {
  4450.         if (effect == null)
  4451.         {
  4452.             stopEffects(L2Effect.EffectType.SLEEP);
  4453.         }
  4454.         else
  4455.         {
  4456.             removeEffect(effect);
  4457.         }
  4458.        
  4459.         setIsSleeping(false);
  4460.         getAI().notifyEvent(CtrlEvent.EVT_THINK, null);
  4461.         updateAbnormalEffect();
  4462.     }
  4463.    
  4464.     /**
  4465.      * Stop a specified/all Stun abnormal L2Effect.<BR>
  4466.      * <BR>
  4467.      * <B><U> Actions</U> :</B><BR>
  4468.      * <BR>
  4469.      * <li>Delete a specified/all (if effect=null) Stun abnormal L2Effect from L2Character and update client magic icone</li> <li>Set the abnormal effect flag _stuned to False</li> <li>Notify the L2Character AI</li> <li>Send Server->Client UserInfo/CharInfo packet</li><BR>
  4470.      * <BR>
  4471.      * @param effect the effect
  4472.      */
  4473.     public final void stopStunning(final L2Effect effect)
  4474.     {
  4475.         if (!isStunned())
  4476.             return;
  4477.        
  4478.         if (effect == null)
  4479.         {
  4480.             stopEffects(L2Effect.EffectType.STUN);
  4481.         }
  4482.         else
  4483.         {
  4484.             removeEffect(effect);
  4485.         }
  4486.        
  4487.         setIsStunned(false);
  4488.         getAI().notifyEvent(CtrlEvent.EVT_THINK, null);
  4489.         updateAbnormalEffect();
  4490.     }
  4491.    
  4492.     /**
  4493.      * Not Implemented.<BR>
  4494.      * <BR>
  4495.      * <B><U> Overridden in</U> :</B><BR>
  4496.      * <BR>
  4497.      * <li>L2NPCInstance</li> <li>L2PcInstance</li> <li>L2Summon</li> <li>L2DoorInstance</li><BR>
  4498.      * <BR>
  4499.      */
  4500.     public abstract void updateAbnormalEffect();
  4501.    
  4502.     /**
  4503.      * Update active skills in progress (In Use and Not In Use because stacked) icones on client.<BR>
  4504.      * <BR>
  4505.      * <B><U> Concept</U> :</B><BR>
  4506.      * <BR>
  4507.      * All active skills effects in progress (In Use and Not In Use because stacked) are represented by an icone on the client.<BR>
  4508.      * <BR>
  4509.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method ONLY UPDATE the client of the player and not clients of all players in the party.</B></FONT><BR>
  4510.      * <BR>
  4511.      */
  4512.     public final void updateEffectIcons()
  4513.     {
  4514.         updateEffectIcons(false);
  4515.     }
  4516.    
  4517.     /**
  4518.      * Update effect icons.
  4519.      * @param partyOnly the party only
  4520.      */
  4521.     public final void updateEffectIcons(final boolean partyOnly)
  4522.     {
  4523.         // Create a L2PcInstance of this if needed
  4524.         L2PcInstance player = null;
  4525.        
  4526.         if (this instanceof L2PcInstance)
  4527.         {
  4528.             player = (L2PcInstance) this;
  4529.         }
  4530.        
  4531.         // Create a L2Summon of this if needed
  4532.         L2Summon summon = null;
  4533.         if (this instanceof L2Summon)
  4534.         {
  4535.             summon = (L2Summon) this;
  4536.             player = summon.getOwner();
  4537.             summon.getOwner().sendPacket(new PetInfo(summon));
  4538.         }
  4539.        
  4540.         // Create the main packet if needed
  4541.         MagicEffectIcons mi = null;
  4542.         if (!partyOnly)
  4543.         {
  4544.             mi = new MagicEffectIcons();
  4545.         }
  4546.        
  4547.         // Create the party packet if needed
  4548.         PartySpelled ps = null;
  4549.         if (summon != null)
  4550.         {
  4551.             ps = new PartySpelled(summon);
  4552.         }
  4553.         else if (player != null && player.isInParty())
  4554.         {
  4555.             ps = new PartySpelled(player);
  4556.         }
  4557.        
  4558.         // Create the olympiad spectator packet if needed
  4559.         ExOlympiadSpelledInfo os = null;
  4560.         if (player != null && player.isInOlympiadMode())
  4561.         {
  4562.             os = new ExOlympiadSpelledInfo(player);
  4563.         }
  4564.        
  4565.         if (mi == null && ps == null && os == null)
  4566.             return; // nothing to do (should not happen)
  4567.            
  4568.         // Add special effects
  4569.         // Note: Now handled by EtcStatusUpdate packet
  4570.         // NOTE: CHECK IF THEY WERE EVEN VISIBLE TO OTHERS...
  4571.         /*
  4572.          * if (player != null && mi != null) { if (player.getWeightPenalty() > 0) mi.addEffect(4270, player.getWeightPenalty(), -1); if (player.getExpertisePenalty() > 0) mi.addEffect(4267, 1, -1); if (player.getMessageRefusal()) mi.addEffect(4269, 1, -1); }
  4573.          */
  4574.        
  4575.         // Go through all effects if any
  4576.         synchronized (_effects)
  4577.         {
  4578.            
  4579.             for (int i = 0; i < _effects.size(); i++)
  4580.             {
  4581.                
  4582.                 if (_effects.get(i) == null || _effects.get(i).getSkill() == null)
  4583.                 {
  4584.                    
  4585.                     _effects.remove(i);
  4586.                     i--;
  4587.                     continue;
  4588.                    
  4589.                 }
  4590.                
  4591.                 if (_effects.get(i).getEffectType() == L2Effect.EffectType.CHARGE && player != null)
  4592.                 {
  4593.                     // handled by EtcStatusUpdate
  4594.                     continue;
  4595.                 }
  4596.                
  4597.                 if (_effects.get(i).getInUse())
  4598.                 {
  4599.                     if (mi != null)
  4600.                     {
  4601.                         _effects.get(i).addIcon(mi);
  4602.                     }
  4603.                     // Like L2OFF toggle and healing potions must not be showed on party buff list
  4604.                     if (ps != null && !_effects.get(i).getSkill().isToggle() && !(_effects.get(i).getSkill().getId() == 2031) && !(_effects.get(i).getSkill().getId() == 2037) && !(_effects.get(i).getSkill().getId() == 2032))
  4605.                     {
  4606.                         _effects.get(i).addPartySpelledIcon(ps);
  4607.                     }
  4608.                     if (os != null)
  4609.                     {
  4610.                         _effects.get(i).addOlympiadSpelledIcon(os);
  4611.                     }
  4612.                 }
  4613.                
  4614.             }
  4615.            
  4616.         }
  4617.        
  4618.         // Send the packets if needed
  4619.         if (mi != null)
  4620.         {
  4621.             sendPacket(mi);
  4622.         }
  4623.        
  4624.         if (ps != null && player != null)
  4625.         {
  4626.             // summon info only needs to go to the owner, not to the whole party
  4627.             // player info: if in party, send to all party members except one's self.
  4628.             // if not in party, send to self.
  4629.             if (player.isInParty() && summon == null)
  4630.             {
  4631.                 player.getParty().broadcastToPartyMembers(player, ps);
  4632.             }
  4633.             else
  4634.             {
  4635.                 player.sendPacket(ps);
  4636.             }
  4637.         }
  4638.        
  4639.         if (os != null)
  4640.         {
  4641.             if ((player != null) && Olympiad.getInstance().getSpectators(player.getOlympiadGameId()) != null)
  4642.             {
  4643.                 for (final L2PcInstance spectator : Olympiad.getInstance().getSpectators(player.getOlympiadGameId()))
  4644.                 {
  4645.                     if (spectator == null)
  4646.                     {
  4647.                         continue;
  4648.                     }
  4649.                     spectator.sendPacket(os);
  4650.                 }
  4651.             }
  4652.         }
  4653.        
  4654.     }
  4655.    
  4656.     // Property - Public
  4657.     /**
  4658.      * Return a map of 16 bits (0x0000) containing all abnormal effect in progress for this L2Character.<BR>
  4659.      * <BR>
  4660.      * <B><U> Concept</U> :</B><BR>
  4661.      * <BR>
  4662.      * In Server->Client packet, each effect is represented by 1 bit of the map (ex : BLEEDING = 0x0001 (bit 1), SLEEP = 0x0080 (bit 8)...). The map is calculated by applying a BINARY OR operation on each effect.<BR>
  4663.      * <BR>
  4664.      * <B><U> Example of use </U> :</B><BR>
  4665.      * <BR>
  4666.      * <li>Server Packet : CharInfo, NpcInfo, NpcInfoPoly, UserInfo...</li><BR>
  4667.      * <BR>
  4668.      * @return the abnormal effect
  4669.      */
  4670.     public int getAbnormalEffect()
  4671.     {
  4672.         int ae = _AbnormalEffects;
  4673.        
  4674.         if (isStunned())
  4675.         {
  4676.             ae |= ABNORMAL_EFFECT_STUN;
  4677.         }
  4678.         if (isRooted())
  4679.         {
  4680.             ae |= ABNORMAL_EFFECT_ROOT;
  4681.         }
  4682.         if (isSleeping())
  4683.         {
  4684.             ae |= ABNORMAL_EFFECT_SLEEP;
  4685.         }
  4686.         if (isConfused())
  4687.         {
  4688.             ae |= ABNORMAL_EFFECT_CONFUSED;
  4689.         }
  4690.         if (isMuted())
  4691.         {
  4692.             ae |= ABNORMAL_EFFECT_MUTED;
  4693.         }
  4694.         if (isAfraid())
  4695.         {
  4696.             ae |= ABNORMAL_EFFECT_AFRAID;
  4697.         }
  4698.         if (isPsychicalMuted())
  4699.         {
  4700.             ae |= ABNORMAL_EFFECT_MUTED;
  4701.         }
  4702.        
  4703.         return ae;
  4704.     }
  4705.    
  4706.     /**
  4707.      * Return all active skills effects in progress on the L2Character.<BR>
  4708.      * <BR>
  4709.      * <B><U> Concept</U> :</B><BR>
  4710.      * <BR>
  4711.      * All active skills effects in progress on the L2Character are identified in <B>_effects</B>. The Integer key of _effects is the L2Skill Identifier that has created the effect.<BR>
  4712.      * <BR>
  4713.      * @return A table containing all active skills effect in progress on the L2Character
  4714.      */
  4715.     public final L2Effect[] getAllEffects()
  4716.     {
  4717.         synchronized (_effects)
  4718.         {
  4719.             final L2Effect[] output = _effects.toArray(new L2Effect[_effects.size()]);
  4720.            
  4721.             return output;
  4722.         }
  4723.     }
  4724.    
  4725.     /**
  4726.      * Return L2Effect in progress on the L2Character corresponding to the L2Skill Identifier.<BR>
  4727.      * <BR>
  4728.      * <B><U> Concept</U> :</B><BR>
  4729.      * <BR>
  4730.      * All active skills effects in progress on the L2Character are identified in <B>_effects</B>.
  4731.      * @param index The L2Skill Identifier of the L2Effect to return from the _effects
  4732.      * @return The L2Effect corresponding to the L2Skill Identifier
  4733.      */
  4734.     public final L2Effect getFirstEffect(final int index)
  4735.     {
  4736.         final L2Effect[] effects = getAllEffects();
  4737.        
  4738.         L2Effect effNotInUse = null;
  4739.        
  4740.         for (final L2Effect effect : effects)
  4741.         {
  4742.            
  4743.             if (effect == null)
  4744.             {
  4745.                 synchronized (_effects)
  4746.                 {
  4747.                     _effects.remove(effect);
  4748.                 }
  4749.                 continue;
  4750.             }
  4751.            
  4752.             if (effect.getSkill().getId() == index)
  4753.             {
  4754.                 if (effect.getInUse())
  4755.                     return effect;
  4756.                
  4757.                 if (effNotInUse == null)
  4758.                     effNotInUse = effect;
  4759.             }
  4760.            
  4761.         }
  4762.        
  4763.         return effNotInUse;
  4764.        
  4765.     }
  4766.    
  4767.     /**
  4768.      * Gets the first effect.
  4769.      * @param type the type
  4770.      * @return the first effect
  4771.      */
  4772.     public final L2Effect getFirstEffect(final SkillType type)
  4773.     {
  4774.        
  4775.         final L2Effect[] effects = getAllEffects();
  4776.        
  4777.         L2Effect effNotInUse = null;
  4778.        
  4779.         for (final L2Effect effect : effects)
  4780.         {
  4781.            
  4782.             if (effect == null)
  4783.             {
  4784.                 synchronized (_effects)
  4785.                 {
  4786.                     _effects.remove(effect);
  4787.                 }
  4788.                 continue;
  4789.             }
  4790.            
  4791.             if (effect.getSkill().getSkillType() == type)
  4792.             {
  4793.                 if (effect.getInUse())
  4794.                     return effect;
  4795.                
  4796.                 if (effNotInUse == null)
  4797.                     effNotInUse = effect;
  4798.             }
  4799.            
  4800.         }
  4801.        
  4802.         return effNotInUse;
  4803.        
  4804.     }
  4805.    
  4806.     /**
  4807.      * Return the first L2Effect in progress on the L2Character created by the L2Skill.<BR>
  4808.      * <BR>
  4809.      * <B><U> Concept</U> :</B><BR>
  4810.      * <BR>
  4811.      * All active skills effects in progress on the L2Character are identified in <B>_effects</B>.
  4812.      * @param skill The L2Skill whose effect must be returned
  4813.      * @return The first L2Effect created by the L2Skill
  4814.      */
  4815.     public final L2Effect getFirstEffect(final L2Skill skill)
  4816.     {
  4817.         final L2Effect[] effects = getAllEffects();
  4818.        
  4819.         L2Effect effNotInUse = null;
  4820.        
  4821.         for (final L2Effect effect : effects)
  4822.         {
  4823.            
  4824.             if (effect == null)
  4825.             {
  4826.                 synchronized (_effects)
  4827.                 {
  4828.                     _effects.remove(effect);
  4829.                 }
  4830.                 continue;
  4831.             }
  4832.            
  4833.             if (effect.getSkill() == skill)
  4834.             {
  4835.                 if (effect.getInUse())
  4836.                     return effect;
  4837.                
  4838.                 if (effNotInUse == null)
  4839.                     effNotInUse = effect;
  4840.             }
  4841.            
  4842.         }
  4843.        
  4844.         return effNotInUse;
  4845.        
  4846.     }
  4847.    
  4848.     /**
  4849.      * Return the first L2Effect in progress on the L2Character corresponding to the Effect Type (ex : BUFF, STUN, ROOT...).<BR>
  4850.      * <BR>
  4851.      * <B><U> Concept</U> :</B><BR>
  4852.      * <BR>
  4853.      * All active skills effects in progress on the L2Character are identified in ConcurrentHashMap(Integer,L2Effect) <B>_effects</B>. The Integer key of _effects is the L2Skill Identifier that has created the L2Effect.<BR>
  4854.      * <BR>
  4855.      * @param tp The Effect Type of skills whose effect must be returned
  4856.      * @return The first L2Effect corresponding to the Effect Type
  4857.      */
  4858.     public final L2Effect getFirstEffect(final L2Effect.EffectType tp)
  4859.     {
  4860.         final L2Effect[] effects = getAllEffects();
  4861.        
  4862.         L2Effect effNotInUse = null;
  4863.        
  4864.         for (final L2Effect effect : effects)
  4865.         {
  4866.            
  4867.             if (effect == null)
  4868.             {
  4869.                 synchronized (_effects)
  4870.                 {
  4871.                     _effects.remove(effect);
  4872.                 }
  4873.                 continue;
  4874.             }
  4875.            
  4876.             if (effect.getEffectType() == tp)
  4877.             {
  4878.                 if (effect.getInUse())
  4879.                     return effect;
  4880.                
  4881.                 if (effNotInUse == null)
  4882.                     effNotInUse = effect;
  4883.             }
  4884.            
  4885.         }
  4886.        
  4887.         return effNotInUse;
  4888.        
  4889.     }
  4890.    
  4891.     /**
  4892.      * Gets the charge effect.
  4893.      * @return the charge effect
  4894.      */
  4895.     public EffectCharge getChargeEffect()
  4896.     {
  4897.        
  4898.         final L2Effect effect = getFirstEffect(SkillType.CHARGE);
  4899.         if (effect != null)
  4900.             return (EffectCharge) effect;
  4901.        
  4902.         return null;
  4903.        
  4904.     }
  4905.    
  4906.     // =========================================================
  4907.     // NEED TO ORGANIZE AND MOVE TO PROPER PLACE
  4908.     /**
  4909.      * This class permit to the L2Character AI to obtain informations and uses L2Character method.
  4910.      */
  4911.     public class AIAccessor
  4912.     {
  4913.        
  4914.         /**
  4915.          * Instantiates a new aI accessor.
  4916.          */
  4917.         public AIAccessor()
  4918.         {
  4919.             // null
  4920.         }
  4921.        
  4922.         /**
  4923.          * Return the L2Character managed by this Accessor AI.<BR>
  4924.          * <BR>
  4925.          * @return the actor
  4926.          */
  4927.         public L2Character getActor()
  4928.         {
  4929.             return L2Character.this;
  4930.         }
  4931.        
  4932.         /**
  4933.          * Accessor to L2Character moveToLocation() method with an interaction area.<BR>
  4934.          * <BR>
  4935.          * @param x the x
  4936.          * @param y the y
  4937.          * @param z the z
  4938.          * @param offset the offset
  4939.          */
  4940.         public void moveTo(final int x, final int y, final int z, final int offset)
  4941.         {
  4942.             moveToLocation(x, y, z, offset);
  4943.         }
  4944.        
  4945.         /**
  4946.          * Accessor to L2Character moveToLocation() method without interaction area.<BR>
  4947.          * <BR>
  4948.          * @param x the x
  4949.          * @param y the y
  4950.          * @param z the z
  4951.          */
  4952.         public void moveTo(final int x, final int y, final int z)
  4953.         {
  4954.             moveToLocation(x, y, z, 0);
  4955.         }
  4956.        
  4957.         /**
  4958.          * Accessor to L2Character stopMove() method.<BR>
  4959.          * <BR>
  4960.          * @param pos the pos
  4961.          */
  4962.         public void stopMove(final L2CharPosition pos)
  4963.         {
  4964.             L2Character.this.stopMove(pos);
  4965.         }
  4966.        
  4967.         /**
  4968.          * Accessor to L2Character doAttack() method.<BR>
  4969.          * <BR>
  4970.          * @param target the target
  4971.          */
  4972.         public void doAttack(final L2Character target)
  4973.         {
  4974.             L2Character.this.doAttack(target);
  4975.         }
  4976.        
  4977.         /**
  4978.          * Accessor to L2Character doCast() method.<BR>
  4979.          * <BR>
  4980.          * @param skill the skill
  4981.          */
  4982.         public void doCast(final L2Skill skill)
  4983.         {
  4984.             L2Character.this.doCast(skill);
  4985.         }
  4986.        
  4987.         /**
  4988.          * Create a NotifyAITask.<BR>
  4989.          * <BR>
  4990.          * @param evt the evt
  4991.          * @return the notify ai task
  4992.          */
  4993.         public NotifyAITask newNotifyTask(final CtrlEvent evt)
  4994.         {
  4995.             return new NotifyAITask(evt);
  4996.         }
  4997.        
  4998.         /**
  4999.          * Cancel the AI.<BR>
  5000.          * <BR>
  5001.          */
  5002.         public void detachAI()
  5003.         {
  5004.             _ai = null;
  5005.         }
  5006.     }
  5007.    
  5008.     /**
  5009.      * This class group all mouvement data.<BR>
  5010.      * <BR>
  5011.      * <B><U> Data</U> :</B><BR>
  5012.      * <BR>
  5013.      * <li>_moveTimestamp : Last time position update</li> <li>_xDestination, _yDestination, _zDestination : Position of the destination</li> <li>_xMoveFrom, _yMoveFrom, _zMoveFrom : Position of the origin</li> <li>_moveStartTime : Start time of the movement</li> <li>_ticksToMove : Nb of ticks
  5014.      * between the start and the destination</li> <li>_xSpeedTicks, _ySpeedTicks : Speed in unit/ticks</li><BR>
  5015.      * <BR>
  5016.      */
  5017.     public static class MoveData
  5018.     {
  5019.         // when we retrieve x/y/z we use GameTimeControl.getGameTicks()
  5020.         // if we are moving, but move timestamp==gameticks, we don't need
  5021.         // to recalculate position
  5022.         /** The _move start time. */
  5023.         public int _moveStartTime;
  5024.        
  5025.         /** The _move timestamp. */
  5026.         public int _moveTimestamp;
  5027.        
  5028.         /** The _x destination. */
  5029.         public int _xDestination;
  5030.        
  5031.         /** The _y destination. */
  5032.         public int _yDestination;
  5033.        
  5034.         /** The _z destination. */
  5035.         public int _zDestination;
  5036.        
  5037.         /** The _x accurate. */
  5038.         public double _xAccurate;
  5039.        
  5040.         /** The _y accurate. */
  5041.         public double _yAccurate;
  5042.        
  5043.         /** The _z accurate. */
  5044.         public double _zAccurate;
  5045.        
  5046.         /** The _heading. */
  5047.         public int _heading;
  5048.        
  5049.         /** The disregarding geodata. */
  5050.         public boolean disregardingGeodata;
  5051.        
  5052.         /** The on geodata path index. */
  5053.         public int onGeodataPathIndex;
  5054.        
  5055.         /** The geo path. */
  5056.         public Node[] geoPath;
  5057.        
  5058.         /** The geo path accurate tx. */
  5059.         public int geoPathAccurateTx;
  5060.        
  5061.         /** The geo path accurate ty. */
  5062.         public int geoPathAccurateTy;
  5063.        
  5064.         /** The geo path gtx. */
  5065.         public int geoPathGtx;
  5066.        
  5067.         /** The geo path gty. */
  5068.         public int geoPathGty;
  5069.     }
  5070.    
  5071.     /** Table containing all skillId that are disabled. */
  5072.     protected List<Integer> _disabledSkills;
  5073.    
  5074.     /** The _all skills disabled. */
  5075.     private boolean _allSkillsDisabled;
  5076.    
  5077.     // private int _flyingRunSpeed;
  5078.     // private int _floatingWalkSpeed;
  5079.     // private int _flyingWalkSpeed;
  5080.     // private int _floatingRunSpeed;
  5081.    
  5082.     /** Movement data of this L2Character. */
  5083.     protected MoveData _move;
  5084.    
  5085.     /** Orientation of the L2Character. */
  5086.     private int _heading;
  5087.    
  5088.     /** L2Charcater targeted by the L2Character. */
  5089.     private L2Object _target;
  5090.    
  5091.     // set by the start of casting, in game ticks
  5092.     /** The _cast end time. */
  5093.     private int _castEndTime;
  5094.    
  5095.     /** The _cast interrupt time. */
  5096.     private int _castInterruptTime;
  5097.    
  5098.     // set by the start of casting, in game ticks
  5099.     /** The _cast potion end time. */
  5100.     private int _castPotionEndTime;
  5101.    
  5102.     /** The _cast potion interrupt time. */
  5103.     @SuppressWarnings("unused")
  5104.     private int _castPotionInterruptTime;
  5105.    
  5106.     // set by the start of attack, in game ticks
  5107.     /** The _attack end time. */
  5108.     int _attackEndTime;
  5109.    
  5110.     /** The _attacking. */
  5111.     private int _attacking;
  5112.    
  5113.     /** The _disable bow attack end time. */
  5114.     private int _disableBowAttackEndTime;
  5115.    
  5116.     /** Table of calculators containing all standard NPC calculator (ex : ACCURACY_COMBAT, EVASION_RATE. */
  5117.     private static final Calculator[] NPC_STD_CALCULATOR;
  5118.     static
  5119.     {
  5120.         NPC_STD_CALCULATOR = Formulas.getInstance().getStdNPCCalculators();
  5121.     }
  5122.    
  5123.     /** The _ai. */
  5124.     protected L2CharacterAI _ai;
  5125.    
  5126.     /** Future Skill Cast. */
  5127.     protected Future<?> _skillCast;
  5128.    
  5129.     /** Future Potion Cast. */
  5130.     protected Future<?> _potionCast;
  5131.    
  5132.     /** Char Coords from Client. */
  5133.     private int _clientX;
  5134.    
  5135.     /** The _client y. */
  5136.     private int _clientY;
  5137.    
  5138.     /** The _client z. */
  5139.     private int _clientZ;
  5140.    
  5141.     /** The _client heading. */
  5142.     private int _clientHeading;
  5143.    
  5144.     /** List of all QuestState instance that needs to be notified of this character's death. */
  5145.     private List<QuestState> _NotifyQuestOfDeathList = new FastList<>();
  5146.    
  5147.     /**
  5148.      * Add QuestState instance that is to be notified of character's death.<BR>
  5149.      * <BR>
  5150.      * @param qs The QuestState that subscribe to this event
  5151.      */
  5152.     public void addNotifyQuestOfDeath(final QuestState qs)
  5153.     {
  5154.         if (qs == null || _NotifyQuestOfDeathList.contains(qs))
  5155.             return;
  5156.        
  5157.         _NotifyQuestOfDeathList.add(qs);
  5158.     }
  5159.    
  5160.     /**
  5161.      * Return a list of L2Character that attacked.<BR>
  5162.      * <BR>
  5163.      * @return the notify quest of death
  5164.      */
  5165.     public final List<QuestState> getNotifyQuestOfDeath()
  5166.     {
  5167.         if (_NotifyQuestOfDeathList == null)
  5168.         {
  5169.             _NotifyQuestOfDeathList = new FastList<>();
  5170.         }
  5171.        
  5172.         return _NotifyQuestOfDeathList;
  5173.     }
  5174.    
  5175.     /**
  5176.      * Add a Func to the Calculator set of the L2Character.<BR>
  5177.      * <BR>
  5178.      * <B><U> Concept</U> :</B><BR>
  5179.      * <BR>
  5180.      * A L2Character owns a table of Calculators called <B>_calculators</B>. Each Calculator (a calculator per state) own a table of Func object. A Func object is a mathematic function that permit to calculate the modifier of a state (ex : REGENERATE_HP_RATE...). To reduce cache memory use,
  5181.      * L2NPCInstances who don't have skills share the same Calculator set called <B>NPC_STD_CALCULATOR</B>.<BR>
  5182.      * <BR>
  5183.      * That's why, if a L2NPCInstance is under a skill/spell effect that modify one of its state, a copy of the NPC_STD_CALCULATOR must be create in its _calculators before addind new Func object.<BR>
  5184.      * <BR>
  5185.      * <B><U> Actions</U> :</B><BR>
  5186.      * <BR>
  5187.      * <li>If _calculators is linked to NPC_STD_CALCULATOR, create a copy of NPC_STD_CALCULATOR in _calculators</li> <li>Add the Func object to _calculators</li><BR>
  5188.      * <BR>
  5189.      * @param f The Func object to add to the Calculator corresponding to the state affected
  5190.      */
  5191.     public final synchronized void addStatFunc(final Func f)
  5192.     {
  5193.         if (f == null)
  5194.             return;
  5195.        
  5196.         // Check if Calculator set is linked to the standard Calculator set of NPC
  5197.         if (_calculators == NPC_STD_CALCULATOR)
  5198.         {
  5199.             // Create a copy of the standard NPC Calculator set
  5200.             _calculators = new Calculator[Stats.NUM_STATS];
  5201.            
  5202.             for (int i = 0; i < Stats.NUM_STATS; i++)
  5203.             {
  5204.                 if (NPC_STD_CALCULATOR[i] != null)
  5205.                 {
  5206.                     _calculators[i] = new Calculator(NPC_STD_CALCULATOR[i]);
  5207.                 }
  5208.             }
  5209.         }
  5210.        
  5211.         // Select the Calculator of the affected state in the Calculator set
  5212.         final int stat = f.stat.ordinal();
  5213.        
  5214.         if (_calculators[stat] == null)
  5215.         {
  5216.             _calculators[stat] = new Calculator();
  5217.         }
  5218.        
  5219.         // Add the Func to the calculator corresponding to the state
  5220.         _calculators[stat].addFunc(f);
  5221.        
  5222.     }
  5223.    
  5224.     /**
  5225.      * Add a list of Funcs to the Calculator set of the L2Character.<BR>
  5226.      * <BR>
  5227.      * <B><U> Concept</U> :</B><BR>
  5228.      * <BR>
  5229.      * A L2Character owns a table of Calculators called <B>_calculators</B>. Each Calculator (a calculator per state) own a table of Func object. A Func object is a mathematic function that permit to calculate the modifier of a state (ex : REGENERATE_HP_RATE...). <BR>
  5230.      * <BR>
  5231.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method is ONLY for L2PcInstance</B></FONT><BR>
  5232.      * <BR>
  5233.      * <B><U> Example of use </U> :</B><BR>
  5234.      * <BR>
  5235.      * <li>Equip an item from inventory</li> <li>Learn a new passive skill</li> <li>Use an active skill</li><BR>
  5236.      * <BR>
  5237.      * @param funcs The list of Func objects to add to the Calculator corresponding to the state affected
  5238.      */
  5239.     public final synchronized void addStatFuncs(final Func[] funcs)
  5240.     {
  5241.        
  5242.         FastList<Stats> modifiedStats = new FastList<>();
  5243.        
  5244.         for (final Func f : funcs)
  5245.         {
  5246.             modifiedStats.add(f.stat);
  5247.             addStatFunc(f);
  5248.         }
  5249.        
  5250.         broadcastModifiedStats(modifiedStats);
  5251.        
  5252.         modifiedStats = null;
  5253.     }
  5254.    
  5255.     /**
  5256.      * Remove a Func from the Calculator set of the L2Character.<BR>
  5257.      * <BR>
  5258.      * <B><U> Concept</U> :</B><BR>
  5259.      * <BR>
  5260.      * A L2Character owns a table of Calculators called <B>_calculators</B>. Each Calculator (a calculator per state) own a table of Func object. A Func object is a mathematic function that permit to calculate the modifier of a state (ex : REGENERATE_HP_RATE...). To reduce cache memory use,
  5261.      * L2NPCInstances who don't have skills share the same Calculator set called <B>NPC_STD_CALCULATOR</B>.<BR>
  5262.      * <BR>
  5263.      * That's why, if a L2NPCInstance is under a skill/spell effect that modify one of its state, a copy of the NPC_STD_CALCULATOR must be create in its _calculators before addind new Func object.<BR>
  5264.      * <BR>
  5265.      * <B><U> Actions</U> :</B><BR>
  5266.      * <BR>
  5267.      * <li>Remove the Func object from _calculators</li><BR>
  5268.      * <BR>
  5269.      * <li>If L2Character is a L2NPCInstance and _calculators is equal to NPC_STD_CALCULATOR, free cache memory and just create a link on NPC_STD_CALCULATOR in _calculators</li><BR>
  5270.      * <BR>
  5271.      * @param f The Func object to remove from the Calculator corresponding to the state affected
  5272.      */
  5273.     public final synchronized void removeStatFunc(final Func f)
  5274.     {
  5275.         if (f == null)
  5276.             return;
  5277.        
  5278.         // Select the Calculator of the affected state in the Calculator set
  5279.         final int stat = f.stat.ordinal();
  5280.        
  5281.         if (_calculators[stat] == null)
  5282.             return;
  5283.        
  5284.         // Remove the Func object from the Calculator
  5285.         _calculators[stat].removeFunc(f);
  5286.        
  5287.         if (_calculators[stat].size() == 0)
  5288.         {
  5289.             _calculators[stat] = null;
  5290.         }
  5291.        
  5292.         // If possible, free the memory and just create a link on NPC_STD_CALCULATOR
  5293.         if (this instanceof L2NpcInstance)
  5294.         {
  5295.             int i = 0;
  5296.            
  5297.             for (; i < Stats.NUM_STATS; i++)
  5298.             {
  5299.                 if (!Calculator.equalsCals(_calculators[i], NPC_STD_CALCULATOR[i]))
  5300.                 {
  5301.                     break;
  5302.                 }
  5303.             }
  5304.            
  5305.             if (i >= Stats.NUM_STATS)
  5306.             {
  5307.                 _calculators = NPC_STD_CALCULATOR;
  5308.             }
  5309.         }
  5310.     }
  5311.    
  5312.     /**
  5313.      * Remove a list of Funcs from the Calculator set of the L2PcInstance.<BR>
  5314.      * <BR>
  5315.      * <B><U> Concept</U> :</B><BR>
  5316.      * <BR>
  5317.      * A L2Character owns a table of Calculators called <B>_calculators</B>. Each Calculator (a calculator per state) own a table of Func object. A Func object is a mathematic function that permit to calculate the modifier of a state (ex : REGENERATE_HP_RATE...). <BR>
  5318.      * <BR>
  5319.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method is ONLY for L2PcInstance</B></FONT><BR>
  5320.      * <BR>
  5321.      * <B><U> Example of use </U> :</B><BR>
  5322.      * <BR>
  5323.      * <li>Unequip an item from inventory</li> <li>Stop an active skill</li><BR>
  5324.      * <BR>
  5325.      * @param funcs The list of Func objects to add to the Calculator corresponding to the state affected
  5326.      */
  5327.     public final synchronized void removeStatFuncs(final Func[] funcs)
  5328.     {
  5329.        
  5330.         FastList<Stats> modifiedStats = new FastList<>();
  5331.        
  5332.         for (final Func f : funcs)
  5333.         {
  5334.             modifiedStats.add(f.stat);
  5335.             removeStatFunc(f);
  5336.         }
  5337.        
  5338.         broadcastModifiedStats(modifiedStats);
  5339.        
  5340.         modifiedStats = null;
  5341.     }
  5342.    
  5343.     /**
  5344.      * Remove all Func objects with the selected owner from the Calculator set of the L2Character.<BR>
  5345.      * <BR>
  5346.      * <B><U> Concept</U> :</B><BR>
  5347.      * <BR>
  5348.      * A L2Character owns a table of Calculators called <B>_calculators</B>. Each Calculator (a calculator per state) own a table of Func object. A Func object is a mathematic function that permit to calculate the modifier of a state (ex : REGENERATE_HP_RATE...). To reduce cache memory use,
  5349.      * L2NPCInstances who don't have skills share the same Calculator set called <B>NPC_STD_CALCULATOR</B>.<BR>
  5350.      * <BR>
  5351.      * That's why, if a L2NPCInstance is under a skill/spell effect that modify one of its state, a copy of the NPC_STD_CALCULATOR must be create in its _calculators before addind new Func object.<BR>
  5352.      * <BR>
  5353.      * <B><U> Actions</U> :</B><BR>
  5354.      * <BR>
  5355.      * <li>Remove all Func objects of the selected owner from _calculators</li><BR>
  5356.      * <BR>
  5357.      * <li>If L2Character is a L2NPCInstance and _calculators is equal to NPC_STD_CALCULATOR, free cache memory and just create a link on NPC_STD_CALCULATOR in _calculators</li><BR>
  5358.      * <BR>
  5359.      * <B><U> Example of use </U> :</B><BR>
  5360.      * <BR>
  5361.      * <li>Unequip an item from inventory</li> <li>Stop an active skill</li><BR>
  5362.      * <BR>
  5363.      * @param owner The Object(Skill, Item...) that has created the effect
  5364.      */
  5365.     public final void removeStatsOwner(final Object owner)
  5366.     {
  5367.         FastList<Stats> modifiedStats = null;
  5368.        
  5369.         int i = 0;
  5370.         // Go through the Calculator set
  5371.         synchronized (_calculators)
  5372.         {
  5373.             for (final Calculator calc : _calculators)
  5374.             {
  5375.                 if (calc != null)
  5376.                 {
  5377.                     // Delete all Func objects of the selected owner
  5378.                     if (modifiedStats != null)
  5379.                     {
  5380.                         modifiedStats.addAll(calc.removeOwner(owner));
  5381.                     }
  5382.                     else
  5383.                     {
  5384.                         modifiedStats = calc.removeOwner(owner);
  5385.                     }
  5386.                    
  5387.                     if (calc.size() == 0)
  5388.                     {
  5389.                         _calculators[i] = null;
  5390.                     }
  5391.                 }
  5392.                 i++;
  5393.             }
  5394.            
  5395.             // If possible, free the memory and just create a link on NPC_STD_CALCULATOR
  5396.             if (this instanceof L2NpcInstance)
  5397.             {
  5398.                 i = 0;
  5399.                 for (; i < Stats.NUM_STATS; i++)
  5400.                 {
  5401.                     if (!Calculator.equalsCals(_calculators[i], NPC_STD_CALCULATOR[i]))
  5402.                     {
  5403.                         break;
  5404.                     }
  5405.                 }
  5406.                
  5407.                 if (i >= Stats.NUM_STATS)
  5408.                 {
  5409.                     _calculators = NPC_STD_CALCULATOR;
  5410.                 }
  5411.             }
  5412.            
  5413.             if (owner instanceof L2Effect && !((L2Effect) owner).preventExitUpdate)
  5414.             {
  5415.                 broadcastModifiedStats(modifiedStats);
  5416.             }
  5417.         }
  5418.        
  5419.         modifiedStats = null;
  5420.     }
  5421.    
  5422.     /**
  5423.      * Broadcast modified stats.
  5424.      * @param stats the stats
  5425.      */
  5426.     public void broadcastModifiedStats(final FastList<Stats> stats)
  5427.     {
  5428.         if (stats == null || stats.isEmpty())
  5429.             return;
  5430.        
  5431.         boolean broadcastFull = false;
  5432.         boolean otherStats = false;
  5433.         StatusUpdate su = null;
  5434.        
  5435.         for (final Stats stat : stats)
  5436.         {
  5437.             if (stat == Stats.POWER_ATTACK_SPEED)
  5438.             {
  5439.                 if (su == null)
  5440.                 {
  5441.                     su = new StatusUpdate(getObjectId());
  5442.                 }
  5443.                
  5444.                 su.addAttribute(StatusUpdate.ATK_SPD, getPAtkSpd());
  5445.             }
  5446.             else if (stat == Stats.MAGIC_ATTACK_SPEED)
  5447.             {
  5448.                 if (su == null)
  5449.                 {
  5450.                     su = new StatusUpdate(getObjectId());
  5451.                 }
  5452.                
  5453.                 su.addAttribute(StatusUpdate.CAST_SPD, getMAtkSpd());
  5454.             }
  5455.             // else if (stat==Stats.MAX_HP) //
  5456.             // {
  5457.             // if (su == null) su = new StatusUpdate(getObjectId());
  5458.             // su.addAttribute(StatusUpdate.MAX_HP, getMaxHp());
  5459.             // }
  5460.             else if (stat == Stats.MAX_CP)
  5461.             {
  5462.                 if (this instanceof L2PcInstance)
  5463.                 {
  5464.                     if (su == null)
  5465.                     {
  5466.                         su = new StatusUpdate(getObjectId());
  5467.                     }
  5468.                    
  5469.                     su.addAttribute(StatusUpdate.MAX_CP, getMaxCp());
  5470.                 }
  5471.             }
  5472.             // else if (stat==Stats.MAX_MP)
  5473.             // {
  5474.             // if (su == null) su = new StatusUpdate(getObjectId());
  5475.             // su.addAttribute(StatusUpdate.MAX_MP, getMaxMp());
  5476.             // }
  5477.             else if (stat == Stats.RUN_SPEED)
  5478.             {
  5479.                 broadcastFull = true;
  5480.             }
  5481.             else
  5482.             {
  5483.                 otherStats = true;
  5484.             }
  5485.         }
  5486.        
  5487.         if (this instanceof L2PcInstance)
  5488.         {
  5489.             if (broadcastFull)
  5490.             {
  5491.                 ((L2PcInstance) this).updateAndBroadcastStatus(2);
  5492.             }
  5493.             else
  5494.             {
  5495.                 if (otherStats)
  5496.                 {
  5497.                     ((L2PcInstance) this).updateAndBroadcastStatus(1);
  5498.                     if (su != null)
  5499.                     {
  5500.                         for (final L2PcInstance player : getKnownList().getKnownPlayers().values())
  5501.                         {
  5502.                             try
  5503.                             {
  5504.                                 player.sendPacket(su);
  5505.                             }
  5506.                             catch (final NullPointerException e)
  5507.                             {
  5508.                                 e.printStackTrace();
  5509.                             }
  5510.                         }
  5511.                     }
  5512.                 }
  5513.                 else if (su != null)
  5514.                 {
  5515.                     broadcastPacket(su);
  5516.                 }
  5517.             }
  5518.         }
  5519.         else if (this instanceof L2NpcInstance)
  5520.         {
  5521.             if (broadcastFull && getKnownList() != null && getKnownList().getKnownPlayers() != null)
  5522.             {
  5523.                 for (final L2PcInstance player : getKnownList().getKnownPlayers().values())
  5524.                     if (player != null)
  5525.                     {
  5526.                         player.sendPacket(new NpcInfo((L2NpcInstance) this, player));
  5527.                     }
  5528.             }
  5529.             else if (su != null)
  5530.             {
  5531.                 broadcastPacket(su);
  5532.             }
  5533.         }
  5534.         else if (this instanceof L2Summon)
  5535.         {
  5536.             if (broadcastFull)
  5537.             {
  5538.                 for (final L2PcInstance player : getKnownList().getKnownPlayers().values())
  5539.                     if (player != null)
  5540.                     {
  5541.                         player.sendPacket(new NpcInfo((L2Summon) this, player));
  5542.                     }
  5543.             }
  5544.             else if (su != null)
  5545.             {
  5546.                 broadcastPacket(su);
  5547.             }
  5548.         }
  5549.         else if (su != null)
  5550.         {
  5551.             broadcastPacket(su);
  5552.         }
  5553.        
  5554.         su = null;
  5555.     }
  5556.    
  5557.     /**
  5558.      * Return the orientation of the L2Character.<BR>
  5559.      * <BR>
  5560.      * @return the heading
  5561.      */
  5562.     public final int getHeading()
  5563.     {
  5564.         return _heading;
  5565.     }
  5566.    
  5567.     /**
  5568.      * Set the orientation of the L2Character.<BR>
  5569.      * <BR>
  5570.      * @param heading the new heading
  5571.      */
  5572.     public final void setHeading(final int heading)
  5573.     {
  5574.         _heading = heading;
  5575.     }
  5576.    
  5577.     /**
  5578.      * Return the X destination of the L2Character or the X position if not in movement.<BR>
  5579.      * <BR>
  5580.      * @return the client x
  5581.      */
  5582.     public final int getClientX()
  5583.     {
  5584.         return _clientX;
  5585.     }
  5586.    
  5587.     /**
  5588.      * Gets the client y.
  5589.      * @return the client y
  5590.      */
  5591.     public final int getClientY()
  5592.     {
  5593.         return _clientY;
  5594.     }
  5595.    
  5596.     /**
  5597.      * Gets the client z.
  5598.      * @return the client z
  5599.      */
  5600.     public final int getClientZ()
  5601.     {
  5602.         return _clientZ;
  5603.     }
  5604.    
  5605.     /**
  5606.      * Gets the client heading.
  5607.      * @return the client heading
  5608.      */
  5609.     public final int getClientHeading()
  5610.     {
  5611.         return _clientHeading;
  5612.     }
  5613.    
  5614.     /**
  5615.      * Sets the client x.
  5616.      * @param val the new client x
  5617.      */
  5618.     public final void setClientX(final int val)
  5619.     {
  5620.         _clientX = val;
  5621.     }
  5622.    
  5623.     /**
  5624.      * Sets the client y.
  5625.      * @param val the new client y
  5626.      */
  5627.     public final void setClientY(final int val)
  5628.     {
  5629.         _clientY = val;
  5630.     }
  5631.    
  5632.     /**
  5633.      * Sets the client z.
  5634.      * @param val the new client z
  5635.      */
  5636.     public final void setClientZ(final int val)
  5637.     {
  5638.         _clientZ = val;
  5639.     }
  5640.    
  5641.     /**
  5642.      * Sets the client heading.
  5643.      * @param val the new client heading
  5644.      */
  5645.     public final void setClientHeading(final int val)
  5646.     {
  5647.         _clientHeading = val;
  5648.     }
  5649.    
  5650.     /**
  5651.      * Gets the xdestination.
  5652.      * @return the xdestination
  5653.      */
  5654.     public final int getXdestination()
  5655.     {
  5656.         final MoveData m = _move;
  5657.        
  5658.         if (m != null)
  5659.             return m._xDestination;
  5660.        
  5661.         return getX();
  5662.     }
  5663.    
  5664.     /**
  5665.      * Return the Y destination of the L2Character or the Y position if not in movement.<BR>
  5666.      * <BR>
  5667.      * @return the ydestination
  5668.      */
  5669.     public final int getYdestination()
  5670.     {
  5671.         final MoveData m = _move;
  5672.        
  5673.         if (m != null)
  5674.             return m._yDestination;
  5675.        
  5676.         return getY();
  5677.     }
  5678.    
  5679.     /**
  5680.      * Return the Z destination of the L2Character or the Z position if not in movement.<BR>
  5681.      * <BR>
  5682.      * @return the zdestination
  5683.      */
  5684.     public final int getZdestination()
  5685.     {
  5686.         final MoveData m = _move;
  5687.        
  5688.         if (m != null)
  5689.             return m._zDestination;
  5690.        
  5691.         return getZ();
  5692.     }
  5693.    
  5694.     /**
  5695.      * Return True if the L2Character is in combat.<BR>
  5696.      * <BR>
  5697.      * @return true, if is in combat
  5698.      */
  5699.     public boolean isInCombat()
  5700.     {
  5701.         return (getAI().getAttackTarget() != null || getAI().isAutoAttacking());
  5702.     }
  5703.    
  5704.     /**
  5705.      * Return True if the L2Character is moving.<BR>
  5706.      * <BR>
  5707.      * @return true, if is moving
  5708.      */
  5709.     public final boolean isMoving()
  5710.     {
  5711.         return _move != null;
  5712.     }
  5713.    
  5714.     /**
  5715.      * Return True if the L2Character is travelling a calculated path.<BR>
  5716.      * <BR>
  5717.      * @return true, if is on geodata path
  5718.      */
  5719.     public final boolean isOnGeodataPath()
  5720.     {
  5721.         final MoveData move = _move;
  5722.        
  5723.         if (move == null)
  5724.             return false;
  5725.        
  5726.         try
  5727.         {
  5728.             if (move.onGeodataPathIndex == -1)
  5729.                 return false;
  5730.            
  5731.             if (move.onGeodataPathIndex == move.geoPath.length - 1)
  5732.                 return false;
  5733.         }
  5734.         catch (final NullPointerException e)
  5735.         {
  5736.             e.printStackTrace();
  5737.             return false;
  5738.         }
  5739.        
  5740.         return true;
  5741.     }
  5742.    
  5743.     /**
  5744.      * Return True if the L2Character is casting.<BR>
  5745.      * <BR>
  5746.      * @return true, if is casting now
  5747.      */
  5748.     public final boolean isCastingNow()
  5749.     {
  5750.        
  5751.         final L2Effect mog = getFirstEffect(L2Effect.EffectType.SIGNET_GROUND);
  5752.         if (mog != null)
  5753.         {
  5754.             return true;
  5755.         }
  5756.        
  5757.         return _castEndTime > GameTimeController.getGameTicks();
  5758.     }
  5759.    
  5760.     /**
  5761.      * Return True if the L2Character is casting.<BR>
  5762.      * <BR>
  5763.      * @return true, if is casting potion now
  5764.      */
  5765.     public final boolean isCastingPotionNow()
  5766.     {
  5767.         return _castPotionEndTime > GameTimeController.getGameTicks();
  5768.     }
  5769.    
  5770.     /**
  5771.      * Return True if the cast of the L2Character can be aborted.<BR>
  5772.      * <BR>
  5773.      * @return true, if successful
  5774.      */
  5775.     public final boolean canAbortCast()
  5776.     {
  5777.         return _castInterruptTime > GameTimeController.getGameTicks();
  5778.     }
  5779.    
  5780.     /**
  5781.      * Return True if the L2Character is attacking.<BR>
  5782.      * <BR>
  5783.      * @return true, if is attacking now
  5784.      */
  5785.     public final boolean isAttackingNow()
  5786.     {
  5787.         return _attackEndTime > GameTimeController.getGameTicks();
  5788.     }
  5789.    
  5790.     /**
  5791.      * Return True if the L2Character has aborted its attack.<BR>
  5792.      * <BR>
  5793.      * @return true, if is attack aborted
  5794.      */
  5795.     public final boolean isAttackAborted()
  5796.     {
  5797.         return _attacking <= 0;
  5798.     }
  5799.    
  5800.     /**
  5801.      * Abort the attack of the L2Character and send Server->Client ActionFailed packet.<BR>
  5802.      * <BR>
  5803.      * see com.l2jlegacy.gameserver.model.L2Character
  5804.      */
  5805.     public final void abortAttack()
  5806.     {
  5807.         if (isAttackingNow())
  5808.         {
  5809.             _attacking = 0;
  5810.             sendPacket(ActionFailed.STATIC_PACKET);
  5811.         }
  5812.     }
  5813.    
  5814.     /**
  5815.      * Returns body part (paperdoll slot) we are targeting right now.
  5816.      * @return the attacking body part
  5817.      */
  5818.     public final int getAttackingBodyPart()
  5819.     {
  5820.         return _attacking;
  5821.     }
  5822.    
  5823.     /**
  5824.      * Abort the cast of the L2Character and send Server->Client MagicSkillCanceld/ActionFailed packet.<BR>
  5825.      * <BR>
  5826.      */
  5827.     public final void abortCast()
  5828.     {
  5829.         abortCast(false);
  5830.        
  5831.     }
  5832.    
  5833.     /**
  5834.      * Abort the cast of the L2Character and send Server->Client MagicSkillCanceld/ActionFailed packet.<BR>
  5835.      * <BR>
  5836.      * @param force the force
  5837.      */
  5838.     public final void abortCast(final boolean force)
  5839.     {
  5840.         if (isCastingNow() || force)
  5841.         {
  5842.             _castEndTime = 0;
  5843.             _castInterruptTime = 0;
  5844.            
  5845.             if (_skillCast != null)
  5846.             {
  5847.                 _skillCast.cancel(true);
  5848.                 _skillCast = null;
  5849.             }
  5850.            
  5851.             if (getForceBuff() != null)
  5852.             {
  5853.                 getForceBuff().onCastAbort();
  5854.             }
  5855.            
  5856.             final L2Effect mog = getFirstEffect(L2Effect.EffectType.SIGNET_GROUND);
  5857.             if (mog != null)
  5858.             {
  5859.                 mog.exit(true);
  5860.             }
  5861.            
  5862.             // cancels the skill hit scheduled task
  5863.             enableAllSkills(); // re-enables the skills
  5864.             if (this instanceof L2PcInstance)
  5865.             {
  5866.                 getAI().notifyEvent(CtrlEvent.EVT_FINISH_CASTING); // setting back previous intention
  5867.             }
  5868.            
  5869.             broadcastPacket(new MagicSkillCanceld(getObjectId())); // broadcast packet to stop animations client-side
  5870.             sendPacket(ActionFailed.STATIC_PACKET); // send an "action failed" packet to the caster
  5871.            
  5872.         }
  5873.         /*
  5874.          * can't abort potion cast if(isCastingPotionNow()){ _castPotionEndTime = 0; _castPotionInterruptTime = 0; if(_potionCast != null) { _potionCast.cancel(true); _potionCast = null; } }
  5875.          */
  5876.     }
  5877.    
  5878.     /**
  5879.      * Update the position of the L2Character during a movement and return True if the movement is finished.<BR>
  5880.      * <BR>
  5881.      * <B><U> Concept</U> :</B><BR>
  5882.      * <BR>
  5883.      * At the beginning of the move action, all properties of the movement are stored in the MoveData object called <B>_move</B> of the L2Character. The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<BR>
  5884.      * <BR>
  5885.      * When the movement is started (ex : by MovetoLocation), this method will be called each 0.1 sec to estimate and update the L2Character position on the server. Note, that the current server position can differe from the current client position even if each movement is straight foward. That's
  5886.      * why, client send regularly a Client->Server ValidatePosition packet to eventually correct the gap on the server. But, it's always the server position that is used in range calculation.<BR>
  5887.      * <BR>
  5888.      * At the end of the estimated movement time, the L2Character position is automatically set to the destination position even if the movement is not finished.<BR>
  5889.      * <BR>
  5890.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : The current Z position is obtained FROM THE CLIENT by the Client->Server ValidatePosition Packet. But x and y positions must be calculated to avoid that players try to modify their movement speed.</B></FONT><BR>
  5891.      * <BR>
  5892.      * @param gameTicks Nb of ticks since the server start
  5893.      * @return True if the movement is finished
  5894.      */
  5895.     public boolean updatePosition(final int gameTicks)
  5896.     {
  5897.         // Get movement data
  5898.         final MoveData m = _move;
  5899.        
  5900.         if (m == null)
  5901.             return true;
  5902.        
  5903.         if (!isVisible())
  5904.         {
  5905.             _move = null;
  5906.             return true;
  5907.         }
  5908.        
  5909.         if (m._moveTimestamp == 0)
  5910.         {
  5911.             m._moveTimestamp = m._moveStartTime;
  5912.             m._xAccurate = getX();
  5913.             m._yAccurate = getY();
  5914.         }
  5915.        
  5916.         // Check if the position has alreday be calculated
  5917.         if (m._moveTimestamp == gameTicks)
  5918.             return false;
  5919.        
  5920.         final int xPrev = getX();
  5921.         final int yPrev = getY();
  5922.         int zPrev = getZ();
  5923.        
  5924.         double dx, dy, dz, distFraction;
  5925.         if (Config.COORD_SYNCHRONIZE == 1)
  5926.         // the only method that can modify x,y while moving (otherwise _move would/should be set null)
  5927.         {
  5928.             dx = m._xDestination - xPrev;
  5929.             dy = m._yDestination - yPrev;
  5930.         }
  5931.         else
  5932.         // otherwise we need saved temporary values to avoid rounding errors
  5933.         {
  5934.             dx = m._xDestination - m._xAccurate;
  5935.             dy = m._yDestination - m._yAccurate;
  5936.         }
  5937.         // Z coordinate will follow geodata or client values
  5938.         if (Config.GEODATA > 0 && Config.COORD_SYNCHRONIZE == 2 && !isFlying() && !isInsideZone(L2Character.ZONE_WATER) && !m.disregardingGeodata && GameTimeController.getGameTicks() % 10 == 0 // once a second to reduce possible cpu load
  5939.             && !(this instanceof L2BoatInstance))
  5940.         {
  5941.             final short geoHeight = GeoData.getInstance().getSpawnHeight(xPrev, yPrev, zPrev - 30, zPrev + 30, getObjectId());
  5942.             dz = m._zDestination - geoHeight;
  5943.             // quite a big difference, compare to validatePosition packet
  5944.             if (this instanceof L2PcInstance && Math.abs(((L2PcInstance) this).getClientZ() - geoHeight) > 200 && Math.abs(((L2PcInstance) this).getClientZ() - geoHeight) < 1500)
  5945.             {
  5946.                 dz = m._zDestination - zPrev; // allow diff
  5947.             }
  5948.             else if (isInCombat() && Math.abs(dz) > 200 && dx * dx + dy * dy < 40000) // allow mob to climb up to pcinstance
  5949.             {
  5950.                 dz = m._zDestination - zPrev; // climbing
  5951.             }
  5952.             else
  5953.             {
  5954.                 zPrev = geoHeight;
  5955.             }
  5956.         }
  5957.         else
  5958.         {
  5959.             dz = m._zDestination - zPrev;
  5960.         }
  5961.        
  5962.         float speed;
  5963.         if (this instanceof L2BoatInstance)
  5964.         {
  5965.             speed = ((L2BoatInstance) this).boatSpeed;
  5966.         }
  5967.         else
  5968.         {
  5969.             speed = getStat().getMoveSpeed();
  5970.         }
  5971.        
  5972.         final double distPassed = speed * (gameTicks - m._moveTimestamp) / GameTimeController.TICKS_PER_SECOND;
  5973.         if (dx * dx + dy * dy < 10000 && dz * dz > 2500) // close enough, allows error between client and server geodata if it cannot be avoided
  5974.         {
  5975.             distFraction = distPassed / Math.sqrt(dx * dx + dy * dy);
  5976.         }
  5977.         else
  5978.         {
  5979.             distFraction = distPassed / Math.sqrt(dx * dx + dy * dy + dz * dz);
  5980.         }
  5981.        
  5982.         // if (Config.DEVELOPER) LOGGER.warn("Move Ticks:" + (gameTicks - m._moveTimestamp) + ", distPassed:" + distPassed + ", distFraction:" + distFraction);
  5983.        
  5984.         if (distFraction > 1) // already there
  5985.         {
  5986.             // Set the position of the L2Character to the destination
  5987.             super.getPosition().setXYZ(m._xDestination, m._yDestination, m._zDestination);
  5988.             if (this instanceof L2BoatInstance)
  5989.             {
  5990.                 ((L2BoatInstance) this).updatePeopleInTheBoat(m._xDestination, m._yDestination, m._zDestination);
  5991.             }
  5992.             else
  5993.             {
  5994.                 revalidateZone();
  5995.             }
  5996.         }
  5997.         else
  5998.         {
  5999.             m._xAccurate += dx * distFraction;
  6000.             m._yAccurate += dy * distFraction;
  6001.            
  6002.             // Set the position of the L2Character to estimated after parcial move
  6003.             super.getPosition().setXYZ((int) m._xAccurate, (int) m._yAccurate, zPrev + (int) (dz * distFraction + 0.5));
  6004.             if (this instanceof L2BoatInstance)
  6005.             {
  6006.                 ((L2BoatInstance) this).updatePeopleInTheBoat((int) m._xAccurate, (int) m._yAccurate, zPrev + (int) (dz * distFraction + 0.5));
  6007.             }
  6008.             else
  6009.             {
  6010.                 revalidateZone();
  6011.             }
  6012.         }
  6013.        
  6014.         // Set the timer of last position update to now
  6015.         m._moveTimestamp = gameTicks;
  6016.        
  6017.         return distFraction > 1;
  6018.     }
  6019.    
  6020.     /**
  6021.      * Revalidate zone.
  6022.      */
  6023.     public void revalidateZone()
  6024.     {
  6025.         if (getWorldRegion() == null)
  6026.             return;
  6027.        
  6028.         getWorldRegion().revalidateZones(this);
  6029.     }
  6030.    
  6031.     /**
  6032.      * Stop movement of the L2Character (Called by AI Accessor only).<BR>
  6033.      * <BR>
  6034.      * <B><U> Actions</U> :</B><BR>
  6035.      * <BR>
  6036.      * <li>Delete movement data of the L2Character</li> <li>Set the current position (x,y,z), its current L2WorldRegion if necessary and its heading</li> <li>Remove the L2Object object from _gmList** of GmListTable</li> <li>Remove object from _knownObjects and _knownPlayer* of all surrounding
  6037.      * L2WorldRegion L2Characters</li><BR>
  6038.      * <BR>
  6039.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T send Server->Client packet StopMove/StopRotation </B></FONT><BR>
  6040.      * <BR>
  6041.      * @param pos the pos
  6042.      */
  6043.     public void stopMove(final L2CharPosition pos)
  6044.     {
  6045.         stopMove(pos, true);
  6046.     }
  6047.    
  6048.     /**
  6049.      * TODO: test broadcast head packets ffro !in boat.
  6050.      * @param pos the pos
  6051.      * @param updateKnownObjects the update known objects
  6052.      */
  6053.     public void stopMove(final L2CharPosition pos, final boolean updateKnownObjects)
  6054.     {
  6055.         // Delete movement data of the L2Character
  6056.         _move = null;
  6057.        
  6058.         // Set AI_INTENTION_IDLE
  6059.         if (this instanceof L2PcInstance && getAI() != null)
  6060.             ((L2PcInstance) this).getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  6061.        
  6062.         // Set the current position (x,y,z), its current L2WorldRegion if necessary and its heading
  6063.         // All data are contained in a L2CharPosition object
  6064.         if (pos != null)
  6065.         {
  6066.             getPosition().setXYZ(pos.x, pos.y, GeoData.getInstance().getHeight(pos.x, pos.y, pos.z));
  6067.             setHeading(pos.heading);
  6068.            
  6069.             if (this instanceof L2PcInstance)
  6070.             {
  6071.                 ((L2PcInstance) this).revalidateZone(true);
  6072.                
  6073.                 if (((L2PcInstance) this).isInBoat())
  6074.                     broadcastPacket(new ValidateLocationInVehicle(this));
  6075.             }
  6076.         }
  6077.        
  6078.         broadcastPacket(new StopMove(this));
  6079.        
  6080.         if (updateKnownObjects)
  6081.             ThreadPoolManager.getInstance().executeTask(new KnownListAsynchronousUpdateTask(this));
  6082.     }
  6083.    
  6084.     /**
  6085.      * Target a L2Object (add the target to the L2Character _target, _knownObject and L2Character to _KnownObject of the L2Object).<BR>
  6086.      * <BR>
  6087.      * <B><U> Concept</U> :</B><BR>
  6088.      * <BR>
  6089.      * The L2Object (including L2Character) targeted is identified in <B>_target</B> of the L2Character<BR>
  6090.      * <BR>
  6091.      * <B><U> Actions</U> :</B><BR>
  6092.      * <BR>
  6093.      * <li>Set the _target of L2Character to L2Object</li> <li>If necessary, add L2Object to _knownObject of the L2Character</li> <li>If necessary, add L2Character to _KnownObject of the L2Object</li> <li>If object==null, cancel Attak or Cast</li><BR>
  6094.      * <BR>
  6095.      * <B><U> Overriden in </U> :</B><BR>
  6096.      * <BR>
  6097.      * <li>L2PcInstance : Remove the L2PcInstance from the old target _statusListener and add it to the new target if it was a L2Character</li><BR>
  6098.      * <BR>
  6099.      * @param object L2object to target
  6100.      */
  6101.     public void setTarget(L2Object object)
  6102.     {
  6103.         if (object != null && !object.isVisible())
  6104.         {
  6105.             object = null;
  6106.         }
  6107.        
  6108.         if (object != null && object != _target)
  6109.         {
  6110.             getKnownList().addKnownObject(object);
  6111.             object.getKnownList().addKnownObject(this);
  6112.         }
  6113.        
  6114.         // If object==null, Cancel Attak or Cast
  6115.         if (object == null)
  6116.         {
  6117.             if (_target != null)
  6118.             {
  6119.                 final TargetUnselected my = new TargetUnselected(this);
  6120.                
  6121.                 // No need to broadcast the packet to all players
  6122.                 if (this instanceof L2PcInstance)
  6123.                 {
  6124.                     // Send packet just to me and to party, not to any other that does not use the information
  6125.                     if (!this.isInParty())
  6126.                     {
  6127.                         this.sendPacket(my);
  6128.                     }
  6129.                     else
  6130.                     {
  6131.                         this.getParty().broadcastToPartyMembers(my);
  6132.                     }
  6133.                 }
  6134.                 else
  6135.                 {
  6136.                     sendPacket(new TargetUnselected(this));
  6137.                 }
  6138.             }
  6139.         }
  6140.        
  6141.         _target = object;
  6142.     }
  6143.    
  6144.     /**
  6145.      * Return the identifier of the L2Object targeted or -1.<BR>
  6146.      * <BR>
  6147.      * @return the target id
  6148.      */
  6149.     public final int getTargetId()
  6150.     {
  6151.         if (_target != null)
  6152.             return _target.getObjectId();
  6153.        
  6154.         return -1;
  6155.     }
  6156.    
  6157.     /**
  6158.      * Return the L2Object targeted or null.<BR>
  6159.      * <BR>
  6160.      * @return the target
  6161.      */
  6162.     public final L2Object getTarget()
  6163.     {
  6164.         return _target;
  6165.     }
  6166.    
  6167.     // called from AIAccessor only
  6168.     /**
  6169.      * Calculate movement data for a move to location action and add the L2Character to movingObjects of GameTimeController (only called by AI Accessor).<BR>
  6170.      * <BR>
  6171.      * <B><U> Concept</U> :</B><BR>
  6172.      * <BR>
  6173.      * At the beginning of the move action, all properties of the movement are stored in the MoveData object called <B>_move</B> of the L2Character. The position of the start point and of the destination permit to estimated in function of the movement speed the time to achieve the destination.<BR>
  6174.      * <BR>
  6175.      * All L2Character in movement are identified in <B>movingObjects</B> of GameTimeController that will call the updatePosition method of those L2Character each 0.1s.<BR>
  6176.      * <BR>
  6177.      * <B><U> Actions</U> :</B><BR>
  6178.      * <BR>
  6179.      * <li>Get current position of the L2Character</li> <li>Calculate distance (dx,dy) between current position and destination including offset</li> <li>Create and Init a MoveData object</li> <li>Set the L2Character _move object to MoveData object</li> <li>Add the L2Character to movingObjects of
  6180.      * the GameTimeController</li> <li>Create a task to notify the AI that L2Character arrives at a check point of the movement</li><BR>
  6181.      * <BR>
  6182.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T send Server->Client packet MoveToPawn/CharMoveToLocation </B></FONT><BR>
  6183.      * <BR>
  6184.      * <B><U> Example of use </U> :</B><BR>
  6185.      * <BR>
  6186.      * <li>AI : onIntentionMoveTo(L2CharPosition), onIntentionPickUp(L2Object), onIntentionInteract(L2Object)</li> <li>FollowTask</li><BR>
  6187.      * <BR>
  6188.      * @param x The X position of the destination
  6189.      * @param y The Y position of the destination
  6190.      * @param z The Y position of the destination
  6191.      * @param offset The size of the interaction area of the L2Character targeted
  6192.      */
  6193.     protected void moveToLocation(int x, int y, int z, int offset)
  6194.     {
  6195.         // Block movment during Event start
  6196.         if (this instanceof L2PcInstance)
  6197.         {
  6198.             if (L2Event.active && ((L2PcInstance) this).eventSitForced)
  6199.             {
  6200.                 ((L2PcInstance) this).sendMessage("A dark force beyond your mortal understanding makes your knees to shake when you try to stand up...");
  6201.                 ((L2PcInstance) this).getClient().sendPacket(ActionFailed.STATIC_PACKET);
  6202.                 return;
  6203.             }
  6204.             else if ((TvT.is_sitForced() && ((L2PcInstance) this)._inEventTvT) || (CTF.is_sitForced() && ((L2PcInstance) this)._inEventCTF) || (DM.is_sitForced() && ((L2PcInstance) this)._inEventDM))
  6205.             {
  6206.                 ((L2PcInstance) this).sendMessage("A dark force beyond your mortal understanding makes your knees to shake when you try to stand up...");
  6207.                 ((L2PcInstance) this).getClient().sendPacket(ActionFailed.STATIC_PACKET);
  6208.                 return;
  6209.             }
  6210.             else if (VIP._sitForced && ((L2PcInstance) this)._inEventVIP)
  6211.             {
  6212.                 ((L2PcInstance) this).sendMessage("A dark force beyond your mortal understanding makes your knees to shake when you try to stand up...");
  6213.                 ((L2PcInstance) this).sendPacket(ActionFailed.STATIC_PACKET);
  6214.                 return;
  6215.             }
  6216.         }
  6217.        
  6218.         // when start to move again, it has to stop sitdown task
  6219.         if (this instanceof L2PcInstance)
  6220.             ((L2PcInstance) this).setPosticipateSit(false);
  6221.        
  6222.         // Fix archer bug with movment/hittask
  6223.         if (this instanceof L2PcInstance && this.isAttackingNow())
  6224.         {
  6225.             final L2ItemInstance rhand = ((L2PcInstance) this).getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
  6226.             if ((rhand != null && rhand.getItemType() == L2WeaponType.BOW))
  6227.                 return;
  6228.         }
  6229.        
  6230.         // Get the Move Speed of the L2Charcater
  6231.         final float speed = getStat().getMoveSpeed();
  6232.        
  6233.         if (speed <= 0 || isMovementDisabled())
  6234.             return;
  6235.        
  6236.         // Get current position of the L2Character
  6237.         final int curX = super.getX();
  6238.         final int curY = super.getY();
  6239.         final int curZ = super.getZ();
  6240.        
  6241.         // Calculate distance (dx,dy) between current position and destination
  6242.         //
  6243.         double dx = x - curX;
  6244.         double dy = y - curY;
  6245.         double dz = z - curZ;
  6246.         double distance = Math.sqrt(dx * dx + dy * dy);
  6247.        
  6248.         if (Config.GEODATA > 0 && isInsideZone(ZONE_WATER) && distance > 700)
  6249.         {
  6250.             final double divider = 700 / distance;
  6251.             x = curX + (int) (divider * dx);
  6252.             y = curY + (int) (divider * dy);
  6253.             z = curZ + (int) (divider * dz);
  6254.             dx = x - curX;
  6255.             dy = y - curY;
  6256.             dz = z - curZ;
  6257.             distance = Math.sqrt(dx * dx + dy * dy);
  6258.         }
  6259.        
  6260.         /*
  6261.          * if(Config.DEBUG) { LOGGER.fine("distance to target:" + distance); }
  6262.          */
  6263.        
  6264.         // Define movement angles needed
  6265.         // ^
  6266.         // | X (x,y)
  6267.         // | /
  6268.         // | /distance
  6269.         // | /
  6270.         // |/ angle
  6271.         // X ---------->
  6272.         // (curx,cury)
  6273.        
  6274.         double cos;
  6275.         double sin;
  6276.        
  6277.         // Check if a movement offset is defined or no distance to go through
  6278.         if (offset > 0 || distance < 1)
  6279.         {
  6280.             // approximation for moving closer when z coordinates are different
  6281.             //
  6282.             offset -= Math.abs(dz);
  6283.            
  6284.             if (offset < 5)
  6285.             {
  6286.                 offset = 5;
  6287.             }
  6288.            
  6289.             // If no distance to go through, the movement is canceled
  6290.             if (distance < 1 || distance - offset <= 0)
  6291.             {
  6292.                 sin = 0;
  6293.                 cos = 1;
  6294.                 distance = 0;
  6295.                 x = curX;
  6296.                 y = curY;
  6297.                
  6298.                 if (Config.DEBUG)
  6299.                 {
  6300.                     LOGGER.debug("Already in range, no movement needed.");
  6301.                 }
  6302.                
  6303.                 // Notify the AI that the L2Character is arrived at destination
  6304.                 getAI().notifyEvent(CtrlEvent.EVT_ARRIVED, null);
  6305.                
  6306.                 return;
  6307.             }
  6308.             // Calculate movement angles needed
  6309.             sin = dy / distance;
  6310.             cos = dx / distance;
  6311.            
  6312.             distance -= offset - 5; // due to rounding error, we have to move a bit closer to be in range
  6313.            
  6314.             // Calculate the new destination with offset included
  6315.             x = curX + (int) (distance * cos);
  6316.             y = curY + (int) (distance * sin);
  6317.            
  6318.         }
  6319.         else
  6320.         {
  6321.             // Calculate movement angles needed
  6322.             sin = dy / distance;
  6323.             cos = dx / distance;
  6324.         }
  6325.        
  6326.         // Create and Init a MoveData object
  6327.         MoveData m = new MoveData();
  6328.        
  6329.         // GEODATA MOVEMENT CHECKS AND PATHFINDING
  6330.        
  6331.         m.onGeodataPathIndex = -1; // Initialize not on geodata path
  6332.         m.disregardingGeodata = false;
  6333.        
  6334.         if (Config.GEODATA > 0 && !isFlying() && (!isInsideZone(ZONE_WATER) || isInsideZone(ZONE_SIEGE)) && !(this instanceof L2NpcWalkerInstance))
  6335.         {
  6336.             final double originalDistance = distance;
  6337.             final int originalX = x;
  6338.             final int originalY = y;
  6339.             final int originalZ = z;
  6340.             final int gtx = originalX - L2World.MAP_MIN_X >> 4;
  6341.             final int gty = originalY - L2World.MAP_MIN_Y >> 4;
  6342.            
  6343.             // Movement checks:
  6344.             // when geodata == 2, for all characters except mobs returning home (could be changed later to teleport if pathfinding fails)
  6345.             // when geodata == 1, for l2playableinstance and l2riftinstance only
  6346.             if (Config.GEODATA > 0 && !(this instanceof L2Attackable && ((L2Attackable) this).isReturningToSpawnPoint()) || this instanceof L2PcInstance || this instanceof L2Summon && !(getAI().getIntention() == AI_INTENTION_FOLLOW) || this instanceof L2RiftInvaderInstance || isAfraid())
  6347.             {
  6348.                 if (isOnGeodataPath())
  6349.                 {
  6350.                     try
  6351.                     {
  6352.                         if (gtx == _move.geoPathGtx && gty == _move.geoPathGty)
  6353.                             return;
  6354.                         _move.onGeodataPathIndex = -1; // Set not on geodata path
  6355.                     }
  6356.                     catch (final NullPointerException e)
  6357.                     {
  6358.                         e.printStackTrace();
  6359.                     }
  6360.                 }
  6361.                
  6362.                 if (curX < L2World.MAP_MIN_X || curX > L2World.MAP_MAX_X || curY < L2World.MAP_MIN_Y || curY > L2World.MAP_MAX_Y)
  6363.                 {
  6364.                     // Temporary fix for character outside world region errors
  6365.                     LOGGER.warn("Character " + getName() + " outside world area, in coordinates x:" + curX + " y:" + curY);
  6366.                     getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  6367.                     if (this instanceof L2PcInstance)
  6368.                     {
  6369.                         ((L2PcInstance) this).deleteMe();
  6370.                     }
  6371.                     else
  6372.                     {
  6373.                         onDecay();
  6374.                     }
  6375.                    
  6376.                     return;
  6377.                 }
  6378.                 final Location destiny = GeoData.getInstance().moveCheck(curX, curY, curZ, x, y, z);
  6379.                 // location different if destination wasn't reached (or just z coord is different)
  6380.                 x = destiny.getX();
  6381.                 y = destiny.getY();
  6382.                 z = destiny.getZ();
  6383.                 distance = Math.sqrt((x - curX) * (x - curX) + (y - curY) * (y - curY));
  6384.                
  6385.             }
  6386.             // Pathfinding checks. Only when geodata setting is 2, the LoS check gives shorter result
  6387.             // than the original movement was and the LoS gives a shorter distance than 2000
  6388.             // This way of detecting need for pathfinding could be changed.
  6389.             if (((this instanceof L2PcInstance) && Config.ALLOW_PLAYERS_PATHNODE || !(this instanceof L2PcInstance)) && Config.GEODATA == 2 && originalDistance - distance > 100 && distance < 2000 && !isAfraid())
  6390.             {
  6391.                 // Path calculation
  6392.                 // Overrides previous movement check
  6393.                 if (this instanceof L2PlayableInstance || isInCombat() || this instanceof L2MinionInstance)
  6394.                 {
  6395.                     // int gx = (curX - L2World.MAP_MIN_X) >> 4;
  6396.                     // int gy = (curY - L2World.MAP_MIN_Y) >> 4;
  6397.                    
  6398.                     m.geoPath = PathFinding.getInstance().findPath(curX, curY, curZ, originalX, originalY, originalZ);
  6399.                     if (m.geoPath == null || m.geoPath.length < 2) // No path found
  6400.                     {
  6401.                         // Even though there's no path found (remember geonodes aren't perfect),
  6402.                         // the mob is attacking and right now we set it so that the mob will go
  6403.                         // after target anyway, is dz is small enough. Summons will follow their masters no matter what.
  6404.                         if (Config.ALLOW_PLAYERS_PATHNODE && (this instanceof L2PcInstance)/* this instanceof L2PcInstance || */
  6405.                             || (!(this instanceof L2PlayableInstance) && Math.abs(z - curZ) > 140) || (this instanceof L2Summon && !((L2Summon) this).getFollowStatus()))
  6406.                         {
  6407.                             getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  6408.                             return;
  6409.                         }
  6410.                         m.disregardingGeodata = true;
  6411.                         x = originalX;
  6412.                         y = originalY;
  6413.                         z = originalZ;
  6414.                         distance = originalDistance;
  6415.                     }
  6416.                     else
  6417.                     {
  6418.                         m.onGeodataPathIndex = 0; // on first segment
  6419.                         m.geoPathGtx = gtx;
  6420.                         m.geoPathGty = gty;
  6421.                         m.geoPathAccurateTx = originalX;
  6422.                         m.geoPathAccurateTy = originalY;
  6423.                        
  6424.                         x = m.geoPath[m.onGeodataPathIndex].getX();
  6425.                         y = m.geoPath[m.onGeodataPathIndex].getY();
  6426.                         z = m.geoPath[m.onGeodataPathIndex].getZ();
  6427.                        
  6428.                         // check for doors in the route
  6429.                         if (DoorTable.getInstance().checkIfDoorsBetween(curX, curY, curZ, x, y, z))
  6430.                         {
  6431.                             m.geoPath = null;
  6432.                             getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  6433.                             return;
  6434.                         }
  6435.                        
  6436.                         for (int i = 0; i < m.geoPath.length - 1; i++)
  6437.                         {
  6438.                             if (DoorTable.getInstance().checkIfDoorsBetween(m.geoPath[i], m.geoPath[i + 1]))
  6439.                             {
  6440.                                 m.geoPath = null;
  6441.                                 getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  6442.                                 return;
  6443.                             }
  6444.                         }
  6445.                        
  6446.                         dx = x - curX;
  6447.                         dy = y - curY;
  6448.                         distance = Math.sqrt(dx * dx + dy * dy);
  6449.                         sin = dy / distance;
  6450.                         cos = dx / distance;
  6451.                     }
  6452.                 }
  6453.             }
  6454.             // If no distance to go through, the movement is canceled
  6455.             if (((this instanceof L2PcInstance) && Config.ALLOW_PLAYERS_PATHNODE || !(this instanceof L2PcInstance)) && distance < 1 && (Config.GEODATA == 2 || this instanceof L2PlayableInstance || this instanceof L2RiftInvaderInstance || isAfraid()))
  6456.             {
  6457.                 /*
  6458.                  * sin = 0; cos = 1; distance = 0; x = curX; y = curY;
  6459.                  */
  6460.                
  6461.                 if (this instanceof L2Summon)
  6462.                 {
  6463.                     ((L2Summon) this).setFollowStatus(false);
  6464.                 }
  6465.                
  6466.                 // getAI().notifyEvent(CtrlEvent.EVT_ARRIVED, null);
  6467.                 getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  6468.                
  6469.                 return;
  6470.             }
  6471.         }
  6472.        
  6473.         // Caclulate the Nb of ticks between the current position and the destination
  6474.         // One tick added for rounding reasons
  6475.         final int ticksToMove = 1 + (int) (GameTimeController.TICKS_PER_SECOND * distance / speed);
  6476.        
  6477.         // Calculate and set the heading of the L2Character
  6478.         setHeading((int) (Math.atan2(-sin, -cos) * 10430.37835) + 32768);
  6479.        
  6480.         /*
  6481.          * if(Config.DEBUG) { LOGGER.fine("dist:" + distance + "speed:" + speed + " ttt:" + ticksToMove + " heading:" + getHeading()); }
  6482.          */
  6483.        
  6484.         m._xDestination = x;
  6485.         m._yDestination = y;
  6486.         m._zDestination = z; // this is what was requested from client
  6487.         m._heading = 0;
  6488.        
  6489.         m._moveStartTime = GameTimeController.getGameTicks();
  6490.        
  6491.         /*
  6492.          * if(Config.DEBUG) { LOGGER.fine("time to target:" + ticksToMove); }
  6493.          */
  6494.        
  6495.         // Set the L2Character _move object to MoveData object
  6496.         _move = m;
  6497.        
  6498.         // Add the L2Character to movingObjects of the GameTimeController
  6499.         // The GameTimeController manage objects movement
  6500.         GameTimeController.getInstance().registerMovingObject(this);
  6501.        
  6502.         // Create a task to notify the AI that L2Character arrives at a check point of the movement
  6503.         if (ticksToMove * GameTimeController.MILLIS_IN_TICK > 3000)
  6504.         {
  6505.             ThreadPoolManager.getInstance().scheduleAi(new NotifyAITask(CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
  6506.         }
  6507.        
  6508.         // the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
  6509.         // to destination by GameTimeController
  6510.        
  6511.         m = null;
  6512.     }
  6513.    
  6514.     /**
  6515.      * Move to next route point.
  6516.      * @return true, if successful
  6517.      */
  6518.     public boolean moveToNextRoutePoint()
  6519.     {
  6520.         if (!isOnGeodataPath())
  6521.         {
  6522.             // Cancel the move action
  6523.             _move = null;
  6524.             return false;
  6525.         }
  6526.        
  6527.         // Get the Move Speed of the L2Charcater
  6528.         final float speed = getStat().getMoveSpeed();
  6529.        
  6530.         if (speed <= 0 || isMovementDisabled())
  6531.         {
  6532.             // Cancel the move action
  6533.             _move = null;
  6534.             return false;
  6535.         }
  6536.        
  6537.         MoveData md = _move;
  6538.         if (md == null)
  6539.             return false;
  6540.        
  6541.         // Create and Init a MoveData object
  6542.         MoveData m = new MoveData();
  6543.        
  6544.         // Update MoveData object
  6545.         m.onGeodataPathIndex = md.onGeodataPathIndex + 1; // next segment
  6546.         m.geoPath = md.geoPath;
  6547.         m.geoPathGtx = md.geoPathGtx;
  6548.         m.geoPathGty = md.geoPathGty;
  6549.         m.geoPathAccurateTx = md.geoPathAccurateTx;
  6550.         m.geoPathAccurateTy = md.geoPathAccurateTy;
  6551.        
  6552.         if (md.onGeodataPathIndex == md.geoPath.length - 2)
  6553.         {
  6554.             m._xDestination = md.geoPathAccurateTx;
  6555.             m._yDestination = md.geoPathAccurateTy;
  6556.             m._zDestination = md.geoPath[m.onGeodataPathIndex].getZ();
  6557.         }
  6558.         else
  6559.         {
  6560.             m._xDestination = md.geoPath[m.onGeodataPathIndex].getX();
  6561.             m._yDestination = md.geoPath[m.onGeodataPathIndex].getY();
  6562.             m._zDestination = md.geoPath[m.onGeodataPathIndex].getZ();
  6563.         }
  6564.        
  6565.         final double dx = m._xDestination - super.getX();
  6566.         final double dy = m._yDestination - super.getY();
  6567.         final double distance = Math.sqrt(dx * dx + dy * dy);
  6568.         final double sin = dy / distance;
  6569.         final double cos = dx / distance;
  6570.        
  6571.         // Caclulate the Nb of ticks between the current position and the destination
  6572.         // One tick added for rounding reasons
  6573.         final int ticksToMove = 1 + (int) (GameTimeController.TICKS_PER_SECOND * distance / speed);
  6574.        
  6575.         setHeading((int) (Math.atan2(-sin, -cos) * 10430.37835) + 32768);
  6576.         m._heading = 0; // ?
  6577.        
  6578.         m._moveStartTime = GameTimeController.getGameTicks();
  6579.        
  6580.         if (Config.DEBUG)
  6581.         {
  6582.             LOGGER.debug("Time to target:" + ticksToMove);
  6583.         }
  6584.        
  6585.         // Set the L2Character _move object to MoveData object
  6586.         _move = m;
  6587.        
  6588.         // Add the L2Character to movingObjects of the GameTimeController
  6589.         // The GameTimeController manage objects movement
  6590.         GameTimeController.getInstance().registerMovingObject(this);
  6591.        
  6592.         // Create a task to notify the AI that L2Character arrives at a check point of the movement
  6593.         if (ticksToMove * GameTimeController.MILLIS_IN_TICK > 3000)
  6594.         {
  6595.             ThreadPoolManager.getInstance().scheduleAi(new NotifyAITask(CtrlEvent.EVT_ARRIVED_REVALIDATE), 2000);
  6596.         }
  6597.        
  6598.         // the CtrlEvent.EVT_ARRIVED will be sent when the character will actually arrive
  6599.         // to destination by GameTimeController
  6600.        
  6601.         // Send a Server->Client packet CharMoveToLocation to the actor and all L2PcInstance in its _knownPlayers
  6602.         CharMoveToLocation msg = new CharMoveToLocation(this);
  6603.         broadcastPacket(msg);
  6604.        
  6605.         msg = null;
  6606.         m = null;
  6607.         md = null;
  6608.        
  6609.         return true;
  6610.     }
  6611.    
  6612.     /**
  6613.      * Validate movement heading.
  6614.      * @param heading the heading
  6615.      * @return true, if successful
  6616.      */
  6617.     public boolean validateMovementHeading(final int heading)
  6618.     {
  6619.         MoveData md = _move;
  6620.        
  6621.         if (md == null)
  6622.             return true;
  6623.        
  6624.         boolean result = true;
  6625.        
  6626.         if (md._heading != heading)
  6627.         {
  6628.             result = md._heading == 0;
  6629.             md._heading = heading;
  6630.         }
  6631.        
  6632.         md = null;
  6633.        
  6634.         return result;
  6635.     }
  6636.    
  6637.     /**
  6638.      * Return the distance between the current position of the L2Character and the target (x,y).<BR>
  6639.      * <BR>
  6640.      * @param x X position of the target
  6641.      * @param y Y position of the target
  6642.      * @return the plan distance
  6643.      * @deprecated use getPlanDistanceSq(int x, int y, int z)
  6644.      */
  6645.     @Deprecated
  6646.     public final double getDistance(final int x, final int y)
  6647.     {
  6648.         final double dx = x - getX();
  6649.         final double dy = y - getY();
  6650.        
  6651.         return Math.sqrt(dx * dx + dy * dy);
  6652.     }
  6653.    
  6654.     /**
  6655.      * Return the distance between the current position of the L2Character and the target (x,y).<BR>
  6656.      * <BR>
  6657.      * @param x X position of the target
  6658.      * @param y Y position of the target
  6659.      * @param z the z
  6660.      * @return the plan distance
  6661.      * @deprecated use getPlanDistanceSq(int x, int y, int z)
  6662.      */
  6663.     @Deprecated
  6664.     public final double getDistance(final int x, final int y, final int z)
  6665.     {
  6666.         final double dx = x - getX();
  6667.         final double dy = y - getY();
  6668.         final double dz = z - getZ();
  6669.        
  6670.         return Math.sqrt(dx * dx + dy * dy + dz * dz);
  6671.     }
  6672.    
  6673.     /**
  6674.      * Return the squared distance between the current position of the L2Character and the given object.<BR>
  6675.      * <BR>
  6676.      * @param object L2Object
  6677.      * @return the squared distance
  6678.      */
  6679.     public final double getDistanceSq(final L2Object object)
  6680.     {
  6681.         return getDistanceSq(object.getX(), object.getY(), object.getZ());
  6682.     }
  6683.    
  6684.     /**
  6685.      * Return the squared distance between the current position of the L2Character and the given x, y, z.<BR>
  6686.      * <BR>
  6687.      * @param x X position of the target
  6688.      * @param y Y position of the target
  6689.      * @param z Z position of the target
  6690.      * @return the squared distance
  6691.      */
  6692.     public final double getDistanceSq(final int x, final int y, final int z)
  6693.     {
  6694.         final double dx = x - getX();
  6695.         final double dy = y - getY();
  6696.         final double dz = z - getZ();
  6697.        
  6698.         return dx * dx + dy * dy + dz * dz;
  6699.     }
  6700.    
  6701.     /**
  6702.      * Return the squared plan distance between the current position of the L2Character and the given object.<BR>
  6703.      * (check only x and y, not z)<BR>
  6704.      * <BR>
  6705.      * @param object L2Object
  6706.      * @return the squared plan distance
  6707.      */
  6708.     public final double getPlanDistanceSq(final L2Object object)
  6709.     {
  6710.         return getPlanDistanceSq(object.getX(), object.getY());
  6711.     }
  6712.    
  6713.     /**
  6714.      * Return the squared plan distance between the current position of the L2Character and the given x, y, z.<BR>
  6715.      * (check only x and y, not z)<BR>
  6716.      * <BR>
  6717.      * @param x X position of the target
  6718.      * @param y Y position of the target
  6719.      * @return the squared plan distance
  6720.      */
  6721.     public final double getPlanDistanceSq(final int x, final int y)
  6722.     {
  6723.         final double dx = x - getX();
  6724.         final double dy = y - getY();
  6725.        
  6726.         return dx * dx + dy * dy;
  6727.     }
  6728.    
  6729.     /**
  6730.      * Check if this object is inside the given radius around the given object. Warning: doesn't cover collision radius!<BR>
  6731.      * <BR>
  6732.      * @param object the target
  6733.      * @param radius the radius around the target
  6734.      * @param checkZ should we check Z axis also
  6735.      * @param strictCheck true if (distance < radius), false if (distance <= radius)
  6736.      * @return true is the L2Character is inside the radius.
  6737.      */
  6738.     public final boolean isInsideRadius(final L2Object object, final int radius, final boolean checkZ, final boolean strictCheck)
  6739.     {
  6740.         if (object != null)
  6741.             return isInsideRadius(object.getX(), object.getY(), object.getZ(), radius, checkZ, strictCheck);
  6742.         return false;
  6743.     }
  6744.    
  6745.     /**
  6746.      * Check if this object is inside the given plan radius around the given point. Warning: doesn't cover collision radius!<BR>
  6747.      * <BR>
  6748.      * @param x X position of the target
  6749.      * @param y Y position of the target
  6750.      * @param radius the radius around the target
  6751.      * @param strictCheck true if (distance < radius), false if (distance <= radius)
  6752.      * @return true is the L2Character is inside the radius.
  6753.      */
  6754.     public final boolean isInsideRadius(final int x, final int y, final int radius, final boolean strictCheck)
  6755.     {
  6756.         return isInsideRadius(x, y, 0, radius, false, strictCheck);
  6757.     }
  6758.    
  6759.     /**
  6760.      * Check if this object is inside the given radius around the given point.<BR>
  6761.      * <BR>
  6762.      * @param x X position of the target
  6763.      * @param y Y position of the target
  6764.      * @param z Z position of the target
  6765.      * @param radius the radius around the target
  6766.      * @param checkZ should we check Z axis also
  6767.      * @param strictCheck true if (distance < radius), false if (distance <= radius)
  6768.      * @return true is the L2Character is inside the radius.
  6769.      */
  6770.     public final boolean isInsideRadius(final int x, final int y, final int z, final int radius, final boolean checkZ, final boolean strictCheck)
  6771.     {
  6772.         final double dx = x - getX();
  6773.         final double dy = y - getY();
  6774.         final double dz = z - getZ();
  6775.        
  6776.         if (strictCheck)
  6777.         {
  6778.             if (checkZ)
  6779.                 return dx * dx + dy * dy + dz * dz < radius * radius;
  6780.             return dx * dx + dy * dy < radius * radius;
  6781.         }
  6782.         if (checkZ)
  6783.             return dx * dx + dy * dy + dz * dz <= radius * radius;
  6784.         return dx * dx + dy * dy <= radius * radius;
  6785.     }
  6786.    
  6787.     // /**
  6788.     // * event that is called when the destination coordinates are reached
  6789.     // */
  6790.     // public void onTargetReached()
  6791.     // {
  6792.     // L2Character pawn = getPawnTarget();
  6793.     //
  6794.     // if (pawn != null)
  6795.     // {
  6796.     // int x = pawn.getX(), y=pawn.getY(),z = pawn.getZ();
  6797.     //
  6798.     // double distance = getDistance(x,y);
  6799.     // if (getCurrentState() == STATE_FOLLOW)
  6800.     // {
  6801.     // calculateMovement(x,y,z,distance);
  6802.     // return;
  6803.     // }
  6804.     //
  6805.     // // takes care of moving away but distance is 0 so i won't follow problem
  6806.     //
  6807.     //
  6808.     // if (((distance > getAttackRange()) && (getCurrentState() == STATE_ATTACKING)) || (pawn.isMoving() && getCurrentState() != STATE_ATTACKING))
  6809.     // {
  6810.     // calculateMovement(x,y,z,distance);
  6811.     // return;
  6812.     // }
  6813.     //
  6814.     // }
  6815.     // // update x,y,z with the current calculated position
  6816.     // stopMove();
  6817.     //
  6818.     // if (Config.DEBUG)
  6819.     // LOGGER.fine(this.getName() +":: target reached at: x "+getX()+" y "+getY()+ " z:" + getZ());
  6820.     //
  6821.     // if (getPawnTarget() != null)
  6822.     // {
  6823.     //
  6824.     // setPawnTarget(null);
  6825.     // setMovingToPawn(false);
  6826.     // }
  6827.     // }
  6828.     //
  6829.     // public void setTo(int x, int y, int z, int heading)
  6830.     // {
  6831.     // setX(x);
  6832.     // setY(y);
  6833.     // setZ(z);
  6834.     // setHeading(heading);
  6835.     // updateCurrentWorldRegion();
  6836.     // if (isMoving())
  6837.     // {
  6838.     // setCurrentState(STATE_IDLE);
  6839.     // StopMove setto = new StopMove(this);
  6840.     // broadcastPacket(setto);
  6841.     // }
  6842.     // else
  6843.     // {
  6844.     // ValidateLocation setto = new ValidateLocation(this);
  6845.     // broadcastPacket(setto);
  6846.     // }
  6847.     //
  6848.     // FinishRotation fr = new FinishRotation(this);
  6849.     // broadcastPacket(fr);
  6850.     // }
  6851.    
  6852.     // protected void startCombat()
  6853.     // {
  6854.     // if (_currentAttackTask == null )//&& !isInCombat())
  6855.     // {
  6856.     // _currentAttackTask = ThreadPoolManager.getInstance().scheduleMed(new AttackTask(), 0);
  6857.     // }
  6858.     // else
  6859.     // {
  6860.     // LOGGER.info("multiple attacks want to start in parallel. prevented.");
  6861.     // }
  6862.     // }
  6863.     //
  6864.    
  6865.     /**
  6866.      * Return the Weapon Expertise Penalty of the L2Character.<BR>
  6867.      * <BR>
  6868.      * @return the weapon expertise penalty
  6869.      */
  6870.     public float getWeaponExpertisePenalty()
  6871.     {
  6872.         return 1.f;
  6873.     }
  6874.    
  6875.     /**
  6876.      * Return the Armour Expertise Penalty of the L2Character.<BR>
  6877.      * <BR>
  6878.      * @return the armour expertise penalty
  6879.      */
  6880.     public float getArmourExpertisePenalty()
  6881.     {
  6882.         return 1.f;
  6883.     }
  6884.    
  6885.     /**
  6886.      * Set _attacking corresponding to Attacking Body part to CHEST.<BR>
  6887.      * <BR>
  6888.      */
  6889.     public void setAttackingBodypart()
  6890.     {
  6891.         _attacking = Inventory.PAPERDOLL_CHEST;
  6892.     }
  6893.    
  6894.     /**
  6895.      * Retun True if arrows are available.<BR>
  6896.      * <BR>
  6897.      * <B><U> Overriden in </U> :</B><BR>
  6898.      * <BR>
  6899.      * <li>L2PcInstance</li><BR>
  6900.      * <BR>
  6901.      * @return true, if successful
  6902.      */
  6903.     protected boolean checkAndEquipArrows()
  6904.     {
  6905.         return true;
  6906.     }
  6907.    
  6908.     /**
  6909.      * Add Exp and Sp to the L2Character.<BR>
  6910.      * <BR>
  6911.      * <B><U> Overriden in </U> :</B><BR>
  6912.      * <BR>
  6913.      * <li>L2PcInstance</li> <li>L2PetInstance</li><BR>
  6914.      * <BR>
  6915.      * @param addToExp the add to exp
  6916.      * @param addToSp the add to sp
  6917.      */
  6918.     public void addExpAndSp(final long addToExp, final int addToSp)
  6919.     {
  6920.         // Dummy method (overridden by players and pets)
  6921.     }
  6922.    
  6923.     /**
  6924.      * Return the active weapon instance (always equiped in the right hand).<BR>
  6925.      * <BR>
  6926.      * <B><U> Overriden in </U> :</B><BR>
  6927.      * <BR>
  6928.      * <li>L2PcInstance</li><BR>
  6929.      * <BR>
  6930.      * @return the active weapon instance
  6931.      */
  6932.     public abstract L2ItemInstance getActiveWeaponInstance();
  6933.    
  6934.     /**
  6935.      * Return the active weapon item (always equiped in the right hand).<BR>
  6936.      * <BR>
  6937.      * <B><U> Overriden in </U> :</B><BR>
  6938.      * <BR>
  6939.      * <li>L2PcInstance</li><BR>
  6940.      * <BR>
  6941.      * @return the active weapon item
  6942.      */
  6943.     public abstract L2Weapon getActiveWeaponItem();
  6944.    
  6945.     /**
  6946.      * Return the secondary weapon instance (always equiped in the left hand).<BR>
  6947.      * <BR>
  6948.      * <B><U> Overriden in </U> :</B><BR>
  6949.      * <BR>
  6950.      * <li>L2PcInstance</li><BR>
  6951.      * <BR>
  6952.      * @return the secondary weapon instance
  6953.      */
  6954.     public abstract L2ItemInstance getSecondaryWeaponInstance();
  6955.    
  6956.     /**
  6957.      * Return the secondary weapon item (always equiped in the left hand).<BR>
  6958.      * <BR>
  6959.      * <B><U> Overriden in </U> :</B><BR>
  6960.      * <BR>
  6961.      * <li>L2PcInstance</li><BR>
  6962.      * <BR>
  6963.      * @return the secondary weapon item
  6964.      */
  6965.     public abstract L2Weapon getSecondaryWeaponItem();
  6966.    
  6967.     /**
  6968.      * Manage hit process (called by Hit Task).<BR>
  6969.      * <BR>
  6970.      * <B><U> Actions</U> :</B><BR>
  6971.      * <BR>
  6972.      * <li>If the attacker/target is dead or use fake death, notify the AI with EVT_CANCEL and send a Server->Client packet ActionFailed (if attacker is a L2PcInstance)</li> <li>If attack isn't aborted, send a message system (critical hit, missed...) to attacker/target if they are L2PcInstance</li>
  6973.      * <li>If attack isn't aborted and hit isn't missed, reduce HP of the target and calculate reflection damage to reduce HP of attacker if necessary</li> <li>if attack isn't aborted and hit isn't missed, manage attack or cast break of the target (calculating rate, sending message...)</li><BR>
  6974.      * <BR>
  6975.      * @param target The L2Character targeted
  6976.      * @param damage Nb of HP to reduce
  6977.      * @param crit True if hit is critical
  6978.      * @param miss True if hit is missed
  6979.      * @param soulshot True if SoulShot are charged
  6980.      * @param shld True if shield is efficient
  6981.      */
  6982.     protected void onHitTimer(final L2Character target, int damage, final boolean crit, final boolean miss, final boolean soulshot, final boolean shld)
  6983.     {
  6984.         // If the attacker/target is dead or use fake death, notify the AI with EVT_CANCEL
  6985.         // and send a Server->Client packet ActionFailed (if attacker is a L2PcInstance)
  6986.         if (target == null || isAlikeDead() || this instanceof L2NpcInstance && ((L2NpcInstance) this).isEventMob)
  6987.         {
  6988.             getAI().notifyEvent(CtrlEvent.EVT_CANCEL);
  6989.             return;
  6990.         }
  6991.        
  6992.         if (this instanceof L2NpcInstance && target.isAlikeDead() || target.isDead() || !getKnownList().knowsObject(target) && !(this instanceof L2DoorInstance))
  6993.         {
  6994.             // getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null);
  6995.             getAI().notifyEvent(CtrlEvent.EVT_CANCEL);
  6996.            
  6997.             sendPacket(ActionFailed.STATIC_PACKET);
  6998.             return;
  6999.         }
  7000.        
  7001.         if (miss)
  7002.         {
  7003.             if (target instanceof L2PcInstance)
  7004.             {
  7005.                 SystemMessage sm = new SystemMessage(SystemMessageId.AVOIDED_S1S_ATTACK);
  7006.                
  7007.                 if (this instanceof L2Summon)
  7008.                 {
  7009.                     final int mobId = ((L2Summon) this).getTemplate().npcId;
  7010.                     sm.addNpcName(mobId);
  7011.                 }
  7012.                 else
  7013.                 {
  7014.                     sm.addString(getName());
  7015.                 }
  7016.                
  7017.                 ((L2PcInstance) target).sendPacket(sm);
  7018.                
  7019.                 sm = null;
  7020.             }
  7021.         }
  7022.        
  7023.         // If attack isn't aborted, send a message system (critical hit, missed...) to attacker/target if they are L2PcInstance
  7024.         if (!isAttackAborted())
  7025.         {
  7026.             if (Config.ALLOW_RAID_BOSS_PETRIFIED && (this instanceof L2PcInstance || this instanceof L2Summon)) // Check if option is True Or False.
  7027.             {
  7028.                 boolean to_be_cursed = false;
  7029.                
  7030.                 // check on BossZone raid lvl
  7031.                 if (!(target instanceof L2PlayableInstance) && !(target instanceof L2SummonInstance))
  7032.                 { // this must work just on mobs/raids
  7033.                
  7034.                     if ((target.isRaid() && getLevel() > target.getLevel() + 8) || (!(target instanceof L2PcInstance) && (target.getTarget() != null && target.getTarget() instanceof L2RaidBossInstance && getLevel() > ((L2RaidBossInstance) target.getTarget()).getLevel() + 8)) || (!(target instanceof L2PcInstance) && (target.getTarget() != null && target.getTarget() instanceof L2GrandBossInstance && getLevel() > ((L2GrandBossInstance) target.getTarget()).getLevel() + 8)))
  7035.                    
  7036.                     {
  7037.                         to_be_cursed = true;
  7038.                     }
  7039.                    
  7040.                     // advanced check too if not already cursed
  7041.                     if (!to_be_cursed)
  7042.                     {
  7043.                         int boss_id = -1;
  7044.                         L2NpcTemplate boss_template = null;
  7045.                         final L2BossZone boss_zone = GrandBossManager.getInstance().getZone(this);
  7046.                        
  7047.                         if (boss_zone != null)
  7048.                         {
  7049.                             boss_id = boss_zone.getBossId();
  7050.                         }
  7051.                        
  7052.                         // boolean alive = false;
  7053.                        
  7054.                         if (boss_id != -1)
  7055.                         {
  7056.                             boss_template = NpcTable.getInstance().getTemplate(boss_id);
  7057.                            
  7058.                             if (boss_template != null && getLevel() > boss_template.getLevel() + 8)
  7059.                             {
  7060.                                 L2MonsterInstance boss_instance = null;
  7061.                                
  7062.                                 if (boss_template.type.equals("L2RaidBoss"))
  7063.                                 {
  7064.                                     final StatsSet actual_boss_stat = RaidBossSpawnManager.getInstance().getStatsSet(boss_id);
  7065.                                     if (actual_boss_stat != null)
  7066.                                     {
  7067.                                         // alive = actual_boss_stat.getLong("respawnTime") == 0;
  7068.                                         boss_instance = RaidBossSpawnManager.getInstance().getBoss(boss_id);
  7069.                                     }
  7070.                                 }
  7071.                                 else if (boss_template.type.equals("L2GrandBoss"))
  7072.                                 {
  7073.                                     final StatsSet actual_boss_stat = GrandBossManager.getInstance().getStatsSet(boss_id);
  7074.                                     if (actual_boss_stat != null)
  7075.                                     {
  7076.                                         // alive = actual_boss_stat.getLong("respawn_time") == 0;
  7077.                                         boss_instance = GrandBossManager.getInstance().getBoss(boss_id);
  7078.                                     }
  7079.                                 }
  7080.                                
  7081.                                 // max allowed rage into take cursed is 3000
  7082.                                 if (boss_instance != null/* && alive */&& boss_instance.isInsideRadius(this, 3000, false, false))
  7083.                                 {
  7084.                                     to_be_cursed = true;
  7085.                                 }
  7086.                             }
  7087.                         }
  7088.                     }
  7089.                 }
  7090.                
  7091.                 if (to_be_cursed)
  7092.                 {
  7093.                     L2Skill skill = SkillTable.getInstance().getInfo(4515, 1);
  7094.                    
  7095.                     if (skill != null)
  7096.                     {
  7097.                         abortAttack();
  7098.                         abortCast();
  7099.                         getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  7100.                         skill.getEffects(target, this, false, false, false);
  7101.                        
  7102.                         if (this instanceof L2Summon)
  7103.                         {
  7104.                             final L2Summon src = ((L2Summon) this);
  7105.                             if (src.getOwner() != null)
  7106.                             {
  7107.                                 src.getOwner().abortAttack();
  7108.                                 src.getOwner().abortCast();
  7109.                                 src.getOwner().getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  7110.                                 skill.getEffects(target, src.getOwner(), false, false, false);
  7111.                             }
  7112.                         }
  7113.                     }
  7114.                     else
  7115.                         LOGGER.warn("Skill 4515 at level 1 is missing in DP.");
  7116.                    
  7117.                     skill = null;
  7118.                    
  7119.                     if (target instanceof L2MinionInstance)
  7120.                     {
  7121.                         ((L2MinionInstance) target).getLeader().stopHating(this);
  7122.                        
  7123.                         List<L2MinionInstance> spawnedMinions = ((L2MinionInstance) target).getLeader().getSpawnedMinions();
  7124.                         if (spawnedMinions != null && spawnedMinions.size() > 0)
  7125.                         {
  7126.                             Iterator<L2MinionInstance> itr = spawnedMinions.iterator();
  7127.                             L2MinionInstance minion;
  7128.                             while (itr.hasNext())
  7129.                             {
  7130.                                 minion = itr.next();
  7131.                                 if (((L2MinionInstance) target).getLeader().getMostHated() == null)
  7132.                                 {
  7133.                                     ((L2AttackableAI) minion.getAI()).setGlobalAggro(-25);
  7134.                                     minion.clearAggroList();
  7135.                                     minion.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  7136.                                     minion.setWalking();
  7137.                                 }
  7138.                                 if (minion != null && !minion.isDead())
  7139.                                 {
  7140.                                     ((L2AttackableAI) minion.getAI()).setGlobalAggro(-25);
  7141.                                     minion.clearAggroList();
  7142.                                     minion.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  7143.                                     minion.addDamage(((L2MinionInstance) target).getLeader().getMostHated(), 100);
  7144.                                 }
  7145.                             }
  7146.                             itr = null;
  7147.                             spawnedMinions = null;
  7148.                             minion = null;
  7149.                         }
  7150.                     }
  7151.                     else
  7152.                     {
  7153.                         ((L2Attackable) target).stopHating(this);
  7154.                         List<L2MinionInstance> spawnedMinions = ((L2MonsterInstance) target).getSpawnedMinions();
  7155.                         if (spawnedMinions != null && spawnedMinions.size() > 0)
  7156.                         {
  7157.                             Iterator<L2MinionInstance> itr = spawnedMinions.iterator();
  7158.                             L2MinionInstance minion;
  7159.                             while (itr.hasNext())
  7160.                             {
  7161.                                 minion = itr.next();
  7162.                                 if (((L2Attackable) target).getMostHated() == null)
  7163.                                 {
  7164.                                     ((L2AttackableAI) minion.getAI()).setGlobalAggro(-25);
  7165.                                     minion.clearAggroList();
  7166.                                     minion.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  7167.                                     minion.setWalking();
  7168.                                 }
  7169.                                 if (minion != null && !minion.isDead())
  7170.                                 {
  7171.                                     ((L2AttackableAI) minion.getAI()).setGlobalAggro(-25);
  7172.                                     minion.clearAggroList();
  7173.                                     minion.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  7174.                                     minion.addDamage(((L2Attackable) target).getMostHated(), 100);
  7175.                                 }
  7176.                             }
  7177.                             itr = null;
  7178.                             spawnedMinions = null;
  7179.                             minion = null;
  7180.                         }
  7181.                     }
  7182.                    
  7183.                     damage = 0; // prevents messing up drop calculation
  7184.                 }
  7185.             }
  7186.            
  7187.             sendDamageMessage(target, damage, false, crit, miss);
  7188.            
  7189.             // If L2Character target is a L2PcInstance, send a system message
  7190.             if (target instanceof L2PcInstance)
  7191.             {
  7192.                 L2PcInstance enemy = (L2PcInstance) target;
  7193.                
  7194.                 // Check if shield is efficient
  7195.                 if (shld)
  7196.                 {
  7197.                     enemy.sendPacket(new SystemMessage(SystemMessageId.SHIELD_DEFENCE_SUCCESSFULL));
  7198.                     // else if (!miss && damage < 1)
  7199.                     // enemy.sendMessage("You hit the target's armor.");
  7200.                 }
  7201.                
  7202.                 enemy = null;
  7203.             }
  7204.             else if (target instanceof L2Summon)
  7205.             {
  7206.                 L2Summon activeSummon = (L2Summon) target;
  7207.                
  7208.                 SystemMessage sm = new SystemMessage(SystemMessageId.PET_RECEIVED_S2_DAMAGE_BY_S1);
  7209.                 sm.addString(getName());
  7210.                 sm.addNumber(damage);
  7211.                 activeSummon.getOwner().sendPacket(sm);
  7212.                
  7213.                 sm = null;
  7214.                 activeSummon = null;
  7215.             }
  7216.            
  7217.             if (!miss && damage > 0)
  7218.             {
  7219.                 L2Weapon weapon = getActiveWeaponItem();
  7220.                 final boolean isBow = weapon != null && weapon.getItemType().toString().equalsIgnoreCase("Bow");
  7221.                
  7222.                 if (!isBow) // Do not reflect or absorb if weapon is of type bow
  7223.                 {
  7224.                     // Absorb HP from the damage inflicted
  7225.                     final double absorbPercent = getStat().calcStat(Stats.ABSORB_DAMAGE_PERCENT, 0, null, null);
  7226.                    
  7227.                     if (absorbPercent > 0)
  7228.                     {
  7229.                         final int maxCanAbsorb = (int) (getMaxHp() - getCurrentHp());
  7230.                         int absorbDamage = (int) (absorbPercent / 100. * damage);
  7231.                        
  7232.                         if (absorbDamage > maxCanAbsorb)
  7233.                         {
  7234.                             absorbDamage = maxCanAbsorb; // Can't absord more than max hp
  7235.                         }
  7236.                        
  7237.                         if (absorbDamage > 0)
  7238.                         {
  7239.                             setCurrentHp(getCurrentHp() + absorbDamage);
  7240.                            
  7241.                             // Custom messages - nice but also more network load
  7242.                             /*
  7243.                              * if (this instanceof L2PcInstance) ((L2PcInstance)this).sendMessage("You absorbed " + absorbDamage + " damage."); else if (this instanceof L2Summon) ((L2Summon)this).getOwner().sendMessage("Summon absorbed " + absorbDamage + " damage."); else if (Config.DEBUG)
  7244.                              * LOGGER.info(getName() + " absorbed " + absorbDamage + " damage.");
  7245.                              */
  7246.                         }
  7247.                     }
  7248.                    
  7249.                     // Reduce HP of the target and calculate reflection damage to reduce HP of attacker if necessary
  7250.                     final double reflectPercent = target.getStat().calcStat(Stats.REFLECT_DAMAGE_PERCENT, 0, null, null);
  7251.                    
  7252.                     if (reflectPercent > 0)
  7253.                     {
  7254.                         int reflectedDamage = (int) (reflectPercent / 100. * damage);
  7255.                         damage -= reflectedDamage;
  7256.                        
  7257.                         if (reflectedDamage > target.getMaxHp())
  7258.                         {
  7259.                             reflectedDamage = target.getMaxHp();
  7260.                         }
  7261.                        
  7262.                         getStatus().reduceHp(reflectedDamage, target, true);
  7263.                        
  7264.                         // Custom messages - nice but also more network load
  7265.                         /*
  7266.                          * if (target instanceof L2PcInstance) ((L2PcInstance)target).sendMessage("You reflected " + reflectedDamage + " damage."); else if (target instanceof L2Summon) ((L2Summon)target).getOwner().sendMessage("Summon reflected " + reflectedDamage + " damage."); if (this instanceof
  7267.                          * L2PcInstance) ((L2PcInstance)this).sendMessage("Target reflected to you " + reflectedDamage + " damage."); else if (this instanceof L2Summon) ((L2Summon)this).getOwner().sendMessage("Target reflected to your summon " + reflectedDamage + " damage.");
  7268.                          */
  7269.                     }
  7270.                 }
  7271.                
  7272.                 target.reduceCurrentHp(damage, this);
  7273.                
  7274.                 // Notify AI with EVT_ATTACKED
  7275.                 target.getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, this);
  7276.                 getAI().clientStartAutoAttack();
  7277.                
  7278.                 // Manage attack or cast break of the target (calculating rate, sending message...)
  7279.                 if (!target.isRaid() && Formulas.calcAtkBreak(target, damage))
  7280.                 {
  7281.                     target.breakAttack();
  7282.                     target.breakCast();
  7283.                 }
  7284.                
  7285.                 // Maybe launch chance skills on us
  7286.                 if (_chanceSkills != null)
  7287.                 {
  7288.                     _chanceSkills.onHit(target, false, crit);
  7289.                 }
  7290.                
  7291.                 // Maybe launch chance skills on target
  7292.                 if (target.getChanceSkills() != null)
  7293.                 {
  7294.                     target.getChanceSkills().onHit(this, true, crit);
  7295.                 }
  7296.                
  7297.                 weapon = null;
  7298.             }
  7299.            
  7300.             // Launch weapon Special ability effect if available
  7301.             L2Weapon activeWeapon = getActiveWeaponItem();
  7302.            
  7303.             if (activeWeapon != null)
  7304.             {
  7305.                 activeWeapon.getSkillEffects(this, target, crit);
  7306.             }
  7307.            
  7308.             /*
  7309.              * COMMENTED OUT BY nexus - 2006-08-17 We must not discharge the soulshouts at the onHitTimer method, as this can cause unwanted soulshout consumption if the attacker recharges the soulshot right after an attack request but before his hit actually lands on the target. The soulshot
  7310.              * discharging has been moved to the doAttack method: As soon as we know that we didn't missed the hit there, then we must discharge any charged soulshots.
  7311.              */
  7312.             /*
  7313.              * L2ItemInstance weapon = getActiveWeaponInstance(); if (!miss) { if (this instanceof L2Summon && !(this instanceof L2PetInstance)) { if (((L2Summon)this).getChargedSoulShot() != L2ItemInstance.CHARGED_NONE) ((L2Summon)this).setChargedSoulShot(L2ItemInstance.CHARGED_NONE); } else { if
  7314.              * (weapon != null && weapon.getChargedSoulshot() != L2ItemInstance.CHARGED_NONE) weapon.setChargedSoulshot(L2ItemInstance.CHARGED_NONE); } }
  7315.              */
  7316.            
  7317.             activeWeapon = null;
  7318.            
  7319.             if (this instanceof L2PcInstance && ((L2PcInstance) this).isMovingTaskDefined())
  7320.             {
  7321.                 final L2ItemInstance rhand = ((L2PcInstance) this).getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
  7322.                 if (rhand != null && rhand.getItemType() == L2WeaponType.BOW)
  7323.                     ((L2PcInstance) this).startMovingTask();
  7324.             }
  7325.             return;
  7326.         }
  7327.        
  7328.         if (this instanceof L2PcInstance && ((L2PcInstance) this).isMovingTaskDefined())
  7329.         {
  7330.             final L2ItemInstance rhand = ((L2PcInstance) this).getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
  7331.             if (rhand != null && rhand.getItemType() == L2WeaponType.BOW)
  7332.                 ((L2PcInstance) this).startMovingTask();
  7333.         }
  7334.        
  7335.         getAI().notifyEvent(CtrlEvent.EVT_CANCEL);
  7336.     }
  7337.    
  7338.     /**
  7339.      * Break an attack and send Server->Client ActionFailed packet and a System Message to the L2Character.<BR>
  7340.      * <BR>
  7341.      */
  7342.     public void breakAttack()
  7343.     {
  7344.         if (isAttackingNow())
  7345.         {
  7346.             // Abort the attack of the L2Character and send Server->Client ActionFailed packet
  7347.             abortAttack();
  7348.            
  7349.             if (this instanceof L2PcInstance)
  7350.             {
  7351.                 sendPacket(ActionFailed.STATIC_PACKET);
  7352.                
  7353.                 // Send a system message
  7354.                 sendPacket(new SystemMessage(SystemMessageId.ATTACK_FAILED));
  7355.             }
  7356.         }
  7357.     }
  7358.    
  7359.     /**
  7360.      * Break a cast and send Server->Client ActionFailed packet and a System Message to the L2Character.<BR>
  7361.      * <BR>
  7362.      */
  7363.     public void breakCast()
  7364.     {
  7365.         // damage can only cancel magical skills
  7366.         if (isCastingNow() && canAbortCast() && getLastSkillCast() != null && getLastSkillCast().isMagic())
  7367.         {
  7368.             // Abort the cast of the L2Character and send Server->Client MagicSkillCanceld/ActionFailed packet.
  7369.             abortCast();
  7370.            
  7371.             if (this instanceof L2PcInstance)
  7372.             {
  7373.                 // Send a system message
  7374.                 sendPacket(new SystemMessage(SystemMessageId.CASTING_INTERRUPTED));
  7375.             }
  7376.         }
  7377.     }
  7378.    
  7379.     /**
  7380.      * Reduce the arrow number of the L2Character.<BR>
  7381.      * <BR>
  7382.      * <B><U> Overriden in </U> :</B><BR>
  7383.      * <BR>
  7384.      * <li>L2PcInstance</li><BR>
  7385.      * <BR>
  7386.      */
  7387.     protected void reduceArrowCount()
  7388.     {
  7389.         // default is to do nothin
  7390.     }
  7391.    
  7392.     /**
  7393.      * Manage Forced attack (shift + select target).<BR>
  7394.      * <BR>
  7395.      * <B><U> Actions</U> :</B><BR>
  7396.      * <BR>
  7397.      * <li>If L2Character or target is in a town area, send a system message TARGET_IN_PEACEZONE a Server->Client packet ActionFailed</li> <li>If target is confused, send a Server->Client packet ActionFailed</li> <li>If L2Character is a L2ArtefactInstance, send a Server->Client packet ActionFailed</li>
  7398.      * <li>Send a Server->Client packet MyTargetSelected to start attack and Notify AI with AI_INTENTION_ATTACK</li><BR>
  7399.      * <BR>
  7400.      * @param player The L2PcInstance to attack
  7401.      */
  7402.     @Override
  7403.     public void onForcedAttack(final L2PcInstance player)
  7404.     {
  7405.         if (player.getTarget() == null || !(player.getTarget() instanceof L2Character))
  7406.         {
  7407.             // If target is not attackable, send a Server->Client packet ActionFailed
  7408.             player.sendPacket(ActionFailed.STATIC_PACKET);
  7409.             return;
  7410.         }
  7411.        
  7412.         if (isInsidePeaceZone(player))
  7413.         {
  7414.             // If L2Character or target is in a peace zone, send a system message TARGET_IN_PEACEZONE a Server->Client packet ActionFailed
  7415.             player.sendPacket(new SystemMessage(SystemMessageId.TARGET_IN_PEACEZONE));
  7416.             player.sendPacket(ActionFailed.STATIC_PACKET);
  7417.             return;
  7418.         }
  7419.        
  7420.         if (player.isInOlympiadMode() && player.getTarget() != null && player.getTarget() instanceof L2PlayableInstance)
  7421.         {
  7422.             L2PcInstance target;
  7423.            
  7424.             if (player.getTarget() instanceof L2Summon)
  7425.             {
  7426.                 target = ((L2Summon) player.getTarget()).getOwner();
  7427.             }
  7428.             else
  7429.             {
  7430.                 target = (L2PcInstance) player.getTarget();
  7431.             }
  7432.            
  7433.             if (target.isInOlympiadMode() && !player.isOlympiadStart() && player.getOlympiadGameId() == target.getOlympiadGameId())
  7434.             {
  7435.                 // if L2PcInstance is in Olympia and the match isn't already start, send a Server->Client packet ActionFailed
  7436.                 player.sendPacket(ActionFailed.STATIC_PACKET);
  7437.                 return;
  7438.             }
  7439.            
  7440.             target = null;
  7441.         }
  7442.        
  7443.         if (player.isConfused() || player.isBlocked())
  7444.         {
  7445.             // If target is confused, send a Server->Client packet ActionFailed
  7446.             player.sendPacket(ActionFailed.STATIC_PACKET);
  7447.             return;
  7448.         }
  7449.        
  7450.         // GeoData Los Check or dz > 1000
  7451.         if (!GeoData.getInstance().canSeeTarget(player, this))
  7452.         {
  7453.             player.sendPacket(new SystemMessage(SystemMessageId.CANT_SEE_TARGET));
  7454.             player.sendPacket(ActionFailed.STATIC_PACKET);
  7455.             return;
  7456.         }
  7457.         // Notify AI with AI_INTENTION_ATTACK
  7458.         player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
  7459.     }
  7460.    
  7461.     /**
  7462.      * Return True if inside peace zone.<BR>
  7463.      * <BR>
  7464.      * @param attacker the attacker
  7465.      * @return true, if is inside peace zone
  7466.      */
  7467.     public boolean isInsidePeaceZone(final L2PcInstance attacker)
  7468.     {
  7469.         return isInsidePeaceZone(attacker, this);
  7470.        
  7471.     }
  7472.    
  7473.     /**
  7474.      * Checks if is inside peace zone.
  7475.      * @param attacker the attacker
  7476.      * @param target the target
  7477.      * @return true, if is inside peace zone
  7478.      */
  7479.     public static boolean isInsidePeaceZone(final L2Object attacker, final L2Object target)
  7480.     {
  7481.         if (target == null)
  7482.             return false;
  7483.        
  7484.         if (target instanceof L2NpcInstance && Config.DISABLE_ATTACK_NPC_TYPE)
  7485.         {
  7486.             final String mobtype = ((L2NpcInstance) target).getTemplate().type;
  7487.             if (Config.LIST_ALLOWED_NPC_TYPES.contains(mobtype))
  7488.             {
  7489.                 return false;
  7490.             }
  7491.         }
  7492.        
  7493.         // Attack Monster on Peace Zone like L2OFF.
  7494.         if (target instanceof L2MonsterInstance || attacker instanceof L2MonsterInstance && Config.ALT_MOB_AGRO_IN_PEACEZONE)
  7495.             return false;
  7496.        
  7497.         // Attack Guard on Peace Zone like L2OFF.
  7498.         if (target instanceof L2GuardInstance || attacker instanceof L2GuardInstance)
  7499.             return false;
  7500.         // Attack NPC on Peace Zone like L2OFF.
  7501.         if (target instanceof L2NpcInstance || attacker instanceof L2NpcInstance)
  7502.             return false;
  7503.        
  7504.         if (Config.ALT_GAME_KARMA_PLAYER_CAN_BE_KILLED_IN_PEACEZONE)
  7505.         {
  7506.             // allows red to be attacked and red to attack flagged players
  7507.             if (target instanceof L2PcInstance && ((L2PcInstance) target).getKarma() > 0)
  7508.                 return false;
  7509.            
  7510.             if (target instanceof L2Summon && ((L2Summon) target).getOwner().getKarma() > 0)
  7511.                 return false;
  7512.            
  7513.             if (attacker instanceof L2PcInstance && ((L2PcInstance) attacker).getKarma() > 0)
  7514.             {
  7515.                 if (target instanceof L2PcInstance && ((L2PcInstance) target).getPvpFlag() > 0)
  7516.                     return false;
  7517.                
  7518.                 if (target instanceof L2Summon && ((L2Summon) target).getOwner().getPvpFlag() > 0)
  7519.                     return false;
  7520.             }
  7521.            
  7522.             if (attacker instanceof L2Summon && ((L2Summon) attacker).getOwner().getKarma() > 0)
  7523.             {
  7524.                 if (target instanceof L2PcInstance && ((L2PcInstance) target).getPvpFlag() > 0)
  7525.                     return false;
  7526.                
  7527.                 if (target instanceof L2Summon && ((L2Summon) target).getOwner().getPvpFlag() > 0)
  7528.                     return false;
  7529.             }
  7530.         }
  7531.        
  7532.         // Right now only L2PcInstance has up-to-date zone status...
  7533.         //
  7534.         L2PcInstance src = null;
  7535.         L2PcInstance dst = null;
  7536.        
  7537.         if (attacker instanceof L2PlayableInstance && target instanceof L2PlayableInstance)
  7538.         {
  7539.             if (attacker instanceof L2PcInstance)
  7540.             {
  7541.                 src = (L2PcInstance) attacker;
  7542.             }
  7543.             else if (attacker instanceof L2Summon)
  7544.             {
  7545.                 src = ((L2Summon) attacker).getOwner();
  7546.             }
  7547.            
  7548.             if (target instanceof L2PcInstance)
  7549.             {
  7550.                 dst = (L2PcInstance) target;
  7551.             }
  7552.             else if (target instanceof L2Summon)
  7553.             {
  7554.                 dst = ((L2Summon) target).getOwner();
  7555.             }
  7556.         }
  7557.        
  7558.         if (src != null && src.getAccessLevel().allowPeaceAttack())
  7559.         {
  7560.             return false;
  7561.         }
  7562.        
  7563.         // checks on event status
  7564.         if (src != null && dst != null)
  7565.         {
  7566.             // Attacker and target can fight in olympiad with peace zone
  7567.             if (src.isInOlympiadMode() && src.isOlympiadStart() && dst.isInOlympiadMode() && dst.isOlympiadStart())
  7568.                 return false;
  7569.            
  7570.             if (dst.isInFunEvent() && src.isInFunEvent())
  7571.             {
  7572.                
  7573.                 if (src.isInStartedTVTEvent() && dst.isInStartedTVTEvent())
  7574.                     return false;
  7575.                 else if (src.isInStartedDMEvent() && dst.isInStartedDMEvent())
  7576.                     return false;
  7577.                 else if (src.isInStartedCTFEvent() && dst.isInStartedCTFEvent())
  7578.                     return false;
  7579.                 else if (src.isInStartedVIPEvent() && dst.isInStartedVIPEvent())
  7580.                     return false;
  7581.                 else if (src.isInStartedVIPEvent() && dst.isInStartedVIPEvent())
  7582.                     return false;
  7583.                 // else
  7584.                 // different events in same location --> already checked
  7585.             }
  7586.         }
  7587.        
  7588.         if (attacker instanceof L2Character && ((L2Character) attacker).isInsideZone(ZONE_PEACE)
  7589.         // the townzone has to be already peace zone
  7590.         // || TownManager.getInstance().getTown(attacker.getX(), attacker.getY(), attacker.getZ())!= null
  7591.         )
  7592.             return true;
  7593.        
  7594.         if (target instanceof L2Character && ((L2Character) target).isInsideZone(ZONE_PEACE)
  7595.         // the townzone has to be already peace zone
  7596.         // || TownManager.getInstance().getTown(target.getX(), target.getY(), target.getZ())!= null
  7597.         )
  7598.             return true;
  7599.        
  7600.         return false;
  7601.     }
  7602.    
  7603.     /**
  7604.      * return true if this character is inside an active grid.
  7605.      * @return the boolean
  7606.      */
  7607.     public Boolean isInActiveRegion()
  7608.     {
  7609.         try
  7610.         {
  7611.             final L2WorldRegion region = L2World.getInstance().getRegion(getX(), getY());
  7612.             return region != null && region.isActive();
  7613.         }
  7614.         catch (final Exception e)
  7615.         {
  7616.             if (this instanceof L2PcInstance)
  7617.             {
  7618.                 LOGGER.warn("Player " + getName() + " at bad coords: (x: " + getX() + ", y: " + getY() + ", z: " + getZ() + ").");
  7619.                
  7620.                 ((L2PcInstance) this).sendMessage("Error with your coordinates! Please reboot your game fully!");
  7621.                 ((L2PcInstance) this).teleToLocation(80753, 145481, -3532, false); // Near Giran luxury shop
  7622.             }
  7623.             else
  7624.             {
  7625.                 LOGGER.warn("Object " + getName() + " at bad coords: (x: " + getX() + ", y: " + getY() + ", z: " + getZ() + ").");
  7626.                 decayMe();
  7627.             }
  7628.             return false;
  7629.         }
  7630.     }
  7631.    
  7632.     /**
  7633.      * Return True if the L2Character has a Party in progress.<BR>
  7634.      * <BR>
  7635.      * @return true, if is in party
  7636.      */
  7637.     public boolean isInParty()
  7638.     {
  7639.         return false;
  7640.     }
  7641.    
  7642.     /**
  7643.      * Return the L2Party object of the L2Character.<BR>
  7644.      * <BR>
  7645.      * @return the party
  7646.      */
  7647.     public L2Party getParty()
  7648.     {
  7649.         return null;
  7650.     }
  7651.    
  7652.     /**
  7653.      * Return the Attack Speed of the L2Character (delay (in milliseconds) before next attack).<BR>
  7654.      * <BR>
  7655.      * @param target the target
  7656.      * @param weapon the weapon
  7657.      * @return the int
  7658.      */
  7659.     public int calculateTimeBetweenAttacks(final L2Character target, final L2Weapon weapon)
  7660.     {
  7661.         double atkSpd = 0;
  7662.         if (weapon != null)
  7663.         {
  7664.             switch (weapon.getItemType())
  7665.             {
  7666.                 case BOW:
  7667.                     atkSpd = getStat().getPAtkSpd();
  7668.                     return (int) (1500 * 345 / atkSpd);
  7669.                 case DAGGER:
  7670.                     atkSpd = getStat().getPAtkSpd();
  7671.                     // atkSpd /= 1.15;
  7672.                     break;
  7673.                 default:
  7674.                     atkSpd = getStat().getPAtkSpd();
  7675.             }
  7676.         }
  7677.         else
  7678.         {
  7679.             atkSpd = getPAtkSpd();
  7680.         }
  7681.        
  7682.         return Formulas.getInstance().calcPAtkSpd(this, target, atkSpd);
  7683.     }
  7684.    
  7685.     /**
  7686.      * Calculate reuse time.
  7687.      * @param target the target
  7688.      * @param weapon the weapon
  7689.      * @return the int
  7690.      */
  7691.     public int calculateReuseTime(final L2Character target, final L2Weapon weapon)
  7692.     {
  7693.         if (weapon == null)
  7694.             return 0;
  7695.        
  7696.         int reuse = weapon.getAttackReuseDelay();
  7697.        
  7698.         // only bows should continue for now
  7699.         if (reuse == 0)
  7700.             return 0;
  7701.        
  7702.         // else if (reuse < 10) reuse = 1500;
  7703.         reuse *= getStat().getReuseModifier(target);
  7704.        
  7705.         final double atkSpd = getStat().getPAtkSpd();
  7706.        
  7707.         switch (weapon.getItemType())
  7708.         {
  7709.             case BOW:
  7710.                 return (int) (reuse * 345 / atkSpd);
  7711.             default:
  7712.                 return (int) (reuse * 312 / atkSpd);
  7713.         }
  7714.     }
  7715.    
  7716.     /**
  7717.      * Return True if the L2Character use a dual weapon.<BR>
  7718.      * <BR>
  7719.      * @return true, if is using dual weapon
  7720.      */
  7721.     public boolean isUsingDualWeapon()
  7722.     {
  7723.         return false;
  7724.     }
  7725.    
  7726.     /**
  7727.      * Add a skill to the L2Character _skills and its Func objects to the calculator set of the L2Character.<BR>
  7728.      * <BR>
  7729.      * <B><U> Concept</U> :</B><BR>
  7730.      * <BR>
  7731.      * All skills own by a L2Character are identified in <B>_skills</B><BR>
  7732.      * <BR>
  7733.      * <B><U> Actions</U> :</B><BR>
  7734.      * <BR>
  7735.      * <li>Replace oldSkill by newSkill or Add the newSkill</li> <li>If an old skill has been replaced, remove all its Func objects of L2Character calculator set</li> <li>Add Func objects of newSkill to the calculator set of the L2Character</li><BR>
  7736.      * <BR>
  7737.      * <B><U> Overriden in </U> :</B><BR>
  7738.      * <BR>
  7739.      * <li>L2PcInstance : Save update in the character_skills table of the database</li><BR>
  7740.      * <BR>
  7741.      * @param newSkill The L2Skill to add to the L2Character
  7742.      * @return The L2Skill replaced or null if just added a new L2Skill
  7743.      */
  7744.     @Override
  7745.     public L2Skill addSkill(final L2Skill newSkill)
  7746.     {
  7747.         L2Skill oldSkill = null;
  7748.        
  7749.         if (newSkill != null)
  7750.         {
  7751.             // Replace oldSkill by newSkill or Add the newSkill
  7752.             oldSkill = _skills.put(newSkill.getId(), newSkill);
  7753.            
  7754.             // If an old skill has been replaced, remove all its Func objects
  7755.             if (oldSkill != null)
  7756.             {
  7757.                 // if skill came with another one, we should delete the other one too.
  7758.                 if (oldSkill.triggerAnotherSkill())
  7759.                 {
  7760.                     if (Config.DEBUG)
  7761.                         LOGGER.info("Removing Triggherable Skill: " + oldSkill.getTriggeredId());
  7762.                    
  7763.                     _triggeredSkills.remove(oldSkill.getTriggeredId());
  7764.                     removeSkill(oldSkill.getTriggeredId(), true);
  7765.                 }
  7766.                 removeStatsOwner(oldSkill);
  7767.                
  7768.                 // final Func[] skill_funcs = oldSkill.getStatFuncs(null, this);
  7769.                
  7770.                 // // Remove old func if single effect skill is defined
  7771.                 // if(newSkill.is_singleEffect()
  7772.                 // && skill_funcs.length>0)
  7773.                 // removeStatFuncs(skill_funcs);
  7774.                
  7775.             }
  7776.            
  7777.             // Add Func objects of newSkill to the calculator set of the L2Character
  7778.             addStatFuncs(newSkill.getStatFuncs(null, this));
  7779.            
  7780.             if (oldSkill != null && _chanceSkills != null)
  7781.             {
  7782.                 removeChanceSkill(oldSkill.getId());
  7783.             }
  7784.             if (newSkill.isChance())
  7785.             {
  7786.                 addChanceSkill(newSkill);
  7787.             }
  7788.            
  7789.             if (newSkill.isChance() && newSkill.triggerAnotherSkill())
  7790.             {
  7791.                 final L2Skill triggeredSkill = SkillTable.getInstance().getInfo(newSkill.getTriggeredId(), newSkill.getTriggeredLevel());
  7792.                 addSkill(triggeredSkill);
  7793.             }
  7794.            
  7795.             if (newSkill.triggerAnotherSkill())
  7796.             {
  7797.                 if (Config.DEBUG)
  7798.                     LOGGER.info("Adding Triggherable Skill: " + newSkill.getTriggeredId());
  7799.                 _triggeredSkills.put(newSkill.getTriggeredId(), SkillTable.getInstance().getInfo(newSkill.getTriggeredId(), newSkill.getTriggeredLevel()));
  7800.             }
  7801.            
  7802.         }
  7803.        
  7804.         return oldSkill;
  7805.     }
  7806.    
  7807.     /**
  7808.      * Adds the chance skill.
  7809.      * @param skill the skill
  7810.      */
  7811.     public void addChanceSkill(final L2Skill skill)
  7812.     {
  7813.         synchronized (this)
  7814.         {
  7815.             if (_chanceSkills == null)
  7816.             {
  7817.                 _chanceSkills = new ChanceSkillList(this);
  7818.             }
  7819.            
  7820.             _chanceSkills.put(skill, skill.getChanceCondition());
  7821.         }
  7822.     }
  7823.    
  7824.     /**
  7825.      * Removes the chance skill.
  7826.      * @param id the id
  7827.      */
  7828.     public void removeChanceSkill(final int id)
  7829.     {
  7830.         synchronized (this)
  7831.         {
  7832.             for (final L2Skill skill : _chanceSkills.keySet())
  7833.             {
  7834.                 if (skill.getId() == id)
  7835.                 {
  7836.                     _chanceSkills.remove(skill);
  7837.                 }
  7838.             }
  7839.            
  7840.             if (_chanceSkills.size() == 0)
  7841.             {
  7842.                 _chanceSkills = null;
  7843.             }
  7844.         }
  7845.     }
  7846.    
  7847.     /**
  7848.      * Remove a skill from the L2Character and its Func objects from calculator set of the L2Character.<BR>
  7849.      * <BR>
  7850.      * <B><U> Concept</U> :</B><BR>
  7851.      * <BR>
  7852.      * All skills own by a L2Character are identified in <B>_skills</B><BR>
  7853.      * <BR>
  7854.      * <B><U> Actions</U> :</B><BR>
  7855.      * <BR>
  7856.      * <li>Remove the skill from the L2Character _skills</li> <li>Remove all its Func objects from the L2Character calculator set</li><BR>
  7857.      * <BR>
  7858.      * <B><U> Overriden in </U> :</B><BR>
  7859.      * <BR>
  7860.      * <li>L2PcInstance : Save update in the character_skills table of the database</li><BR>
  7861.      * <BR>
  7862.      * @param skill The L2Skill to remove from the L2Character
  7863.      * @return The L2Skill removed
  7864.      */
  7865.     public synchronized L2Skill removeSkill(final L2Skill skill)
  7866.     {
  7867.         if (skill == null)
  7868.             return null;
  7869.        
  7870.         // Remove the skill from the L2Character _skills
  7871.         return removeSkill(skill.getId());
  7872.     }
  7873.    
  7874.     /**
  7875.      * Removes the skill.
  7876.      * @param skillId the skill id
  7877.      * @return the l2 skill
  7878.      */
  7879.     public L2Skill removeSkill(final int skillId)
  7880.     {
  7881.         return removeSkill(skillId, true);
  7882.     }
  7883.    
  7884.     /**
  7885.      * Removes the skill.
  7886.      * @param skillId the skill id
  7887.      * @param cancelEffect the cancel effect
  7888.      * @return the l2 skill
  7889.      */
  7890.     public L2Skill removeSkill(final int skillId, final boolean cancelEffect)
  7891.     {
  7892.         // Remove the skill from the L2Character _skills
  7893.         final L2Skill oldSkill = _skills.remove(skillId);
  7894.         // Remove all its Func objects from the L2Character calculator set
  7895.         if (oldSkill != null)
  7896.         {
  7897.             // this is just a fail-safe againts buggers and gm dummies...
  7898.             if (oldSkill.triggerAnotherSkill())
  7899.             {
  7900.                 if (Config.DEBUG)
  7901.                     LOGGER.info("Removing Triggherable Skill: " + oldSkill.getTriggeredId());
  7902.                 removeSkill(oldSkill.getTriggeredId(), true);
  7903.                 _triggeredSkills.remove(oldSkill.getTriggeredId());
  7904.             }
  7905.            
  7906.             // Stop casting if this skill is used right now
  7907.             if (getLastSkillCast() != null && isCastingNow())
  7908.             {
  7909.                 if (oldSkill.getId() == getLastSkillCast().getId())
  7910.                 {
  7911.                     abortCast();
  7912.                 }
  7913.             }
  7914.            
  7915.             if (cancelEffect || oldSkill.isToggle())
  7916.             {
  7917.                 final L2Effect e = getFirstEffect(oldSkill);
  7918.                 if (e == null)
  7919.                 {
  7920.                     removeStatsOwner(oldSkill);
  7921.                     stopSkillEffects(oldSkill.getId());
  7922.                 }
  7923.             }
  7924.            
  7925.             if (oldSkill.isChance() && _chanceSkills != null)
  7926.             {
  7927.                 removeChanceSkill(oldSkill.getId());
  7928.             }
  7929.             removeStatsOwner(oldSkill);
  7930.         }
  7931.         return oldSkill;
  7932.     }
  7933.    
  7934.     /**
  7935.      * Return all skills own by the L2Character in a table of L2Skill.<BR>
  7936.      * <BR>
  7937.      * <B><U> Concept</U> :</B><BR>
  7938.      * <BR>
  7939.      * All skills own by a L2Character are identified in <B>_skills</B> the L2Character <BR>
  7940.      * <BR>
  7941.      * @return the all skills
  7942.      */
  7943.     public final L2Skill[] getAllSkills()
  7944.     {
  7945.         return _skills.values().toArray(new L2Skill[_skills.values().size()]);
  7946.     }
  7947.    
  7948.     /**
  7949.      * @return the map containing this character skills.
  7950.      */
  7951.     @Override
  7952.     public Map<Integer, L2Skill> getSkills()
  7953.     {
  7954.         return _skills;
  7955.     }
  7956.    
  7957.     /**
  7958.      * Gets the chance skills.
  7959.      * @return the chance skills
  7960.      */
  7961.     public ChanceSkillList getChanceSkills()
  7962.     {
  7963.         return _chanceSkills;
  7964.     }
  7965.    
  7966.     /**
  7967.      * Return the level of a skill owned by the L2Character.<BR>
  7968.      * <BR>
  7969.      * @param skillId The identifier of the L2Skill whose level must be returned
  7970.      * @return The level of the L2Skill identified by skillId
  7971.      */
  7972.     @Override
  7973.     public int getSkillLevel(final int skillId)
  7974.     {
  7975.         final L2Skill skill = _skills.get(skillId);
  7976.        
  7977.         if (skill == null)
  7978.             return -1;
  7979.        
  7980.         return skill.getLevel();
  7981.     }
  7982.    
  7983.     /**
  7984.      * Return True if the skill is known by the L2Character.<BR>
  7985.      * <BR>
  7986.      * @param skillId The identifier of the L2Skill to check the knowledge
  7987.      * @return the known skill
  7988.      */
  7989.     @Override
  7990.     public final L2Skill getKnownSkill(final int skillId)
  7991.     {
  7992.         return _skills.get(skillId);
  7993.     }
  7994.    
  7995.     /**
  7996.      * Return the number of skills of type(Buff, Debuff, HEAL_PERCENT, MANAHEAL_PERCENT) affecting this L2Character.<BR>
  7997.      * <BR>
  7998.      * @return The number of Buffs affecting this L2Character
  7999.      */
  8000.     public int getBuffCount()
  8001.     {
  8002.         final L2Effect[] effects = getAllEffects();
  8003.        
  8004.         int numBuffs = 0;
  8005.        
  8006.         for (final L2Effect e : effects)
  8007.         {
  8008.             if (e == null)
  8009.             {
  8010.                 synchronized (_effects)
  8011.                 {
  8012.                     _effects.remove(e);
  8013.                 }
  8014.                 continue;
  8015.             }
  8016.            
  8017.             if ((e.getSkill().getSkillType() == L2Skill.SkillType.BUFF || e.getSkill().getId() == 1416 || e.getSkill().getSkillType() == L2Skill.SkillType.REFLECT || e.getSkill().getSkillType() == L2Skill.SkillType.HEAL_PERCENT || e.getSkill().getSkillType() == L2Skill.SkillType.MANAHEAL_PERCENT) && !(e.getSkill().getId() > 4360 && e.getSkill().getId() < 4367)) // 7s
  8018.             // buffs
  8019.             {
  8020.                 numBuffs++;
  8021.             }
  8022.         }
  8023.        
  8024.         return numBuffs;
  8025.     }
  8026.    
  8027.     /**
  8028.      * Return the number of skills of type(Debuff, poison, slow, etc.) affecting this L2Character.<BR>
  8029.      * <BR>
  8030.      * @return The number of debuff affecting this L2Character
  8031.      */
  8032.     public int getDeBuffCount()
  8033.     {
  8034.         final L2Effect[] effects = getAllEffects();
  8035.         int numDeBuffs = 0;
  8036.        
  8037.         for (final L2Effect e : effects)
  8038.         {
  8039.             if (e == null)
  8040.             {
  8041.                 synchronized (_effects)
  8042.                 {
  8043.                     _effects.remove(e);
  8044.                 }
  8045.                 continue;
  8046.             }
  8047.            
  8048.             // Check for all debuff skills
  8049.             if (e.getSkill().is_Debuff())
  8050.             {
  8051.                 numDeBuffs++;
  8052.             }
  8053.         }
  8054.        
  8055.         return numDeBuffs;
  8056.     }
  8057.    
  8058.     /**
  8059.      * Gets the max buff count.
  8060.      * @return the max buff count
  8061.      */
  8062.     public int getMaxBuffCount()
  8063.     {
  8064.         return Config.BUFFS_MAX_AMOUNT + Math.max(0, getSkillLevel(L2Skill.SKILL_DIVINE_INSPIRATION));
  8065.     }
  8066.    
  8067.     /**
  8068.      * Removes the first Buff of this L2Character.<BR>
  8069.      * <BR>
  8070.      * @param preferSkill If != 0 the given skill Id will be removed instead of first
  8071.      */
  8072.     public void removeFirstBuff(final int preferSkill)
  8073.     {
  8074.         final L2Effect[] effects = getAllEffects();
  8075.        
  8076.         L2Effect removeMe = null;
  8077.        
  8078.         for (final L2Effect e : effects)
  8079.         {
  8080.             if (e == null)
  8081.             {
  8082.                 synchronized (_effects)
  8083.                 {
  8084.                     _effects.remove(e);
  8085.                 }
  8086.                 continue;
  8087.             }
  8088.            
  8089.             if ((e.getSkill().getSkillType() == L2Skill.SkillType.BUFF || e.getSkill().getSkillType() == L2Skill.SkillType.REFLECT || e.getSkill().getSkillType() == L2Skill.SkillType.HEAL_PERCENT || e.getSkill().getSkillType() == L2Skill.SkillType.MANAHEAL_PERCENT) && !(e.getSkill().getId() > 4360 && e.getSkill().getId() < 4367))
  8090.             {
  8091.                 if (preferSkill == 0)
  8092.                 {
  8093.                     removeMe = e;
  8094.                     break;
  8095.                 }
  8096.                 else if (e.getSkill().getId() == preferSkill)
  8097.                 {
  8098.                     removeMe = e;
  8099.                     break;
  8100.                 }
  8101.                 else if (removeMe == null)
  8102.                 {
  8103.                     removeMe = e;
  8104.                 }
  8105.             }
  8106.         }
  8107.        
  8108.         if (removeMe != null)
  8109.         {
  8110.             removeMe.exit(true);
  8111.         }
  8112.     }
  8113.  
  8114.     /**
  8115.      * Removes the first DeBuff of this L2Character.<BR>
  8116.      * <BR>
  8117.      * @param preferSkill If != 0 the given skill Id will be removed instead of first
  8118.      */
  8119.     public void removeFirstDeBuff(final int preferSkill)
  8120.     {
  8121.         final L2Effect[] effects = getAllEffects();
  8122.        
  8123.         L2Effect removeMe = null;
  8124.        
  8125.         for (final L2Effect e : effects)
  8126.         {
  8127.             if (e == null)
  8128.             {
  8129.                
  8130.                 synchronized (_effects)
  8131.                 {
  8132.                     _effects.remove(e);
  8133.                 }
  8134.                 continue;
  8135.             }
  8136.            
  8137.             if (e.getSkill().is_Debuff())
  8138.             {
  8139.                 if (preferSkill == 0)
  8140.                 {
  8141.                     removeMe = e;
  8142.                     break;
  8143.                 }
  8144.                 else if (e.getSkill().getId() == preferSkill)
  8145.                 {
  8146.                     removeMe = e;
  8147.                     break;
  8148.                 }
  8149.                 else if (removeMe == null)
  8150.                 {
  8151.                     removeMe = e;
  8152.                 }
  8153.             }
  8154.         }
  8155.        
  8156.         if (removeMe != null)
  8157.         {
  8158.             removeMe.exit(true);
  8159.         }
  8160.     }
  8161.    
  8162.     /**
  8163.      * Gets the dance count.
  8164.      * @return the dance count
  8165.      */
  8166.     public int getDanceCount()
  8167.     {
  8168.         int danceCount = 0;
  8169.        
  8170.         final L2Effect[] effects = getAllEffects();
  8171.        
  8172.         for (final L2Effect e : effects)
  8173.         {
  8174.             if (e == null)
  8175.             {
  8176.                 synchronized (_effects)
  8177.                 {
  8178.                     _effects.remove(e);
  8179.                 }
  8180.                 continue;
  8181.             }
  8182.            
  8183.             if (e.getSkill().isDance() && e.getInUse())
  8184.             {
  8185.                 danceCount++;
  8186.             }
  8187.         }
  8188.        
  8189.         return danceCount;
  8190.     }
  8191.    
  8192.     /**
  8193.      * Checks if the given skill stacks with an existing one.<BR>
  8194.      * <BR>
  8195.      * @param checkSkill the skill to be checked
  8196.      * @return Returns whether or not this skill will stack
  8197.      */
  8198.     public boolean doesStack(final L2Skill checkSkill)
  8199.     {
  8200.         if (_effects.size() < 1 || checkSkill._effectTemplates == null || checkSkill._effectTemplates.length < 1 || checkSkill._effectTemplates[0].stackType == null)
  8201.             return false;
  8202.        
  8203.         final String stackType = checkSkill._effectTemplates[0].stackType;
  8204.        
  8205.         if (stackType.equals("none"))
  8206.             return false;
  8207.        
  8208.         final L2Effect[] effects = getAllEffects();
  8209.        
  8210.         for (final L2Effect e : effects)
  8211.         {
  8212.             if (e == null)
  8213.             {
  8214.                 synchronized (_effects)
  8215.                 {
  8216.                     _effects.remove(e);
  8217.                 }
  8218.                 continue;
  8219.             }
  8220.            
  8221.             if (e.getStackType() != null && e.getStackType().equals(stackType))
  8222.                 return true;
  8223.         }
  8224.        
  8225.         return false;
  8226.     }
  8227.    
  8228.     /**
  8229.      * Manage the magic skill launching task (MP, HP, Item consummation...) and display the magic skill animation on client.<BR>
  8230.      * <BR>
  8231.      * <B><U> Actions</U> :</B><BR>
  8232.      * <BR>
  8233.      * <li>Send a Server->Client packet MagicSkillLaunched (to display magic skill animation) to all L2PcInstance of L2Charcater _knownPlayers</li> <li>Consumme MP, HP and Item if necessary</li> <li>Send a Server->Client packet StatusUpdate with MP modification to the L2PcInstance</li> <li>Launch
  8234.      * the magic skill in order to calculate its effects</li> <li>If the skill type is PDAM, notify the AI of the target with AI_INTENTION_ATTACK</li> <li>Notify the AI of the L2Character with EVT_FINISH_CASTING</li><BR>
  8235.      * <BR>
  8236.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : A magic skill casting MUST BE in progress</B></FONT><BR>
  8237.      * <BR>
  8238.      * @param targets the targets
  8239.      * @param skill The L2Skill to use
  8240.      * @param coolTime the cool time
  8241.      * @param instant the instant
  8242.      */
  8243.     public void onMagicLaunchedTimer(final L2Object[] targets, final L2Skill skill, final int coolTime, final boolean instant)
  8244.     {
  8245.         if (skill == null || (targets == null || targets.length <= 0) && skill.getTargetType() != SkillTargetType.TARGET_AURA)
  8246.         {
  8247.             _skillCast = null;
  8248.             enableAllSkills();
  8249.             getAI().notifyEvent(CtrlEvent.EVT_CANCEL);
  8250.            
  8251.             return;
  8252.         }
  8253.        
  8254.         // Escaping from under skill's radius and peace zone check. First version, not perfect in AoE skills.
  8255.         int escapeRange = 0;
  8256.        
  8257.         if (skill.getEffectRange() > escapeRange)
  8258.         {
  8259.             escapeRange = skill.getEffectRange();
  8260.         }
  8261.         else if (skill.getCastRange() < 0 && skill.getSkillRadius() > 80)
  8262.         {
  8263.             escapeRange = skill.getSkillRadius();
  8264.         }
  8265.        
  8266.         L2Object[] final_targets = null;
  8267.         int _skipped = 0;
  8268.        
  8269.         if (escapeRange > 0)
  8270.         {
  8271.             List<L2Character> targetList = new FastList<>();
  8272.            
  8273.             for (int i = 0; targets != null && i < targets.length; i++)
  8274.             {
  8275.                 if (targets[i] instanceof L2Character)
  8276.                 {
  8277.                     if (!Util.checkIfInRange(escapeRange, this, targets[i], true))
  8278.                     {
  8279.                         continue;
  8280.                     }
  8281.                    
  8282.                     // Check if the target is behind a wall
  8283.                     if (skill.getSkillRadius() > 0 && skill.isOffensive() && Config.GEODATA > 0 && !GeoData.getInstance().canSeeTarget(this, targets[i]))
  8284.                     {
  8285.                         _skipped++;
  8286.                         continue;
  8287.                     }
  8288.                    
  8289.                     if (skill.isOffensive())
  8290.                     {
  8291.                         if (this instanceof L2PcInstance)
  8292.                         {
  8293.                             if (((L2Character) targets[i]).isInsidePeaceZone((L2PcInstance) this))
  8294.                             {
  8295.                                 continue;
  8296.                             }
  8297.                         }
  8298.                         else
  8299.                         {
  8300.                             if (L2Character.isInsidePeaceZone(this, targets[i]))
  8301.                             {
  8302.                                 continue;
  8303.                             }
  8304.                         }
  8305.                     }
  8306.                     targetList.add((L2Character) targets[i]);
  8307.                 }
  8308.                 // else
  8309.                 // {
  8310.                 // if (Config.DEBUG)
  8311.                 // LOGGER.warn("Class cast bad: "+targets[i].getClass().toString());
  8312.                 // }
  8313.             }
  8314.             if (targetList.isEmpty() && skill.getTargetType() != SkillTargetType.TARGET_AURA)
  8315.             {
  8316.                 if (this instanceof L2PcInstance)
  8317.                 {
  8318.                     for (int i = 0; i < _skipped; i++)
  8319.                         sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CANT_SEE_TARGET));
  8320.                    
  8321.                 }
  8322.                
  8323.                 abortCast();
  8324.                 return;
  8325.             }
  8326.             final_targets = targetList.toArray(new L2Character[targetList.size()]);
  8327.             targetList = null;
  8328.            
  8329.         }
  8330.         else
  8331.         {
  8332.            
  8333.             final_targets = targets;
  8334.            
  8335.         }
  8336.        
  8337.         // if the skill is not a potion and player
  8338.         // is not casting now
  8339.         // Ensure that a cast is in progress
  8340.         // Check if player is using fake death.
  8341.         // Potions can be used while faking death.
  8342.         if (!skill.isPotion())
  8343.         {
  8344.             if (!isCastingNow() || isAlikeDead())
  8345.             {
  8346.                 _skillCast = null;
  8347.                 enableAllSkills();
  8348.                
  8349.                 getAI().notifyEvent(CtrlEvent.EVT_CANCEL);
  8350.                
  8351.                 _castEndTime = 0;
  8352.                 _castInterruptTime = 0;
  8353.                 return;
  8354.             }
  8355.         }/*
  8356.          * else{ if(!isCastingPotionNow()) { _potionCast = null; enableAllSkills(); getAI().notifyEvent(CtrlEvent.EVT_CANCEL); _castPotionEndTime = 0; _castPotionInterruptTime = 0; return; } }
  8357.          */
  8358.        
  8359.         // Get the display identifier of the skill
  8360.         final int magicId = skill.getDisplayId();
  8361.        
  8362.         // Get the level of the skill
  8363.         int level = getSkillLevel(skill.getId());
  8364.        
  8365.         if (level < 1)
  8366.         {
  8367.             level = 1;
  8368.         }
  8369.        
  8370.         // Send a Server->Client packet MagicSkillLaunched to the L2Character AND to all L2PcInstance in the _KnownPlayers of the L2Character
  8371.         if (!skill.isPotion())
  8372.         {
  8373.             broadcastPacket(new MagicSkillLaunched(this, magicId, level, final_targets));
  8374.         }
  8375.        
  8376.         if (instant)
  8377.         {
  8378.             onMagicHitTimer(final_targets, skill, coolTime, true);
  8379.         }
  8380.         else
  8381.         {
  8382.             if (skill.isPotion())
  8383.                 _potionCast = ThreadPoolManager.getInstance().scheduleEffect(new MagicUseTask(final_targets, skill, coolTime, 2), 200);
  8384.             else
  8385.                 _skillCast = ThreadPoolManager.getInstance().scheduleEffect(new MagicUseTask(final_targets, skill, coolTime, 2), 200);
  8386.            
  8387.         }
  8388.        
  8389.     }
  8390.    
  8391.     /*
  8392.      * Runs in the end of skill casting
  8393.      */
  8394.     /**
  8395.      * On magic hit timer.
  8396.      * @param targets the targets
  8397.      * @param skill the skill
  8398.      * @param coolTime the cool time
  8399.      * @param instant the instant
  8400.      */
  8401.     public void onMagicHitTimer(final L2Object[] targets, final L2Skill skill, final int coolTime, final boolean instant)
  8402.     {
  8403.         if (skill == null || (targets == null || targets.length <= 0) && skill.getTargetType() != SkillTargetType.TARGET_AURA)
  8404.         {
  8405.             _skillCast = null;
  8406.             enableAllSkills();
  8407.             getAI().notifyEvent(CtrlEvent.EVT_CANCEL);
  8408.            
  8409.             return;
  8410.         }
  8411.        
  8412.         if (getForceBuff() != null)
  8413.         {
  8414.             _skillCast = null;
  8415.             enableAllSkills();
  8416.            
  8417.             getForceBuff().onCastAbort();
  8418.            
  8419.             return;
  8420.         }
  8421.        
  8422.         final L2Effect mog = getFirstEffect(L2Effect.EffectType.SIGNET_GROUND);
  8423.         if (mog != null)
  8424.         {
  8425.             _skillCast = null;
  8426.             enableAllSkills();
  8427.            
  8428.             // close skill if it's not SIGNET_CASTTIME
  8429.             if (mog.getSkill().getSkillType() != SkillType.SIGNET_CASTTIME)
  8430.             {
  8431.                 mog.exit(true);
  8432.             }
  8433.            
  8434.             final L2Object target = targets == null ? null : targets[0];
  8435.             if (target != null)
  8436.             {
  8437.                 notifyQuestEventSkillFinished(skill, target);
  8438.             }
  8439.             return;
  8440.         }
  8441.        
  8442.         final L2Object[] targets2 = targets;
  8443.         try
  8444.         {
  8445.             if (targets2 != null && targets2.length != 0)
  8446.             {
  8447.                
  8448.                 // Go through targets table
  8449.                 for (final L2Object target2 : targets2)
  8450.                 {
  8451.                     if (target2 == null)
  8452.                     {
  8453.                         continue;
  8454.                     }
  8455.                    
  8456.                     if (target2 instanceof L2PlayableInstance)
  8457.                     {
  8458.                         L2Character target = (L2Character) target2;
  8459.                        
  8460.                         // If the skill is type STEALTH(ex: Dance of Shadow)
  8461.                         if (skill.isAbnormalEffectByName(ABNORMAL_EFFECT_STEALTH))
  8462.                         {
  8463.                             final L2Effect silentMove = target.getFirstEffect(L2Effect.EffectType.SILENT_MOVE);
  8464.                             if (silentMove != null)
  8465.                                 silentMove.exit(true);
  8466.                         }
  8467.                        
  8468.                         if (skill.getSkillType() == SkillType.BUFF || skill.getSkillType() == SkillType.SEED)
  8469.                         {
  8470.                             SystemMessage smsg = new SystemMessage(SystemMessageId.YOU_FEEL_S1_EFFECT);
  8471.                             smsg.addString(skill.getName());
  8472.                             target.sendPacket(smsg);
  8473.                             smsg = null;
  8474.                         }
  8475.                        
  8476.                         if (this instanceof L2PcInstance && target instanceof L2Summon)
  8477.                         {
  8478.                             ((L2Summon) target).getOwner().sendPacket(new PetInfo((L2Summon) target));
  8479.                             sendPacket(new NpcInfo((L2Summon) target, this));
  8480.                            
  8481.                             // The PetInfo packet wipes the PartySpelled (list of active spells' icons). Re-add them
  8482.                             ((L2Summon) target).updateEffectIcons(true);
  8483.                         }
  8484.                        
  8485.                         target = null;
  8486.                     }
  8487.                 }
  8488.                
  8489.             }
  8490.            
  8491.         }
  8492.         catch (final Exception e)
  8493.         {
  8494.             e.printStackTrace();
  8495.         }
  8496.        
  8497.         try
  8498.         {
  8499.            
  8500.             StatusUpdate su = new StatusUpdate(getObjectId());
  8501.             boolean isSendStatus = false;
  8502.            
  8503.             // Consume MP of the L2Character and Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform
  8504.             final double mpConsume = getStat().getMpConsume(skill);
  8505.            
  8506.             if (mpConsume > 0)
  8507.             {
  8508.                 if (skill.isDance())
  8509.                 {
  8510.                     getStatus().reduceMp(calcStat(Stats.DANCE_MP_CONSUME_RATE, mpConsume, null, null));
  8511.                 }
  8512.                 else if (skill.isMagic())
  8513.                 {
  8514.                     getStatus().reduceMp(calcStat(Stats.MAGICAL_MP_CONSUME_RATE, mpConsume, null, null));
  8515.                 }
  8516.                 else
  8517.                 {
  8518.                     getStatus().reduceMp(calcStat(Stats.PHYSICAL_MP_CONSUME_RATE, mpConsume, null, null));
  8519.                 }
  8520.                
  8521.                 su.addAttribute(StatusUpdate.CUR_MP, (int) getCurrentMp());
  8522.                 isSendStatus = true;
  8523.             }
  8524.            
  8525.             // Consume HP if necessary and Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform
  8526.             if (skill.getHpConsume() > 0)
  8527.             {
  8528.                 double consumeHp;
  8529.                
  8530.                 consumeHp = calcStat(Stats.HP_CONSUME_RATE, skill.getHpConsume(), null, null);
  8531.                
  8532.                 if (consumeHp + 1 >= getCurrentHp())
  8533.                 {
  8534.                     consumeHp = getCurrentHp() - 1.0;
  8535.                 }
  8536.                
  8537.                 getStatus().reduceHp(consumeHp, this);
  8538.                
  8539.                 su.addAttribute(StatusUpdate.CUR_HP, (int) getCurrentHp());
  8540.                 isSendStatus = true;
  8541.             }
  8542.            
  8543.             // Send a Server->Client packet StatusUpdate with MP modification to the L2PcInstance
  8544.             if (isSendStatus)
  8545.             {
  8546.                 sendPacket(su);
  8547.             }
  8548.            
  8549.             // Consume Items if necessary and Send the Server->Client packet InventoryUpdate with Item modification to all the L2Character
  8550.             if (skill.getItemConsume() > 0)
  8551.             {
  8552.                 consumeItem(skill.getItemConsumeId(), skill.getItemConsume());
  8553.             }
  8554.            
  8555.             // Launch the magic skill in order to calculate its effects
  8556.             callSkill(skill, targets);
  8557.            
  8558.             su = null;
  8559.            
  8560.         }
  8561.         catch (final Exception e)
  8562.         {
  8563.             e.printStackTrace();
  8564.         }
  8565.        
  8566.         if (instant || coolTime == 0)
  8567.         {
  8568.            
  8569.             onMagicFinalizer(targets, skill);
  8570.            
  8571.         }
  8572.         else
  8573.         {
  8574.             if (skill.isPotion())
  8575.                 _potionCast = ThreadPoolManager.getInstance().scheduleEffect(new MagicUseTask(targets, skill, coolTime, 3), coolTime);
  8576.             else
  8577.                 _skillCast = ThreadPoolManager.getInstance().scheduleEffect(new MagicUseTask(targets, skill, coolTime, 3), coolTime);
  8578.            
  8579.         }
  8580.     }
  8581.    
  8582.     /*
  8583.      * Runs after skill hitTime+coolTime
  8584.      */
  8585.     /**
  8586.      * On magic finalizer.
  8587.      * @param targets the targets
  8588.      * @param skill the skill
  8589.      */
  8590.     public void onMagicFinalizer(final L2Object[] targets, final L2Skill skill)
  8591.     {
  8592.         if (skill.isPotion())
  8593.         {
  8594.             _potionCast = null;
  8595.             _castPotionEndTime = 0;
  8596.             _castPotionInterruptTime = 0;
  8597.         }
  8598.         else
  8599.         {
  8600.             _skillCast = null;
  8601.             _castEndTime = 0;
  8602.             _castInterruptTime = 0;
  8603.            
  8604.             enableAllSkills();
  8605.            
  8606.             // if the skill has changed the character's state to something other than STATE_CASTING
  8607.             // then just leave it that way, otherwise switch back to STATE_IDLE.
  8608.             // if(isCastingNow())
  8609.             // getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null);
  8610.             if (skill.getId() != 345 && skill.getId() != 346)
  8611.             {
  8612.                 // Like L2OFF while use a skill and next interntion == null the char stop auto attack
  8613.                 if (getAI().getNextIntention() == null && (skill.getSkillType() == SkillType.PDAM && skill.getCastRange() < 400) || skill.getSkillType() == SkillType.BLOW || skill.getSkillType() == SkillType.DRAIN_SOUL || skill.getSkillType() == SkillType.SOW || skill.getSkillType() == SkillType.SPOIL)
  8614.                 {
  8615.                     if (this instanceof L2PcInstance)
  8616.                     {
  8617.                         final L2PcInstance currPlayer = (L2PcInstance) this;
  8618.                         final SkillDat skilldat = currPlayer.getCurrentSkill();
  8619.                         // Like L2OFF if the skill is BLOW the player doesn't auto attack
  8620.                         // If on XML skill nextActionAttack = true the char auto attack
  8621.                         // If CTRL is pressed the autoattack is aborted (like L2OFF)
  8622.                         if (skilldat != null && !skilldat.isCtrlPressed() && skill.nextActionIsAttack() && getTarget() != null && getTarget() instanceof L2Character)
  8623.                         {
  8624.                             getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, getTarget());
  8625.                         }
  8626.                     }
  8627.                     else
  8628.                     // case NPC
  8629.                     {
  8630.                         if (skill.nextActionIsAttack() && getTarget() != null && getTarget() instanceof L2Character)
  8631.                         {
  8632.                             getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, getTarget());
  8633.                         }
  8634.                         else if ((skill.isOffensive()) && !(skill.getSkillType() == SkillType.UNLOCK) && !(skill.getSkillType() == SkillType.BLOW) && !(skill.getSkillType() == SkillType.DELUXE_KEY_UNLOCK) && skill.getId() != 345 && skill.getId() != 346)
  8635.                         {
  8636.                             getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, getTarget());
  8637.                             getAI().clientStartAutoAttack();
  8638.                         }
  8639.                     }
  8640.                 }
  8641.                 if (this instanceof L2PcInstance)
  8642.                 {
  8643.                     final L2PcInstance currPlayer = (L2PcInstance) this;
  8644.                     final SkillDat skilldat = currPlayer.getCurrentSkill();
  8645.                     if (skilldat != null && !skilldat.isCtrlPressed() && (skill.isOffensive()) && !(skill.getSkillType() == SkillType.UNLOCK) && !(skill.getSkillType() == SkillType.BLOW) && !(skill.getSkillType() == SkillType.DELUXE_KEY_UNLOCK) && skill.getId() != 345 && skill.getId() != 346)
  8646.                     {
  8647.                         if (!skill.isMagic() && skill.nextActionIsAttack())
  8648.                             getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, getTarget());
  8649.                        
  8650.                         getAI().clientStartAutoAttack();
  8651.                     }
  8652.                 }
  8653.                 else
  8654.                 // case npc
  8655.                 {
  8656.                     if ((skill.isOffensive()) && !(skill.getSkillType() == SkillType.UNLOCK) && !(skill.getSkillType() == SkillType.BLOW) && !(skill.getSkillType() == SkillType.DELUXE_KEY_UNLOCK) && skill.getId() != 345 && skill.getId() != 346)
  8657.                     {
  8658.                         if (!skill.isMagic())
  8659.                             getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, getTarget());
  8660.                        
  8661.                         getAI().clientStartAutoAttack();
  8662.                     }
  8663.                 }
  8664.             }
  8665.             else
  8666.             {
  8667.                 getAI().clientStopAutoAttack();
  8668.             }
  8669.            
  8670.             // Notify the AI of the L2Character with EVT_FINISH_CASTING
  8671.             getAI().notifyEvent(CtrlEvent.EVT_FINISH_CASTING);
  8672.            
  8673.             notifyQuestEventSkillFinished(skill, getTarget());
  8674.            
  8675.             /*
  8676.              * If character is a player, then wipe their current cast state and check if a skill is queued. If there is a queued skill, launch it and wipe the queue.
  8677.              */
  8678.             if (this instanceof L2PcInstance)
  8679.             {
  8680.                 L2PcInstance currPlayer = (L2PcInstance) this;
  8681.                 SkillDat queuedSkill = currPlayer.getQueuedSkill();
  8682.                
  8683.                 currPlayer.setCurrentSkill(null, false, false);
  8684.                
  8685.                 if (queuedSkill != null)
  8686.                 {
  8687.                     currPlayer.setQueuedSkill(null, false, false);
  8688.                    
  8689.                     // DON'T USE : Recursive call to useMagic() method
  8690.                     // currPlayer.useMagic(queuedSkill.getSkill(), queuedSkill.isCtrlPressed(), queuedSkill.isShiftPressed());
  8691.                     ThreadPoolManager.getInstance().executeTask(new QueuedMagicUseTask(currPlayer, queuedSkill.getSkill(), queuedSkill.isCtrlPressed(), queuedSkill.isShiftPressed()));
  8692.                 }
  8693.                
  8694.                 queuedSkill = null;
  8695.                
  8696.                 final L2Weapon activeWeapon = getActiveWeaponItem();
  8697.                 // Launch weapon Special ability skill effect if available
  8698.                 if (activeWeapon != null)
  8699.                 {
  8700.                     try
  8701.                     {
  8702.                         if (targets != null && targets.length > 0)
  8703.                         {
  8704.                             for (final L2Object target : targets)
  8705.                             {
  8706.                                 if (target != null && target instanceof L2Character && !((L2Character) target).isDead())
  8707.                                 {
  8708.                                     final L2Character player = (L2Character) target;
  8709.                                    
  8710.                                     if (activeWeapon.getSkillEffects(this, player, skill))
  8711.                                     {
  8712.                                         sendPacket(SystemMessage.sendString("Target affected by weapon special ability!"));
  8713.                                     }
  8714.                                 }
  8715.                                
  8716.                             }
  8717.                         }
  8718.                     }
  8719.                     catch (final Exception e)
  8720.                     {
  8721.                         e.printStackTrace();
  8722.                     }
  8723.                 }
  8724.                
  8725.                 currPlayer = null;
  8726.             }
  8727.         }
  8728.     }
  8729.    
  8730.     // Quest event ON_SPELL_FNISHED
  8731.     /**
  8732.      * Notify quest event skill finished.
  8733.      * @param skill the skill
  8734.      * @param target the target
  8735.      */
  8736.     private void notifyQuestEventSkillFinished(final L2Skill skill, final L2Object target)
  8737.     {
  8738.         if (this instanceof L2NpcInstance && (target instanceof L2PcInstance || target instanceof L2Summon))
  8739.         {
  8740.            
  8741.             final L2PcInstance player = target instanceof L2PcInstance ? (L2PcInstance) target : ((L2Summon) target).getOwner();
  8742.            
  8743.             for (final Quest quest : ((L2NpcTemplate) getTemplate()).getEventQuests(Quest.QuestEventType.ON_SPELL_FINISHED))
  8744.             {
  8745.                 quest.notifySpellFinished(((L2NpcInstance) this), player, skill);
  8746.             }
  8747.         }
  8748.     }
  8749.    
  8750.     /**
  8751.      * Reduce the item number of the L2Character.<BR>
  8752.      * <BR>
  8753.      * <B><U> Overriden in </U> :</B><BR>
  8754.      * <BR>
  8755.      * <li>L2PcInstance</li><BR>
  8756.      * <BR>
  8757.      * @param itemConsumeId the item consume id
  8758.      * @param itemCount the item count
  8759.      */
  8760.     public void consumeItem(final int itemConsumeId, final int itemCount)
  8761.     {
  8762.     }
  8763.    
  8764.     /**
  8765.      * Enable a skill (remove it from _disabledSkills of the L2Character).<BR>
  8766.      * <BR>
  8767.      * <B><U> Concept</U> :</B><BR>
  8768.      * <BR>
  8769.      * All skills disabled are identified by their skillId in <B>_disabledSkills</B> of the L2Character <BR>
  8770.      * <BR>
  8771.      * @param _skill
  8772.      */
  8773.     public void enableSkill(final L2Skill _skill)
  8774.     {
  8775.         if (_disabledSkills == null)
  8776.             return;
  8777.        
  8778.         _disabledSkills.remove(new Integer(_skill.getReuseHashCode()));
  8779.        
  8780.         if (this instanceof L2PcInstance)
  8781.         {
  8782.             removeTimeStamp(_skill);
  8783.         }
  8784.     }
  8785.    
  8786.     /**
  8787.      * Disable a skill (add it to _disabledSkills of the L2Character).<BR>
  8788.      * <BR>
  8789.      * <B><U> Concept</U> :</B><BR>
  8790.      * <BR>
  8791.      * All skills disabled are identified by their skillId in <B>_disabledSkills</B> of the L2Character <BR>
  8792.      * <BR>
  8793.      * @param skill The identifier of the L2Skill to disable
  8794.      */
  8795.     public void disableSkill(final L2Skill skill)
  8796.     {
  8797.         if (_disabledSkills == null)
  8798.         {
  8799.             _disabledSkills = Collections.synchronizedList(new FastList<Integer>());
  8800.         }
  8801.        
  8802.         _disabledSkills.add(skill.getReuseHashCode());
  8803.     }
  8804.    
  8805.     /**
  8806.      * Disable this skill id for the duration of the delay in milliseconds.
  8807.      * @param skill the skill thats going to be disabled
  8808.      * @param delay (seconds * 1000)
  8809.      */
  8810.     public void disableSkill(final L2Skill skill, final long delay)
  8811.     {
  8812.         if (skill == null)
  8813.             return;
  8814.        
  8815.         disableSkill(skill);
  8816.        
  8817.         if (delay > 10)
  8818.         {
  8819.             ThreadPoolManager.getInstance().scheduleAi(new EnableSkill(skill), delay);
  8820.         }
  8821.     }
  8822.    
  8823.     /**
  8824.      * Check if a skill is disabled.<BR>
  8825.      * <BR>
  8826.      * <B><U> Concept</U> :</B><BR>
  8827.      * <BR>
  8828.      * All skills disabled are identified by their skillId in <B>_disabledSkills</B> of the L2Character <BR>
  8829.      * <BR>
  8830.      * @param _skill the skill to know if its disabled
  8831.      * @return true, if is skill disabled
  8832.      */
  8833.     public boolean isSkillDisabled(final L2Skill _skill)
  8834.     {
  8835.         final L2Skill skill = _skill;
  8836.        
  8837.         if (isAllSkillsDisabled() && !skill.isPotion())
  8838.             return true;
  8839.        
  8840.         if (this instanceof L2PcInstance)
  8841.         {
  8842.             final L2PcInstance activeChar = (L2PcInstance) this;
  8843.            
  8844.             if ((skill.getSkillType() == SkillType.FISHING || skill.getSkillType() == SkillType.REELING || skill.getSkillType() == SkillType.PUMPING) && !activeChar.isFishing() && (activeChar.getActiveWeaponItem() != null && activeChar.getActiveWeaponItem().getItemType() != L2WeaponType.ROD))
  8845.             {
  8846.                 if (skill.getSkillType() == SkillType.PUMPING)
  8847.                 {
  8848.                     // Pumping skill is available only while fishing
  8849.                     activeChar.sendPacket(new SystemMessage(SystemMessageId.CAN_USE_PUMPING_ONLY_WHILE_FISHING));
  8850.                 }
  8851.                 else if (skill.getSkillType() == SkillType.REELING)
  8852.                 {
  8853.                     // Reeling skill is available only while fishing
  8854.                     activeChar.sendPacket(new SystemMessage(SystemMessageId.CAN_USE_REELING_ONLY_WHILE_FISHING));
  8855.                 }
  8856.                 else if (skill.getSkillType() == SkillType.FISHING)
  8857.                 {
  8858.                     // Player hasn't fishing pole equiped
  8859.                     activeChar.sendPacket(new SystemMessage(SystemMessageId.FISHING_POLE_NOT_EQUIPPED));
  8860.                 }
  8861.                
  8862.                 final SystemMessage sm = new SystemMessage(SystemMessageId.S1_CANNOT_BE_USED);
  8863.                 sm.addString(skill.getName());
  8864.                 activeChar.sendPacket(sm);
  8865.                 return true;
  8866.             }
  8867.            
  8868.             if ((skill.getSkillType() == SkillType.FISHING || skill.getSkillType() == SkillType.REELING || skill.getSkillType() == SkillType.PUMPING) && activeChar.getActiveWeaponItem() == null)
  8869.             {
  8870.                 final SystemMessage sm = new SystemMessage(SystemMessageId.S1_CANNOT_BE_USED);
  8871.                 sm.addString(skill.getName());
  8872.                 activeChar.sendPacket(sm);
  8873.                 return true;
  8874.             }
  8875.            
  8876.             if ((skill.getSkillType() == SkillType.REELING || skill.getSkillType() == SkillType.PUMPING) && !activeChar.isFishing() && (activeChar.getActiveWeaponItem() != null && activeChar.getActiveWeaponItem().getItemType() == L2WeaponType.ROD))
  8877.             {
  8878.                 if (skill.getSkillType() == SkillType.PUMPING)
  8879.                 {
  8880.                     // Pumping skill is available only while fishing
  8881.                     activeChar.sendPacket(new SystemMessage(SystemMessageId.CAN_USE_PUMPING_ONLY_WHILE_FISHING));
  8882.                 }
  8883.                 else if (skill.getSkillType() == SkillType.REELING)
  8884.                 {
  8885.                     // Reeling skill is available only while fishing
  8886.                     activeChar.sendPacket(new SystemMessage(SystemMessageId.CAN_USE_REELING_ONLY_WHILE_FISHING));
  8887.                 }
  8888.                
  8889.                 final SystemMessage sm = new SystemMessage(SystemMessageId.S1_CANNOT_BE_USED);
  8890.                 sm.addString(skill.getName());
  8891.                 activeChar.sendPacket(sm);
  8892.                 return true;
  8893.             }
  8894.            
  8895.             if (activeChar.isHero() && HeroSkillTable.isHeroSkill(_skill.getId()) && activeChar.isInOlympiadMode() && activeChar.isOlympiadStart())
  8896.             {
  8897.                 activeChar.sendMessage("You can't use Hero skills during Olympiad match.");
  8898.                 return true;
  8899.             }
  8900.         }
  8901.        
  8902.         if (_disabledSkills == null)
  8903.             return false;
  8904.        
  8905.         return _disabledSkills.contains(_skill.getReuseHashCode());
  8906.     }
  8907.    
  8908.     /**
  8909.      * Disable all skills (set _allSkillsDisabled to True).<BR>
  8910.      * <BR>
  8911.      */
  8912.     public void disableAllSkills()
  8913.     {
  8914.         if (Config.DEBUG)
  8915.         {
  8916.             LOGGER.debug("All skills disabled");
  8917.         }
  8918.        
  8919.         _allSkillsDisabled = true;
  8920.     }
  8921.    
  8922.     /**
  8923.      * Enable all skills (set _allSkillsDisabled to False).<BR>
  8924.      * <BR>
  8925.      */
  8926.     public void enableAllSkills()
  8927.     {
  8928.         if (Config.DEBUG)
  8929.         {
  8930.             LOGGER.debug("All skills enabled");
  8931.         }
  8932.        
  8933.         _allSkillsDisabled = false;
  8934.     }
  8935.    
  8936.     /**
  8937.      * Launch the magic skill and calculate its effects on each target contained in the targets table.<BR>
  8938.      * <BR>
  8939.      * @param skill The L2Skill to use
  8940.      * @param targets The table of L2Object targets
  8941.      */
  8942.     public void callSkill(final L2Skill skill, final L2Object[] targets)
  8943.     {
  8944.         try
  8945.         {
  8946.             if (skill.isToggle() && getFirstEffect(skill.getId()) != null)
  8947.                 return;
  8948.            
  8949.             if (targets == null || targets.length == 0)
  8950.             {
  8951.                 getAI().notifyEvent(CtrlEvent.EVT_CANCEL);
  8952.                 return;
  8953.             }
  8954.            
  8955.             // Do initial checkings for skills and set pvp flag/draw aggro when needed
  8956.             for (final L2Object target : targets)
  8957.             {
  8958.                 if (target instanceof L2Character)
  8959.                 {
  8960.                     // Set some values inside target's instance for later use
  8961.                     L2Character player = (L2Character) target;
  8962.                    
  8963.                     if (skill.getEffectType() == L2Skill.SkillType.BUFF)
  8964.                         if (player.isBlockBuff())
  8965.                             continue;
  8966.                    
  8967.                     /*
  8968.                      * LOGGER.info("--"+skill.getId()); L2Weapon activeWeapon = getActiveWeaponItem(); // Launch weapon Special ability skill effect if available if(activeWeapon != null && !((L2Character) target).isDead()) { if(activeWeapon.getSkillEffects(this, player, skill).length > 0 && this
  8969.                      * instanceof L2PcInstance) { sendPacket(SystemMessage.sendString("Target affected by weapon special ability!")); } }
  8970.                      */
  8971.                    
  8972.                     if (target instanceof L2Character)
  8973.                     {
  8974.                         final L2Character targ = (L2Character) target;
  8975.                        
  8976.                         if (ChanceSkillList.canTriggerByCast(this, targ, skill))
  8977.                         {
  8978.                             // Maybe launch chance skills on us
  8979.                             if (_chanceSkills != null)
  8980.                             {
  8981.                                 _chanceSkills.onSkillHit(targ, false, skill.isMagic(), skill.isOffensive());
  8982.                             }
  8983.                             // Maybe launch chance skills on target
  8984.                             if (targ.getChanceSkills() != null)
  8985.                             {
  8986.                                 targ.getChanceSkills().onSkillHit(this, true, skill.isMagic(), skill.isOffensive());
  8987.                             }
  8988.                         }
  8989.                     }
  8990.                    
  8991.                     if (Config.ALLOW_RAID_BOSS_PETRIFIED && (this instanceof L2PcInstance || this instanceof L2Summon)) // Check if option is True Or False.
  8992.                     {
  8993.                         boolean to_be_cursed = false;
  8994.                        
  8995.                         // check on BossZone raid lvl
  8996.                         if (!(player.getTarget() instanceof L2PlayableInstance) && !(player.getTarget() instanceof L2SummonInstance))
  8997.                         { // this must work just on mobs/raids
  8998.                        
  8999.                             if ((player.isRaid() && getLevel() > player.getLevel() + 8) || (!(player instanceof L2PcInstance) && (player.getTarget() != null && player.getTarget() instanceof L2RaidBossInstance && getLevel() > ((L2RaidBossInstance) player.getTarget()).getLevel() + 8)) || (!(player instanceof L2PcInstance) && (player.getTarget() != null && player.getTarget() instanceof L2GrandBossInstance && getLevel() > ((L2GrandBossInstance) player.getTarget()).getLevel() + 8)))
  9000.                             {
  9001.                                 to_be_cursed = true;
  9002.                             }
  9003.                            
  9004.                             // advanced check too if not already cursed
  9005.                             if (!to_be_cursed)
  9006.                             {
  9007.                                 int boss_id = -1;
  9008.                                 L2NpcTemplate boss_template = null;
  9009.                                 final L2BossZone boss_zone = GrandBossManager.getInstance().getZone(this);
  9010.                                
  9011.                                 if (boss_zone != null)
  9012.                                 {
  9013.                                     boss_id = boss_zone.getBossId();
  9014.                                 }
  9015.                                
  9016.                                 // boolean alive = false;
  9017.                                
  9018.                                 if (boss_id != -1)
  9019.                                 {
  9020.                                     boss_template = NpcTable.getInstance().getTemplate(boss_id);
  9021.                                    
  9022.                                     if (boss_template != null && getLevel() > boss_template.getLevel() + 8)
  9023.                                     {
  9024.                                         L2MonsterInstance boss_instance = null;
  9025.                                        
  9026.                                         if (boss_template.type.equals("L2RaidBoss"))
  9027.                                         {
  9028.                                             final StatsSet actual_boss_stat = RaidBossSpawnManager.getInstance().getStatsSet(boss_id);
  9029.                                             if (actual_boss_stat != null)
  9030.                                             {
  9031.                                                 // alive = actual_boss_stat.getLong("respawnTime") == 0;
  9032.                                                 boss_instance = RaidBossSpawnManager.getInstance().getBoss(boss_id);
  9033.                                             }
  9034.                                         }
  9035.                                         else if (boss_template.type.equals("L2GrandBoss"))
  9036.                                         {
  9037.                                             final StatsSet actual_boss_stat = GrandBossManager.getInstance().getStatsSet(boss_id);
  9038.                                             if (actual_boss_stat != null)
  9039.                                             {
  9040.                                                 // alive = actual_boss_stat.getLong("respawn_time") == 0;
  9041.                                                 boss_instance = GrandBossManager.getInstance().getBoss(boss_id);
  9042.                                             }
  9043.                                         }
  9044.                                        
  9045.                                         // max allowed rage into take cursed is 3000
  9046.                                         if (boss_instance != null/* && alive */&& boss_instance.isInsideRadius(this, 3000, false, false))
  9047.                                         {
  9048.                                             to_be_cursed = true;
  9049.                                         }
  9050.                                     }
  9051.                                 }
  9052.                             }
  9053.                         }
  9054.                        
  9055.                         if (to_be_cursed)
  9056.                         {
  9057.                             if (skill.isMagic())
  9058.                             {
  9059.                                 L2Skill tempSkill = SkillTable.getInstance().getInfo(4215, 1);
  9060.                                 if (tempSkill != null)
  9061.                                 {
  9062.                                     abortAttack();
  9063.                                     abortCast();
  9064.                                     getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  9065.                                     tempSkill.getEffects(player, this, false, false, false);
  9066.                                    
  9067.                                     if (this instanceof L2Summon)
  9068.                                     {
  9069.                                        
  9070.                                         final L2Summon src = ((L2Summon) this);
  9071.                                         if (src.getOwner() != null)
  9072.                                         {
  9073.                                             src.getOwner().abortAttack();
  9074.                                             src.getOwner().abortCast();
  9075.                                             src.getOwner().getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  9076.                                             tempSkill.getEffects(player, src.getOwner(), false, false, false);
  9077.                                         }
  9078.                                     }
  9079.                                    
  9080.                                 }
  9081.                                 else
  9082.                                     LOGGER.warn("Skill 4215 at level 1 is missing in DP.");
  9083.                                
  9084.                                 tempSkill = null;
  9085.                             }
  9086.                             else
  9087.                             {
  9088.                                 L2Skill tempSkill = SkillTable.getInstance().getInfo(4515, 1);
  9089.                                 if (tempSkill != null)
  9090.                                 {
  9091.                                     tempSkill.getEffects(player, this, false, false, false);
  9092.                                 }
  9093.                                 else
  9094.                                 {
  9095.                                     LOGGER.warn("Skill 4515 at level 1 is missing in DP.");
  9096.                                 }
  9097.                                
  9098.                                 tempSkill = null;
  9099.                                
  9100.                                 if (player instanceof L2MinionInstance)
  9101.                                 {
  9102.                                     ((L2MinionInstance) player).getLeader().stopHating(this);
  9103.                                     List<L2MinionInstance> spawnedMinions = ((L2MonsterInstance) player).getSpawnedMinions();
  9104.                                     if (spawnedMinions != null && spawnedMinions.size() > 0)
  9105.                                     {
  9106.                                         Iterator<L2MinionInstance> itr = spawnedMinions.iterator();
  9107.                                         L2MinionInstance minion;
  9108.                                         while (itr.hasNext())
  9109.                                         {
  9110.                                             minion = itr.next();
  9111.                                             if (((L2Attackable) player).getMostHated() == null)
  9112.                                             {
  9113.                                                 ((L2AttackableAI) minion.getAI()).setGlobalAggro(-25);
  9114.                                                 minion.clearAggroList();
  9115.                                                 minion.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  9116.                                                 minion.setWalking();
  9117.                                             }
  9118.                                             if (minion != null && !minion.isDead())
  9119.                                             {
  9120.                                                 ((L2AttackableAI) minion.getAI()).setGlobalAggro(-25);
  9121.                                                 minion.clearAggroList();
  9122.                                                 minion.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  9123.                                                 minion.addDamage(((L2Attackable) player).getMostHated(), 100);
  9124.                                             }
  9125.                                         }
  9126.                                         itr = null;
  9127.                                         spawnedMinions = null;
  9128.                                         minion = null;
  9129.                                     }
  9130.                                 }
  9131.                                 else
  9132.                                 {
  9133.                                     ((L2Attackable) player).stopHating(this);
  9134.                                     List<L2MinionInstance> spawnedMinions = ((L2MonsterInstance) player).getSpawnedMinions();
  9135.                                     if (spawnedMinions != null && spawnedMinions.size() > 0)
  9136.                                     {
  9137.                                         Iterator<L2MinionInstance> itr = spawnedMinions.iterator();
  9138.                                         L2MinionInstance minion;
  9139.                                         while (itr.hasNext())
  9140.                                         {
  9141.                                             minion = itr.next();
  9142.                                             if (((L2Attackable) player).getMostHated() == null)
  9143.                                             {
  9144.                                                 ((L2AttackableAI) minion.getAI()).setGlobalAggro(-25);
  9145.                                                 minion.clearAggroList();
  9146.                                                 minion.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  9147.                                                 minion.setWalking();
  9148.                                             }
  9149.                                             if (minion != null && !minion.isDead())
  9150.                                             {
  9151.                                                 ((L2AttackableAI) minion.getAI()).setGlobalAggro(-25);
  9152.                                                 minion.clearAggroList();
  9153.                                                 minion.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  9154.                                                 minion.addDamage(((L2Attackable) player).getMostHated(), 100);
  9155.                                             }
  9156.                                         }
  9157.                                         itr = null;
  9158.                                         spawnedMinions = null;
  9159.                                         minion = null;
  9160.                                     }
  9161.                                 }
  9162.                             }
  9163.                             return;
  9164.                         }
  9165.                     }
  9166.                    
  9167.                     L2PcInstance activeChar = null;
  9168.                    
  9169.                     if (this instanceof L2PcInstance)
  9170.                     {
  9171.                         activeChar = (L2PcInstance) this;
  9172.                     }
  9173.                     else if (this instanceof L2Summon)
  9174.                     {
  9175.                         activeChar = ((L2Summon) this).getOwner();
  9176.                     }
  9177.                    
  9178.                     if (activeChar != null)
  9179.                     {
  9180.                         if (skill.isOffensive())
  9181.                         {
  9182.                             if (player instanceof L2PcInstance || player instanceof L2Summon)
  9183.                             {
  9184.                                 // Signets are a special case, casted on target_self but don't harm self
  9185.                                 if (skill.getSkillType() != L2Skill.SkillType.SIGNET && skill.getSkillType() != L2Skill.SkillType.SIGNET_CASTTIME)
  9186.                                 {
  9187.                                     player.getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, activeChar);
  9188.                                     activeChar.updatePvPStatus(player);
  9189.                                 }
  9190.                             }
  9191.                             else if (player instanceof L2Attackable)
  9192.                             {
  9193.                                 switch (skill.getSkillType())
  9194.                                 {
  9195.                                     case AGGREDUCE:
  9196.                                     case AGGREDUCE_CHAR:
  9197.                                     case AGGREMOVE:
  9198.                                         break;
  9199.                                     default:
  9200.                                         ((L2Character) target).addAttackerToAttackByList(this);
  9201.                                         /*
  9202.                                          * ((L2Character) target).getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, this); - Deprecated Notify the AI that is being attacked. It should be notified once the skill is finished in order to avoid AI action previous to skill end. IE: Backstab on monsters, the AI
  9203.                                          * rotates previous to skill end so it doesn't make affect. We calculate the hit time to know when the AI should rotate.
  9204.                                          */
  9205.                                         int hitTime = Formulas.getInstance().calcMAtkSpd(activeChar, skill, skill.getHitTime());
  9206.                                         if ((checkBss() || checkSps()) && !skill.isStaticHitTime() && !skill.isPotion() && skill.isMagic())
  9207.                                             hitTime = (int) (0.70 * hitTime);
  9208.                                         ThreadPoolManager.getInstance().scheduleGeneral(new notifyAiTaskDelayed(CtrlEvent.EVT_ATTACKED, this, target), hitTime);
  9209.                                         break;
  9210.                                 }
  9211.                             }
  9212.                         }
  9213.                         else
  9214.                         {
  9215.                             if (player instanceof L2PcInstance)
  9216.                             {
  9217.                                 // Casting non offensive skill on player with pvp flag set or with karma
  9218.                                 if (!player.equals(this) && (((L2PcInstance) player).getPvpFlag() > 0 || ((L2PcInstance) player).getKarma() > 0))
  9219.                                 {
  9220.                                     activeChar.updatePvPStatus();
  9221.                                 }
  9222.                             }
  9223.                             else if (player instanceof L2Attackable && !(skill.getSkillType() == L2Skill.SkillType.SUMMON) && !(skill.getSkillType() == L2Skill.SkillType.BEAST_FEED) && !(skill.getSkillType() == L2Skill.SkillType.UNLOCK) && !(skill.getSkillType() == L2Skill.SkillType.DELUXE_KEY_UNLOCK))
  9224.                             {
  9225.                                 activeChar.updatePvPStatus(this);
  9226.                             }
  9227.                         }
  9228.                         player = null;
  9229.                         // activeWeapon = null;
  9230.                     }
  9231.                     activeChar = null;
  9232.                 }
  9233.                 if (target instanceof L2MonsterInstance)
  9234.                 {
  9235.                     if (!skill.isOffensive() && skill.getSkillType() != SkillType.UNLOCK && skill.getSkillType() != SkillType.SUMMON && skill.getSkillType() != SkillType.DELUXE_KEY_UNLOCK && skill.getSkillType() != SkillType.BEAST_FEED)
  9236.                     {
  9237.                         L2PcInstance activeChar = null;
  9238.                        
  9239.                         if (this instanceof L2PcInstance)
  9240.                         {
  9241.                             activeChar = (L2PcInstance) this;
  9242.                             activeChar.updatePvPStatus(activeChar);
  9243.                         }
  9244.                         else if (this instanceof L2Summon)
  9245.                         {
  9246.                             activeChar = ((L2Summon) this).getOwner();
  9247.                         }
  9248.                     }
  9249.                 }
  9250.             }
  9251.            
  9252.             ISkillHandler handler = null;
  9253.            
  9254.             if (skill.isToggle())
  9255.             {
  9256.                 // Check if the skill effects are already in progress on the L2Character
  9257.                 if (getFirstEffect(skill.getId()) != null)
  9258.                 {
  9259.                     handler = SkillHandler.getInstance().getSkillHandler(skill.getSkillType());
  9260.                    
  9261.                     if (handler != null)
  9262.                     {
  9263.                         handler.useSkill(this, skill, targets);
  9264.                     }
  9265.                     else
  9266.                     {
  9267.                         skill.useSkill(this, targets);
  9268.                     }
  9269.                    
  9270.                     return;
  9271.                 }
  9272.             }/*
  9273.              * TODO else { if(this instanceof L2PcInstance || this instanceof L2Summon) { L2PcInstance caster = this instanceof L2PcInstance ? (L2PcInstance) this : ((L2Summon) this).getOwner(); for(L2Object target : targets) { if(target instanceof L2NpcInstance) { if (((L2NpcInstance)
  9274.              * target).getTemplate().getEventQuests(Quest.QuestEventType.ON_SKILL_USE) != null) { for(Quest quest : ((L2NpcInstance) target).getTemplate().getEventQuests(Quest.QuestEventType.ON_SKILL_USE)) { quest.notifySkillUse((L2NpcInstance) target, caster, skill); } } } } caster = null; } }
  9275.              */
  9276.            
  9277.             // Check if over-hit is possible
  9278.             if (skill.isOverhit())
  9279.             {
  9280.                 // Set the "over-hit enabled" flag on each of the possible targets
  9281.                 for (final L2Object target : targets)
  9282.                 {
  9283.                     L2Character player = (L2Character) target;
  9284.                     if (player instanceof L2Attackable)
  9285.                     {
  9286.                         ((L2Attackable) player).overhitEnabled(true);
  9287.                     }
  9288.                    
  9289.                     player = null;
  9290.                 }
  9291.             }
  9292.            
  9293.             // Get the skill handler corresponding to the skill type (PDAM, MDAM, SWEEP...) started in gameserver
  9294.             handler = SkillHandler.getInstance().getSkillHandler(skill.getSkillType());
  9295.            
  9296.             // Launch the magic skill and calculate its effects
  9297.             if (handler != null)
  9298.             {
  9299.                 handler.useSkill(this, skill, targets);
  9300.             }
  9301.             else
  9302.             {
  9303.                 skill.useSkill(this, targets);
  9304.             }
  9305.            
  9306.             // if the skill is a potion, must delete the potion item
  9307.             if (skill.isPotion() && this instanceof L2PlayableInstance)
  9308.             {
  9309.                 Potions.delete_Potion_Item((L2PlayableInstance) this, skill.getId(), skill.getLevel());
  9310.             }
  9311.            
  9312.             if (this instanceof L2PcInstance || this instanceof L2Summon)
  9313.             {
  9314.                 L2PcInstance caster = this instanceof L2PcInstance ? (L2PcInstance) this : ((L2Summon) this).getOwner();
  9315.                 for (final L2Object target : targets)
  9316.                 {
  9317.                     if (target instanceof L2NpcInstance)
  9318.                     {
  9319.                         L2NpcInstance npc = (L2NpcInstance) target;
  9320.                        
  9321.                         for (final Quest quest : npc.getTemplate().getEventQuests(Quest.QuestEventType.ON_SKILL_USE))
  9322.                         {
  9323.                             quest.notifySkillUse(npc, caster, skill);
  9324.                         }
  9325.                        
  9326.                         npc = null;
  9327.                     }
  9328.                 }
  9329.                
  9330.                 if (skill.getAggroPoints() > 0)
  9331.                 {
  9332.                     for (final L2Object spMob : caster.getKnownList().getKnownObjects().values())
  9333.                         if (spMob instanceof L2NpcInstance)
  9334.                         {
  9335.                             L2NpcInstance npcMob = (L2NpcInstance) spMob;
  9336.                            
  9337.                             if (npcMob.isInsideRadius(caster, 1000, true, true) && npcMob.hasAI() && npcMob.getAI().getIntention() == AI_INTENTION_ATTACK)
  9338.                             {
  9339.                                 L2Object npcTarget = npcMob.getTarget();
  9340.                                
  9341.                                 for (final L2Object target : targets)
  9342.                                     if (npcTarget == target || npcMob == target)
  9343.                                     {
  9344.                                         npcMob.seeSpell(caster, target, skill);
  9345.                                     }
  9346.                                
  9347.                                 npcTarget = null;
  9348.                             }
  9349.                            
  9350.                             npcMob = null;
  9351.                         }
  9352.                 }
  9353.                
  9354.                 caster = null;
  9355.             }
  9356.            
  9357.             handler = null;
  9358.         }
  9359.         catch (final Exception e)
  9360.         {
  9361.             LOGGER.warn("", e);
  9362.         }
  9363.        
  9364.         if (this instanceof L2PcInstance && ((L2PcInstance) this).isMovingTaskDefined() && !skill.isPotion())
  9365.             ((L2PcInstance) this).startMovingTask();
  9366.     }
  9367.    
  9368.     /**
  9369.      * See spell.
  9370.      * @param caster the caster
  9371.      * @param target the target
  9372.      * @param skill the skill
  9373.      */
  9374.     public void seeSpell(final L2PcInstance caster, final L2Object target, final L2Skill skill)
  9375.     {
  9376.         if (this instanceof L2Attackable)
  9377.         {
  9378.             ((L2Attackable) this).addDamageHate(caster, 0, -skill.getAggroPoints());
  9379.         }
  9380.     }
  9381.    
  9382.     /**
  9383.      * Return True if the L2Character is behind the target and can't be seen.<BR>
  9384.      * <BR>
  9385.      * @param target the target
  9386.      * @return true, if is behind
  9387.      */
  9388.     public boolean isBehind(final L2Object target)
  9389.     {
  9390.         double angleChar, angleTarget, angleDiff; //
  9391.         final double maxAngleDiff = 40;
  9392.        
  9393.         if (target == null)
  9394.             return false;
  9395.        
  9396.         if (target instanceof L2Character)
  9397.         {
  9398.         if (target != this)
  9399.         {
  9400.             ((L2Character) target).sendPacket(new ValidateLocation(this));
  9401.             this.sendPacket(new ValidateLocation(((L2Character) target)));
  9402.             }
  9403.            
  9404.             L2Character target1 = (L2Character) target;
  9405.             angleChar = Util.calculateAngleFrom(target1, this);
  9406.             angleTarget = Util.convertHeadingToDegree(target1.getHeading());
  9407.             angleDiff = angleChar - angleTarget;
  9408.            
  9409.             if (angleDiff <= -360 + maxAngleDiff)
  9410.             {
  9411.                 angleDiff += 360;
  9412.             }
  9413.            
  9414.             if (angleDiff >= 360 - maxAngleDiff)
  9415.             {
  9416.                 angleDiff -= 360;
  9417.             }
  9418.            
  9419.             if (Math.abs(angleDiff) <= maxAngleDiff)
  9420.             {
  9421.                 if (Config.DEBUG)
  9422.                 {
  9423.                     LOGGER.info("Char " + getName() + " is behind " + target.getName());
  9424.                 }
  9425.                
  9426.                 return true;
  9427.             }
  9428.            
  9429.             target1 = null;
  9430.         }
  9431.        
  9432.         return false;
  9433.     }
  9434.    
  9435.     /**
  9436.      * Checks if is behind target.
  9437.      * @return true, if is behind target
  9438.      */
  9439.     public boolean isBehindTarget()
  9440.     {
  9441.         return isBehind(getTarget());
  9442.     }
  9443.    
  9444.     /**
  9445.      * Returns true if target is in front of L2Character (shield def etc).
  9446.      * @param target the target
  9447.      * @param maxAngle the max angle
  9448.      * @return true, if is facing
  9449.      */
  9450.     public boolean isFacing(final L2Object target, final int maxAngle)
  9451.     {
  9452.         double angleChar, angleTarget, angleDiff, maxAngleDiff;
  9453.         if (target == null)
  9454.             return false;
  9455.         maxAngleDiff = maxAngle / 2;
  9456.         angleTarget = Util.calculateAngleFrom(this, target);
  9457.         angleChar = Util.convertHeadingToDegree(this.getHeading());
  9458.         angleDiff = angleChar - angleTarget;
  9459.         if (angleDiff <= -360 + maxAngleDiff)
  9460.             angleDiff += 360;
  9461.         if (angleDiff >= 360 - maxAngleDiff)
  9462.             angleDiff -= 360;
  9463.         if (Math.abs(angleDiff) <= maxAngleDiff)
  9464.             return true;
  9465.         return false;
  9466.     }
  9467.    
  9468.     /**
  9469.      * Return True if the L2Character is behind the target and can't be seen.<BR>
  9470.      * <BR>
  9471.      * @param target the target
  9472.      * @return true, if is front
  9473.      */
  9474.     public boolean isFront(final L2Object target)
  9475.     {
  9476.         double angleChar, angleTarget, angleDiff;
  9477.         final double maxAngleDiff = 40;
  9478.        
  9479.         if (target == null)
  9480.             return false;
  9481.        
  9482.         if (target instanceof L2Character)
  9483.         {
  9484.         if (target != this)
  9485.         {
  9486.             ((L2Character) target).sendPacket(new ValidateLocation(this));
  9487.             this.sendPacket(new ValidateLocation(((L2Character) target)));
  9488.             }
  9489.            
  9490.             L2Character target1 = (L2Character) target;
  9491.             angleChar = Util.calculateAngleFrom(target1, this);
  9492.             angleTarget = Util.convertHeadingToDegree(target1.getHeading());
  9493.             angleDiff = angleChar - angleTarget;
  9494.            
  9495.             if (angleDiff <= -180 + maxAngleDiff)
  9496.             {
  9497.                 angleDiff += 180;
  9498.             }
  9499.            
  9500.             if (angleDiff >= 180 - maxAngleDiff)
  9501.             {
  9502.                 angleDiff -= 180;
  9503.             }
  9504.            
  9505.             if (Math.abs(angleDiff) <= maxAngleDiff)
  9506.             {
  9507.                 if (isBehindTarget())
  9508.                     return false;
  9509.                
  9510.                 if (Config.DEBUG)
  9511.                 {
  9512.                     LOGGER.info("Char " + getName() + " is side " + target.getName());
  9513.                 }
  9514.                
  9515.                 return true;
  9516.             }
  9517.            
  9518.             target1 = null;
  9519.         }
  9520.        
  9521.         return false;
  9522.     }
  9523.    
  9524.     /**
  9525.      * Checks if is front target.
  9526.      * @return true, if is front target
  9527.      */
  9528.     public boolean isFrontTarget()
  9529.     {
  9530.         return isFront(getTarget());
  9531.     }
  9532.    
  9533.     /**
  9534.      * Return True if the L2Character is side the target and can't be seen.<BR>
  9535.      * <BR>
  9536.      * @param target the target
  9537.      * @return true, if is side
  9538.      */
  9539.     public boolean isSide(final L2Object target)
  9540.     {
  9541.         if (target == null)
  9542.             return false;
  9543.        
  9544.         if (target instanceof L2Character)
  9545.         {
  9546.             if (isBehindTarget() || isFrontTarget())
  9547.                 return false;
  9548.         }
  9549.        
  9550.         return true;
  9551.     }
  9552.    
  9553.     /**
  9554.      * Checks if is side target.
  9555.      * @return true, if is side target
  9556.      */
  9557.     public boolean isSideTarget()
  9558.     {
  9559.         return isSide(getTarget());
  9560.     }
  9561.    
  9562.     /**
  9563.      * Return 1.<BR>
  9564.      * <BR>
  9565.      * @return the level mod
  9566.      */
  9567.     public double getLevelMod()
  9568.     {
  9569.         return 1;
  9570.     }
  9571.    
  9572.     /**
  9573.      * Sets the skill cast.
  9574.      * @param newSkillCast the new skill cast
  9575.      */
  9576.     public final void setSkillCast(final Future<?> newSkillCast)
  9577.     {
  9578.         _skillCast = newSkillCast;
  9579.     }
  9580.    
  9581.     /**
  9582.      * Sets the skill cast end time.
  9583.      * @param newSkillCastEndTime the new skill cast end time
  9584.      */
  9585.     public final void setSkillCastEndTime(final int newSkillCastEndTime)
  9586.     {
  9587.         _castEndTime = newSkillCastEndTime;
  9588.         // for interrupt -12 ticks; first removing the extra second and then -200 ms
  9589.         _castInterruptTime = newSkillCastEndTime - 12;
  9590.     }
  9591.    
  9592.     /** The _ pvp reg task. */
  9593.     private Future<?> _PvPRegTask;
  9594.    
  9595.     /** The _pvp flag lasts. */
  9596.     private long _pvpFlagLasts;
  9597.    
  9598.     /**
  9599.      * Sets the pvp flag lasts.
  9600.      * @param time the new pvp flag lasts
  9601.      */
  9602.     public void setPvpFlagLasts(final long time)
  9603.     {
  9604.         _pvpFlagLasts = time;
  9605.     }
  9606.    
  9607.     /**
  9608.      * Gets the pvp flag lasts.
  9609.      * @return the pvp flag lasts
  9610.      */
  9611.     public long getPvpFlagLasts()
  9612.     {
  9613.         return _pvpFlagLasts;
  9614.     }
  9615.    
  9616.     /**
  9617.      * Start pvp flag.
  9618.      */
  9619.     public void startPvPFlag()
  9620.     {
  9621.         updatePvPFlag(1);
  9622.        
  9623.         _PvPRegTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new PvPFlag(), 1000, 1000);
  9624.     }
  9625.    
  9626.     /**
  9627.      * Stop pvp reg task.
  9628.      */
  9629.     public void stopPvpRegTask()
  9630.     {
  9631.         if (_PvPRegTask != null)
  9632.         {
  9633.             _PvPRegTask.cancel(true);
  9634.         }
  9635.     }
  9636.    
  9637.     /**
  9638.      * Stop pvp flag.
  9639.      */
  9640.     public void stopPvPFlag()
  9641.     {
  9642.         stopPvpRegTask();
  9643.        
  9644.         updatePvPFlag(0);
  9645.        
  9646.         _PvPRegTask = null;
  9647.     }
  9648.    
  9649.     /**
  9650.      * Update pvp flag.
  9651.      * @param value the value
  9652.      */
  9653.     public void updatePvPFlag(final int value)
  9654.     {
  9655.         // Overridden in L2PcInstance
  9656.         //
  9657.         // if (!(this instanceof L2PcInstance))
  9658.         // return;
  9659.         // L2PcInstance player = (L2PcInstance)this;
  9660.         // if (player.getPvpFlag() == value)
  9661.         // return;
  9662.         // player.setPvpFlag(value);
  9663.         //
  9664.         // player.sendPacket(new UserInfo(player));
  9665.         // for (L2PcInstance target : getKnownList().getKnownPlayers().values())
  9666.         // {
  9667.         // target.sendPacket(new RelationChanged(player, player.getRelation(player), player.isAutoAttackable(target)));
  9668.         // }
  9669.     }
  9670.    
  9671.     // public void checkPvPFlag()
  9672.     // {
  9673.     // if (Config.DEBUG) LOGGER.fine("Checking PvpFlag");
  9674.     // _PvPRegTask = ThreadPoolManager.getInstance().scheduleLowAtFixedRate(new PvPFlag(), 1000, 5000);
  9675.     // _PvPRegActive = true;
  9676.     // // LOGGER.fine("PvP recheck");
  9677.     // }
  9678.     //
  9679.    
  9680.     /**
  9681.      * Return a Random Damage in function of the weapon.<BR>
  9682.      * <BR>
  9683.      * @param target the target
  9684.      * @return the random damage
  9685.      */
  9686.     public final int getRandomDamage(final L2Character target)
  9687.     {
  9688.         final L2Weapon weaponItem = getActiveWeaponItem();
  9689.        
  9690.         if (weaponItem == null)
  9691.             return 5 + (int) Math.sqrt(getLevel());
  9692.        
  9693.         return weaponItem.getRandomDamage();
  9694.     }
  9695.    
  9696.     /*
  9697.      * (non-Javadoc)
  9698.      * @see com.l2jlegacy.gameserver.model.L2Object#toString()
  9699.      */
  9700.     @Override
  9701.     public String toString()
  9702.     {
  9703.         return "mob " + getObjectId();
  9704.     }
  9705.    
  9706.     /**
  9707.      * Gets the attack end time.
  9708.      * @return the attack end time
  9709.      */
  9710.     public int getAttackEndTime()
  9711.     {
  9712.         return _attackEndTime;
  9713.     }
  9714.    
  9715.     /**
  9716.      * Not Implemented.<BR>
  9717.      * <BR>
  9718.      * @return the level
  9719.      */
  9720.     public abstract int getLevel();
  9721.    
  9722.     // =========================================================
  9723.    
  9724.     // =========================================================
  9725.     // Stat - NEED TO REMOVE ONCE L2CHARSTAT IS COMPLETE
  9726.     // Property - Public
  9727.     /**
  9728.      * Calc stat.
  9729.      * @param stat the stat
  9730.      * @param init the init
  9731.      * @param target the target
  9732.      * @param skill the skill
  9733.      * @return the double
  9734.      */
  9735.     public final double calcStat(final Stats stat, final double init, final L2Character target, final L2Skill skill)
  9736.     {
  9737.         return getStat().calcStat(stat, init, target, skill);
  9738.     }
  9739.    
  9740.     // Property - Public
  9741.     /**
  9742.      * Gets the accuracy.
  9743.      * @return the accuracy
  9744.      */
  9745.     public int getAccuracy()
  9746.     {
  9747.         return getStat().getAccuracy();
  9748.     }
  9749.    
  9750.     /**
  9751.      * Gets the attack speed multiplier.
  9752.      * @return the attack speed multiplier
  9753.      */
  9754.     public final float getAttackSpeedMultiplier()
  9755.     {
  9756.         return getStat().getAttackSpeedMultiplier();
  9757.     }
  9758.    
  9759.     /**
  9760.      * Gets the cON.
  9761.      * @return the cON
  9762.      */
  9763.     public int getCON()
  9764.     {
  9765.         return getStat().getCON();
  9766.     }
  9767.    
  9768.     /**
  9769.      * Gets the dEX.
  9770.      * @return the dEX
  9771.      */
  9772.     public int getDEX()
  9773.     {
  9774.         return getStat().getDEX();
  9775.     }
  9776.    
  9777.     /**
  9778.      * Gets the critical dmg.
  9779.      * @param target the target
  9780.      * @param init the init
  9781.      * @return the critical dmg
  9782.      */
  9783.     public final double getCriticalDmg(final L2Character target, final double init)
  9784.     {
  9785.         return getStat().getCriticalDmg(target, init);
  9786.     }
  9787.    
  9788.     /**
  9789.      * Gets the critical hit.
  9790.      * @param target the target
  9791.      * @param skill the skill
  9792.      * @return the critical hit
  9793.      */
  9794.     public int getCriticalHit(final L2Character target, final L2Skill skill)
  9795.     {
  9796.         return getStat().getCriticalHit(target, skill);
  9797.     }
  9798.    
  9799.     /**
  9800.      * Gets the evasion rate.
  9801.      * @param target the target
  9802.      * @return the evasion rate
  9803.      */
  9804.     public int getEvasionRate(final L2Character target)
  9805.     {
  9806.         return getStat().getEvasionRate(target);
  9807.     }
  9808.    
  9809.     /**
  9810.      * Gets the iNT.
  9811.      * @return the iNT
  9812.      */
  9813.     public int getINT()
  9814.     {
  9815.         return getStat().getINT();
  9816.     }
  9817.    
  9818.     /**
  9819.      * Gets the magical attack range.
  9820.      * @param skill the skill
  9821.      * @return the magical attack range
  9822.      */
  9823.     public final int getMagicalAttackRange(final L2Skill skill)
  9824.     {
  9825.         return getStat().getMagicalAttackRange(skill);
  9826.     }
  9827.    
  9828.     /**
  9829.      * Gets the max cp.
  9830.      * @return the max cp
  9831.      */
  9832.     public final int getMaxCp()
  9833.     {
  9834.         return getStat().getMaxCp();
  9835.     }
  9836.    
  9837.     /**
  9838.      * Gets the m atk.
  9839.      * @param target the target
  9840.      * @param skill the skill
  9841.      * @return the m atk
  9842.      */
  9843.     public int getMAtk(final L2Character target, final L2Skill skill)
  9844.     {
  9845.         return getStat().getMAtk(target, skill);
  9846.     }
  9847.    
  9848.     /**
  9849.      * Gets the m atk spd.
  9850.      * @return the m atk spd
  9851.      */
  9852.     public int getMAtkSpd()
  9853.     {
  9854.         return getStat().getMAtkSpd();
  9855.     }
  9856.    
  9857.     /**
  9858.      * Gets the max mp.
  9859.      * @return the max mp
  9860.      */
  9861.     public int getMaxMp()
  9862.     {
  9863.         return getStat().getMaxMp();
  9864.     }
  9865.    
  9866.     /**
  9867.      * Gets the max hp.
  9868.      * @return the max hp
  9869.      */
  9870.     public int getMaxHp()
  9871.     {
  9872.         return getStat().getMaxHp();
  9873.     }
  9874.    
  9875.     /**
  9876.      * Gets the m critical hit.
  9877.      * @param target the target
  9878.      * @param skill the skill
  9879.      * @return the m critical hit
  9880.      */
  9881.     public final int getMCriticalHit(final L2Character target, final L2Skill skill)
  9882.     {
  9883.         return getStat().getMCriticalHit(target, skill);
  9884.     }
  9885.    
  9886.     /**
  9887.      * Gets the m def.
  9888.      * @param target the target
  9889.      * @param skill the skill
  9890.      * @return the m def
  9891.      */
  9892.     public int getMDef(final L2Character target, final L2Skill skill)
  9893.     {
  9894.         return getStat().getMDef(target, skill);
  9895.     }
  9896.    
  9897.     /**
  9898.      * Gets the mEN.
  9899.      * @return the mEN
  9900.      */
  9901.     public int getMEN()
  9902.     {
  9903.         return getStat().getMEN();
  9904.     }
  9905.    
  9906.     /**
  9907.      * Gets the m reuse rate.
  9908.      * @param skill the skill
  9909.      * @return the m reuse rate
  9910.      */
  9911.     public double getMReuseRate(final L2Skill skill)
  9912.     {
  9913.         return getStat().getMReuseRate(skill);
  9914.     }
  9915.    
  9916.     /**
  9917.      * Gets the movement speed multiplier.
  9918.      * @return the movement speed multiplier
  9919.      */
  9920.     public float getMovementSpeedMultiplier()
  9921.     {
  9922.         return getStat().getMovementSpeedMultiplier();
  9923.     }
  9924.    
  9925.     /**
  9926.      * Gets the p atk.
  9927.      * @param target the target
  9928.      * @return the p atk
  9929.      */
  9930.     public int getPAtk(final L2Character target)
  9931.     {
  9932.         return getStat().getPAtk(target);
  9933.     }
  9934.    
  9935.     /**
  9936.      * Gets the p atk animals.
  9937.      * @param target the target
  9938.      * @return the p atk animals
  9939.      */
  9940.     public double getPAtkAnimals(final L2Character target)
  9941.     {
  9942.         return getStat().getPAtkAnimals(target);
  9943.     }
  9944.    
  9945.     /**
  9946.      * Gets the p atk dragons.
  9947.      * @param target the target
  9948.      * @return the p atk dragons
  9949.      */
  9950.     public double getPAtkDragons(final L2Character target)
  9951.     {
  9952.         return getStat().getPAtkDragons(target);
  9953.     }
  9954.    
  9955.     /**
  9956.      * Gets the p atk angels.
  9957.      * @param target the target
  9958.      * @return the p atk angels
  9959.      */
  9960.     public double getPAtkAngels(final L2Character target)
  9961.     {
  9962.         return getStat().getPAtkAngels(target);
  9963.     }
  9964.    
  9965.     /**
  9966.      * Gets the p atk insects.
  9967.      * @param target the target
  9968.      * @return the p atk insects
  9969.      */
  9970.     public double getPAtkInsects(final L2Character target)
  9971.     {
  9972.         return getStat().getPAtkInsects(target);
  9973.     }
  9974.    
  9975.     /**
  9976.      * Gets the p atk monsters.
  9977.      * @param target the target
  9978.      * @return the p atk monsters
  9979.      */
  9980.     public double getPAtkMonsters(final L2Character target)
  9981.     {
  9982.         return getStat().getPAtkMonsters(target);
  9983.     }
  9984.    
  9985.     /**
  9986.      * Gets the p atk plants.
  9987.      * @param target the target
  9988.      * @return the p atk plants
  9989.      */
  9990.     public double getPAtkPlants(final L2Character target)
  9991.     {
  9992.         return getStat().getPAtkPlants(target);
  9993.     }
  9994.    
  9995.     /**
  9996.      * Gets the p atk spd.
  9997.      * @return the p atk spd
  9998.      */
  9999.     public int getPAtkSpd()
  10000.     {
  10001.         return getStat().getPAtkSpd();
  10002.     }
  10003.    
  10004.     /**
  10005.      * Gets the p atk undead.
  10006.      * @param target the target
  10007.      * @return the p atk undead
  10008.      */
  10009.     public double getPAtkUndead(final L2Character target)
  10010.     {
  10011.         return getStat().getPAtkUndead(target);
  10012.     }
  10013.    
  10014.     /**
  10015.      * Gets the p def undead.
  10016.      * @param target the target
  10017.      * @return the p def undead
  10018.      */
  10019.     public double getPDefUndead(final L2Character target)
  10020.     {
  10021.         return getStat().getPDefUndead(target);
  10022.     }
  10023.    
  10024.     /**
  10025.      * Gets the p def plants.
  10026.      * @param target the target
  10027.      * @return the p def plants
  10028.      */
  10029.     public double getPDefPlants(final L2Character target)
  10030.     {
  10031.         return getStat().getPDefPlants(target);
  10032.     }
  10033.    
  10034.     /**
  10035.      * Gets the p def insects.
  10036.      * @param target the target
  10037.      * @return the p def insects
  10038.      */
  10039.     public double getPDefInsects(final L2Character target)
  10040.     {
  10041.         return getStat().getPDefInsects(target);
  10042.     }
  10043.    
  10044.     /**
  10045.      * Gets the p def animals.
  10046.      * @param target the target
  10047.      * @return the p def animals
  10048.      */
  10049.     public double getPDefAnimals(final L2Character target)
  10050.     {
  10051.         return getStat().getPDefAnimals(target);
  10052.     }
  10053.    
  10054.     /**
  10055.      * Gets the p def monsters.
  10056.      * @param target the target
  10057.      * @return the p def monsters
  10058.      */
  10059.     public double getPDefMonsters(final L2Character target)
  10060.     {
  10061.         return getStat().getPDefMonsters(target);
  10062.     }
  10063.    
  10064.     /**
  10065.      * Gets the p def dragons.
  10066.      * @param target the target
  10067.      * @return the p def dragons
  10068.      */
  10069.     public double getPDefDragons(final L2Character target)
  10070.     {
  10071.         return getStat().getPDefDragons(target);
  10072.     }
  10073.    
  10074.     /**
  10075.      * Gets the p def angels.
  10076.      * @param target the target
  10077.      * @return the p def angels
  10078.      */
  10079.     public double getPDefAngels(final L2Character target)
  10080.     {
  10081.         return getStat().getPDefAngels(target);
  10082.     }
  10083.    
  10084.     /**
  10085.      * Gets the p def.
  10086.      * @param target the target
  10087.      * @return the p def
  10088.      */
  10089.     public int getPDef(final L2Character target)
  10090.     {
  10091.         return getStat().getPDef(target);
  10092.     }
  10093.    
  10094.     /**
  10095.      * Gets the p atk giants.
  10096.      * @param target the target
  10097.      * @return the p atk giants
  10098.      */
  10099.     public double getPAtkGiants(final L2Character target)
  10100.     {
  10101.         return getStat().getPAtkGiants(target);
  10102.     }
  10103.    
  10104.     /**
  10105.      * Gets the p atk magic creatures.
  10106.      * @param target the target
  10107.      * @return the p atk magic creatures
  10108.      */
  10109.     public double getPAtkMagicCreatures(final L2Character target)
  10110.     {
  10111.         return getStat().getPAtkMagicCreatures(target);
  10112.     }
  10113.    
  10114.     /**
  10115.      * Gets the p def giants.
  10116.      * @param target the target
  10117.      * @return the p def giants
  10118.      */
  10119.     public double getPDefGiants(final L2Character target)
  10120.     {
  10121.         return getStat().getPDefGiants(target);
  10122.     }
  10123.    
  10124.     /**
  10125.      * Gets the p def magic creatures.
  10126.      * @param target the target
  10127.      * @return the p def magic creatures
  10128.      */
  10129.     public double getPDefMagicCreatures(final L2Character target)
  10130.     {
  10131.         return getStat().getPDefMagicCreatures(target);
  10132.     }
  10133.    
  10134.     /**
  10135.      * Gets the physical attack range.
  10136.      * @return the physical attack range
  10137.      */
  10138.     public final int getPhysicalAttackRange()
  10139.     {
  10140.         return getStat().getPhysicalAttackRange();
  10141.     }
  10142.    
  10143.     /**
  10144.      * Gets the run speed.
  10145.      * @return the run speed
  10146.      */
  10147.     public int getRunSpeed()
  10148.     {
  10149.         return getStat().getRunSpeed();
  10150.     }
  10151.    
  10152.     /**
  10153.      * Gets the shld def.
  10154.      * @return the shld def
  10155.      */
  10156.     public final int getShldDef()
  10157.     {
  10158.         return getStat().getShldDef();
  10159.     }
  10160.    
  10161.     /**
  10162.      * Gets the sTR.
  10163.      * @return the sTR
  10164.      */
  10165.     public int getSTR()
  10166.     {
  10167.         return getStat().getSTR();
  10168.     }
  10169.    
  10170.     /**
  10171.      * Gets the walk speed.
  10172.      * @return the walk speed
  10173.      */
  10174.     public final int getWalkSpeed()
  10175.     {
  10176.         return getStat().getWalkSpeed();
  10177.     }
  10178.    
  10179.     /**
  10180.      * Gets the wIT.
  10181.      * @return the wIT
  10182.      */
  10183.     public int getWIT()
  10184.     {
  10185.         return getStat().getWIT();
  10186.     }
  10187.    
  10188.     // =========================================================
  10189.    
  10190.     // =========================================================
  10191.     // Status - NEED TO REMOVE ONCE L2CHARTATUS IS COMPLETE
  10192.     // Method - Public
  10193.     /**
  10194.      * Adds the status listener.
  10195.      * @param object the object
  10196.      */
  10197.     public void addStatusListener(final L2Character object)
  10198.     {
  10199.         getStatus().addStatusListener(object);
  10200.     }
  10201.    
  10202.     /**
  10203.      * Reduce current hp.
  10204.      * @param i the i
  10205.      * @param attacker the attacker
  10206.      */
  10207.     public void reduceCurrentHp(final double i, final L2Character attacker)
  10208.     {
  10209.         reduceCurrentHp(i, attacker, true);
  10210.     }
  10211.    
  10212.     /**
  10213.      * Reduce current hp.
  10214.      * @param i the i
  10215.      * @param attacker the attacker
  10216.      * @param awake the awake
  10217.      */
  10218.     public void reduceCurrentHp(final double i, final L2Character attacker, final boolean awake)
  10219.     {
  10220.         if (this instanceof L2NpcInstance)
  10221.             if (Config.INVUL_NPC_LIST.contains(Integer.valueOf(((L2NpcInstance) this).getNpcId())))
  10222.                 return;
  10223.        
  10224.         if (Config.L2JMOD_CHAMPION_ENABLE && isChampion() && Config.L2JMOD_CHAMPION_HP != 0)
  10225.         {
  10226.             getStatus().reduceHp(i / Config.L2JMOD_CHAMPION_HP, attacker, awake);
  10227.         }
  10228.         else if (is_advanceFlag())
  10229.         {
  10230.             getStatus().reduceHp(i / _advanceMultiplier, attacker, awake);
  10231.         }
  10232.         else if (isUnkillable())
  10233.         {
  10234.             final double hpToReduce = this.getCurrentHp() - 1;
  10235.             if (i > this.getCurrentHp())
  10236.                 getStatus().reduceHp(hpToReduce, attacker, awake);
  10237.             else
  10238.                 getStatus().reduceHp(i, attacker, awake);
  10239.         }
  10240.         else
  10241.         {
  10242.             getStatus().reduceHp(i, attacker, awake);
  10243.         }
  10244.     }
  10245.    
  10246.     private long _nextReducingHPByOverTime = -1;
  10247.    
  10248.     public void reduceCurrentHpByDamOverTime(final double i, final L2Character attacker, final boolean awake, final int period)
  10249.     {
  10250.         if (_nextReducingHPByOverTime > System.currentTimeMillis())
  10251.         {
  10252.             return;
  10253.         }
  10254.        
  10255.         _nextReducingHPByOverTime = System.currentTimeMillis() + (period * 1000);
  10256.         reduceCurrentHp(i, attacker, awake);
  10257.        
  10258.     }
  10259.    
  10260.     private long _nextReducingMPByOverTime = -1;
  10261.    
  10262.     public void reduceCurrentMpByDamOverTime(final double i, final int period)
  10263.     {
  10264.         if (_nextReducingMPByOverTime > System.currentTimeMillis())
  10265.         {
  10266.             return;
  10267.         }
  10268.        
  10269.         _nextReducingMPByOverTime = System.currentTimeMillis() + (period * 1000);
  10270.         reduceCurrentMp(i);
  10271.        
  10272.     }
  10273.    
  10274.     /**
  10275.      * Reduce current mp.
  10276.      * @param i the i
  10277.      */
  10278.     public void reduceCurrentMp(final double i)
  10279.     {
  10280.         getStatus().reduceMp(i);
  10281.     }
  10282.    
  10283.     /**
  10284.      * Removes the status listener.
  10285.      * @param object the object
  10286.      */
  10287.     public void removeStatusListener(final L2Character object)
  10288.     {
  10289.         getStatus().removeStatusListener(object);
  10290.     }
  10291.    
  10292.     /**
  10293.      * Stop hp mp regeneration.
  10294.      */
  10295.     protected void stopHpMpRegeneration()
  10296.     {
  10297.         getStatus().stopHpMpRegeneration();
  10298.     }
  10299.    
  10300.     // Property - Public
  10301.     /**
  10302.      * Gets the current cp.
  10303.      * @return the current cp
  10304.      */
  10305.     public final double getCurrentCp()
  10306.     {
  10307.         return getStatus().getCurrentCp();
  10308.     }
  10309.    
  10310.     /**
  10311.      * Sets the current cp.
  10312.      * @param newCp the new current cp
  10313.      */
  10314.     public final void setCurrentCp(final Double newCp)
  10315.     {
  10316.         setCurrentCp((double) newCp);
  10317.     }
  10318.    
  10319.     /**
  10320.      * Sets the current cp.
  10321.      * @param newCp the new current cp
  10322.      */
  10323.     public final void setCurrentCp(final double newCp)
  10324.     {
  10325.         getStatus().setCurrentCp(newCp);
  10326.     }
  10327.    
  10328.     /**
  10329.      * Gets the current hp.
  10330.      * @return the current hp
  10331.      */
  10332.     public final double getCurrentHp()
  10333.     {
  10334.         return getStatus().getCurrentHp();
  10335.     }
  10336.    
  10337.     /**
  10338.      * Sets the current hp.
  10339.      * @param newHp the new current hp
  10340.      */
  10341.     public final void setCurrentHp(final double newHp)
  10342.     {
  10343.         getStatus().setCurrentHp(newHp);
  10344.     }
  10345.    
  10346.     /**
  10347.      * Sets the current hp direct.
  10348.      * @param newHp the new current hp direct
  10349.      */
  10350.     public final void setCurrentHpDirect(final double newHp)
  10351.     {
  10352.         getStatus().setCurrentHpDirect(newHp);
  10353.     }
  10354.    
  10355.     /**
  10356.      * Sets the current cp direct.
  10357.      * @param newCp the new current cp direct
  10358.      */
  10359.     public final void setCurrentCpDirect(final double newCp)
  10360.     {
  10361.         getStatus().setCurrentCpDirect(newCp);
  10362.     }
  10363.    
  10364.     /**
  10365.      * Sets the current mp direct.
  10366.      * @param newMp the new current mp direct
  10367.      */
  10368.     public final void setCurrentMpDirect(final double newMp)
  10369.     {
  10370.         getStatus().setCurrentMpDirect(newMp);
  10371.     }
  10372.    
  10373.     /**
  10374.      * Sets the current hp mp.
  10375.      * @param newHp the new hp
  10376.      * @param newMp the new mp
  10377.      */
  10378.     public final void setCurrentHpMp(final double newHp, final double newMp)
  10379.     {
  10380.         getStatus().setCurrentHpMp(newHp, newMp);
  10381.     }
  10382.    
  10383.     /**
  10384.      * Gets the current mp.
  10385.      * @return the current mp
  10386.      */
  10387.     public final double getCurrentMp()
  10388.     {
  10389.         return getStatus().getCurrentMp();
  10390.     }
  10391.    
  10392.     /**
  10393.      * Sets the current mp.
  10394.      * @param newMp the new current mp
  10395.      */
  10396.     public final void setCurrentMp(final Double newMp)
  10397.     {
  10398.         setCurrentMp((double) newMp);
  10399.     }
  10400.    
  10401.     /**
  10402.      * Sets the current mp.
  10403.      * @param newMp the new current mp
  10404.      */
  10405.     public final void setCurrentMp(final double newMp)
  10406.     {
  10407.         getStatus().setCurrentMp(newMp);
  10408.     }
  10409.    
  10410.     // =========================================================
  10411.    
  10412.     /**
  10413.      * Sets the ai class.
  10414.      * @param aiClass the new ai class
  10415.      */
  10416.     public void setAiClass(final String aiClass)
  10417.     {
  10418.         _aiClass = aiClass;
  10419.     }
  10420.    
  10421.     /**
  10422.      * Gets the ai class.
  10423.      * @return the ai class
  10424.      */
  10425.     public String getAiClass()
  10426.     {
  10427.         return _aiClass;
  10428.     }
  10429.    
  10430.     /*
  10431.      * public L2Character getLastBuffer() { return _lastBuffer; }
  10432.      */
  10433.    
  10434.     /**
  10435.      * Sets the champion.
  10436.      * @param champ the new champion
  10437.      */
  10438.     public void setChampion(final boolean champ)
  10439.     {
  10440.         _champion = champ;
  10441.     }
  10442.    
  10443.     /**
  10444.      * Checks if is champion.
  10445.      * @return true, if is champion
  10446.      */
  10447.     public boolean isChampion()
  10448.     {
  10449.         return _champion;
  10450.     }
  10451.    
  10452.     /**
  10453.      * Gets the last heal amount.
  10454.      * @return the last heal amount
  10455.      */
  10456.     public int getLastHealAmount()
  10457.     {
  10458.         return _lastHealAmount;
  10459.     }
  10460.    
  10461.     /*
  10462.      * public void setLastBuffer(L2Character buffer) { _lastBuffer = buffer; }
  10463.      */
  10464.    
  10465.     /**
  10466.      * Sets the last heal amount.
  10467.      * @param hp the new last heal amount
  10468.      */
  10469.     public void setLastHealAmount(final int hp)
  10470.     {
  10471.         _lastHealAmount = hp;
  10472.     }
  10473.    
  10474.     /**
  10475.      * @return the _advanceFlag
  10476.      */
  10477.     public boolean is_advanceFlag()
  10478.     {
  10479.         return _advanceFlag;
  10480.     }
  10481.    
  10482.     /**
  10483.      * @param advanceFlag
  10484.      */
  10485.     public void set_advanceFlag(final boolean advanceFlag)
  10486.     {
  10487.         _advanceFlag = advanceFlag;
  10488.     }
  10489.    
  10490.     /**
  10491.      * @param advanceMultiplier
  10492.      */
  10493.     public void set_advanceMultiplier(final int advanceMultiplier)
  10494.     {
  10495.         _advanceMultiplier = advanceMultiplier;
  10496.     }
  10497.    
  10498.     /**
  10499.      * Check if character reflected skill.
  10500.      * @param skill the skill
  10501.      * @return true, if successful
  10502.      */
  10503.     public boolean reflectSkill(final L2Skill skill)
  10504.     {
  10505.         final double reflect = calcStat(skill.isMagic() ? Stats.REFLECT_SKILL_MAGIC : Stats.REFLECT_SKILL_PHYSIC, 0, null, null);
  10506.        
  10507.         if (Rnd.get(100) < reflect)
  10508.             return true;
  10509.        
  10510.         return false;
  10511.     }
  10512.    
  10513.     /**
  10514.      * Vengeance skill.
  10515.      * @param skill the skill
  10516.      * @return true, if successful
  10517.      */
  10518.     public boolean vengeanceSkill(final L2Skill skill)
  10519.     {
  10520.         if (!skill.isMagic() && skill.getCastRange() <= 40)
  10521.         {
  10522.             final double venganceChance = calcStat(Stats.VENGEANCE_SKILL_PHYSICAL_DAMAGE, 0, null, skill);
  10523.             if (venganceChance > Rnd.get(100))
  10524.                 return true;
  10525.         }
  10526.         return false;
  10527.     }
  10528.    
  10529.     /**
  10530.      * Send system message about damage.<BR>
  10531.      * <BR>
  10532.      * <B><U> Overriden in </U> :</B><BR>
  10533.      * <BR>
  10534.      * <li>L2PcInstance <li>L2SummonInstance <li>L2PetInstance</li><BR>
  10535.      * <BR>
  10536.      * @param target the target
  10537.      * @param damage the damage
  10538.      * @param mcrit the mcrit
  10539.      * @param pcrit the pcrit
  10540.      * @param miss the miss
  10541.      */
  10542.     public void sendDamageMessage(final L2Character target, final int damage, final boolean mcrit, final boolean pcrit, final boolean miss)
  10543.     {
  10544.     }
  10545.    
  10546.     /**
  10547.      * Gets the force buff.
  10548.      * @return the force buff
  10549.      */
  10550.     public ForceBuff getForceBuff()
  10551.     {
  10552.         return _forceBuff;
  10553.     }
  10554.    
  10555.     /**
  10556.      * Sets the force buff.
  10557.      * @param fb the new force buff
  10558.      */
  10559.     public void setForceBuff(final ForceBuff fb)
  10560.     {
  10561.         _forceBuff = fb;
  10562.     }
  10563.    
  10564.     /**
  10565.      * Checks if is fear immune.
  10566.      * @return true, if is fear immune
  10567.      */
  10568.     public boolean isFearImmune()
  10569.     {
  10570.         return false;
  10571.     }
  10572.    
  10573.     /**
  10574.      * Restore hpmp.
  10575.      */
  10576.     public void restoreHPMP()
  10577.     {
  10578.         getStatus().setCurrentHpMp(getMaxHp(), getMaxMp());
  10579.     }
  10580.    
  10581.     /**
  10582.      * Restore cp.
  10583.      */
  10584.     public void restoreCP()
  10585.     {
  10586.         getStatus().setCurrentCp(getMaxCp());
  10587.     }
  10588.    
  10589.     /**
  10590.      * Block.
  10591.      */
  10592.     public void block()
  10593.     {
  10594.         _blocked = true;
  10595.     }
  10596.    
  10597.     /**
  10598.      * Unblock.
  10599.      */
  10600.     public void unblock()
  10601.     {
  10602.         _blocked = false;
  10603.     }
  10604.    
  10605.     /**
  10606.      * Checks if is blocked.
  10607.      * @return true, if is blocked
  10608.      */
  10609.     public boolean isBlocked()
  10610.     {
  10611.         return _blocked;
  10612.     }
  10613.    
  10614.     /**
  10615.      * Checks if is meditated.
  10616.      * @return true, if is meditated
  10617.      */
  10618.     public boolean isMeditated()
  10619.     {
  10620.         return _meditated;
  10621.     }
  10622.    
  10623.     /**
  10624.      * Sets the meditated.
  10625.      * @param meditated the new meditated
  10626.      */
  10627.     public void setMeditated(final boolean meditated)
  10628.     {
  10629.         _meditated = meditated;
  10630.     }
  10631.    
  10632.     /**
  10633.      * Update attack stance.
  10634.      */
  10635.     public void updateAttackStance()
  10636.     {
  10637.         attackStance = System.currentTimeMillis();
  10638.     }
  10639.    
  10640.     /**
  10641.      * Gets the attack stance.
  10642.      * @return the attack stance
  10643.      */
  10644.     public long getAttackStance()
  10645.     {
  10646.         return attackStance;
  10647.     }
  10648.    
  10649.     /** The _petrified. */
  10650.     private boolean _petrified = false;
  10651.    
  10652.     /**
  10653.      * Checks if is petrified.
  10654.      * @return the petrified
  10655.      */
  10656.     public boolean isPetrified()
  10657.     {
  10658.         return _petrified;
  10659.     }
  10660.    
  10661.     /**
  10662.      * Sets the petrified.
  10663.      * @param petrified the petrified to set
  10664.      */
  10665.     public void setPetrified(final boolean petrified)
  10666.     {
  10667.         if (petrified)
  10668.         {
  10669.             setIsParalyzed(petrified);
  10670.             setIsInvul(petrified);
  10671.             _petrified = petrified;
  10672.         }
  10673.         else
  10674.         {
  10675.             _petrified = petrified;
  10676.             setIsParalyzed(petrified);
  10677.             setIsInvul(petrified);
  10678.         }
  10679.     }
  10680.    
  10681.     /**
  10682.      * Check bss.
  10683.      * @return true, if successful
  10684.      */
  10685.     public boolean checkBss()
  10686.     {
  10687.        
  10688.         boolean bss = false;
  10689.        
  10690.         final L2ItemInstance weaponInst = this.getActiveWeaponInstance();
  10691.        
  10692.         if (weaponInst != null)
  10693.         {
  10694.             if (weaponInst.getChargedSpiritshot() == L2ItemInstance.CHARGED_BLESSED_SPIRITSHOT)
  10695.             {
  10696.                 bss = true;
  10697.                 // ponInst.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  10698.             }
  10699.            
  10700.         }
  10701.         // If there is no weapon equipped, check for an active summon.
  10702.         else if (this instanceof L2Summon)
  10703.         {
  10704.             final L2Summon activeSummon = (L2Summon) this;
  10705.            
  10706.             if (activeSummon.getChargedSpiritShot() == L2ItemInstance.CHARGED_BLESSED_SPIRITSHOT)
  10707.             {
  10708.                 bss = true;
  10709.                 // activeSummon.setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  10710.             }
  10711.            
  10712.         }
  10713.        
  10714.         return bss;
  10715.     }
  10716.    
  10717.     /**
  10718.      * Removes the bss.
  10719.      */
  10720.     synchronized public void removeBss()
  10721.     {
  10722.        
  10723.         final L2ItemInstance weaponInst = this.getActiveWeaponInstance();
  10724.        
  10725.         if (weaponInst != null)
  10726.         {
  10727.             if (weaponInst.getChargedSpiritshot() == L2ItemInstance.CHARGED_BLESSED_SPIRITSHOT)
  10728.             {
  10729.                 weaponInst.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  10730.             }
  10731.            
  10732.         }
  10733.         // If there is no weapon equipped, check for an active summon.
  10734.         else if (this instanceof L2Summon)
  10735.         {
  10736.             final L2Summon activeSummon = (L2Summon) this;
  10737.            
  10738.             if (activeSummon.getChargedSpiritShot() == L2ItemInstance.CHARGED_BLESSED_SPIRITSHOT)
  10739.             {
  10740.                 activeSummon.setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  10741.             }
  10742.            
  10743.         }
  10744.        
  10745.         reloadShots(true);
  10746.     }
  10747.    
  10748.     /**
  10749.      * Check sps.
  10750.      * @return true, if successful
  10751.      */
  10752.     public boolean checkSps()
  10753.     {
  10754.        
  10755.         boolean ss = false;
  10756.        
  10757.         final L2ItemInstance weaponInst = this.getActiveWeaponInstance();
  10758.        
  10759.         if (weaponInst != null)
  10760.         {
  10761.             if (weaponInst.getChargedSpiritshot() == L2ItemInstance.CHARGED_SPIRITSHOT)
  10762.             {
  10763.                 ss = true;
  10764.                 // weaponInst.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  10765.             }
  10766.         }
  10767.         // If there is no weapon equipped, check for an active summon.
  10768.         else if (this instanceof L2Summon)
  10769.         {
  10770.             final L2Summon activeSummon = (L2Summon) this;
  10771.            
  10772.             if (activeSummon.getChargedSpiritShot() == L2ItemInstance.CHARGED_SPIRITSHOT)
  10773.             {
  10774.                 ss = true;
  10775.                 // activeSummon.setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  10776.             }
  10777.         }
  10778.        
  10779.         return ss;
  10780.        
  10781.     }
  10782.    
  10783.     /**
  10784.      * Removes the sps.
  10785.      */
  10786.     synchronized public void removeSps()
  10787.     {
  10788.        
  10789.         final L2ItemInstance weaponInst = this.getActiveWeaponInstance();
  10790.        
  10791.         if (weaponInst != null)
  10792.         {
  10793.             if (weaponInst.getChargedSpiritshot() == L2ItemInstance.CHARGED_SPIRITSHOT)
  10794.             {
  10795.                 weaponInst.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  10796.             }
  10797.         }
  10798.         // If there is no weapon equipped, check for an active summon.
  10799.         else if (this instanceof L2Summon)
  10800.         {
  10801.             final L2Summon activeSummon = (L2Summon) this;
  10802.            
  10803.             if (activeSummon.getChargedSpiritShot() == L2ItemInstance.CHARGED_SPIRITSHOT)
  10804.             {
  10805.                 activeSummon.setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  10806.             }
  10807.         }
  10808.        
  10809.         reloadShots(true);
  10810.     }
  10811.    
  10812.     /**
  10813.      * Check ss.
  10814.      * @return true, if successful
  10815.      */
  10816.     public boolean checkSs()
  10817.     {
  10818.        
  10819.         boolean ss = false;
  10820.        
  10821.         final L2ItemInstance weaponInst = this.getActiveWeaponInstance();
  10822.        
  10823.         if (weaponInst != null)
  10824.         {
  10825.             if (weaponInst.getChargedSoulshot() == L2ItemInstance.CHARGED_SOULSHOT)
  10826.             {
  10827.                 ss = true;
  10828.                 // weaponInst.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  10829.             }
  10830.         }
  10831.         // If there is no weapon equipped, check for an active summon.
  10832.         else if (this instanceof L2Summon)
  10833.         {
  10834.             final L2Summon activeSummon = (L2Summon) this;
  10835.            
  10836.             if (activeSummon.getChargedSoulShot() == L2ItemInstance.CHARGED_SOULSHOT)
  10837.             {
  10838.                 ss = true;
  10839.                 // activeSummon.setChargedSpiritShot(L2ItemInstance.CHARGED_NONE);
  10840.             }
  10841.         }
  10842.        
  10843.         return ss;
  10844.        
  10845.     }
  10846.    
  10847.     /**
  10848.      * Removes the ss.
  10849.      */
  10850.     public void removeSs()
  10851.     {
  10852.        
  10853.         final L2ItemInstance weaponInst = this.getActiveWeaponInstance();
  10854.        
  10855.         if (weaponInst != null)
  10856.         {
  10857.             if (weaponInst.getChargedSoulshot() == L2ItemInstance.CHARGED_SOULSHOT)
  10858.             {
  10859.                 weaponInst.setChargedSoulshot(L2ItemInstance.CHARGED_NONE);
  10860.             }
  10861.         }
  10862.         // If there is no weapon equipped, check for an active summon.
  10863.         else if (this instanceof L2Summon)
  10864.         {
  10865.             final L2Summon activeSummon = (L2Summon) this;
  10866.            
  10867.             if (activeSummon.getChargedSoulShot() == L2ItemInstance.CHARGED_SOULSHOT)
  10868.             {
  10869.                 activeSummon.setChargedSoulShot(L2ItemInstance.CHARGED_NONE);
  10870.             }
  10871.         }
  10872.         reloadShots(false);
  10873.     }
  10874.    
  10875.     /**
  10876.      * Return a multiplier based on weapon random damage<BR>
  10877.      * <BR>
  10878.      * .
  10879.      * @return the random damage multiplier
  10880.      */
  10881.     public final double getRandomDamageMultiplier()
  10882.     {
  10883.         final L2Weapon activeWeapon = getActiveWeaponItem();
  10884.         int random;
  10885.        
  10886.         if (activeWeapon != null)
  10887.             random = activeWeapon.getRandomDamage();
  10888.         else
  10889.             random = 5 + (int) Math.sqrt(getLevel());
  10890.        
  10891.         return (1 + ((double) Rnd.get(0 - random, random) / 100));
  10892.     }
  10893.    
  10894.     /**
  10895.      * Sets the checks if is buff protected.
  10896.      * @param value the new checks if is buff protected
  10897.      */
  10898.     public final void setIsBuffProtected(final boolean value)
  10899.     {
  10900.         _isBuffProtected = value;
  10901.     }
  10902.    
  10903.     /**
  10904.      * Checks if is buff protected.
  10905.      * @return true, if is buff protected
  10906.      */
  10907.     public boolean isBuffProtected()
  10908.     {
  10909.         return _isBuffProtected;
  10910.     }
  10911.    
  10912.     /**
  10913.      * Gets the _triggered skills.
  10914.      * @return the _triggeredSkills
  10915.      */
  10916.     public Map<Integer, L2Skill> get_triggeredSkills()
  10917.     {
  10918.         return _triggeredSkills;
  10919.     }
  10920.    
  10921.     /**
  10922.      * Set target of L2Attackable and update it.
  10923.      * @author: Nefer
  10924.      * @param trasformedNpc
  10925.      */
  10926.     public void setTargetTrasformedNpc(final L2Attackable trasformedNpc)
  10927.     {
  10928.         if (trasformedNpc == null)
  10929.             return;
  10930.        
  10931.         // Set the target of the L2PcInstance player
  10932.         this.setTarget(trasformedNpc);
  10933.        
  10934.         // Send a Server->Client packet MyTargetSelected to the L2PcInstance player
  10935.         // The player.getLevel() - getLevel() permit to display the correct color in the select window
  10936.         MyTargetSelected my = new MyTargetSelected(trasformedNpc.getObjectId(), this.getLevel() - trasformedNpc.getLevel());
  10937.         this.sendPacket(my);
  10938.         my = null;
  10939.        
  10940.         // Send a Server->Client packet StatusUpdate of the L2NpcInstance to the L2PcInstance to update its HP bar
  10941.         StatusUpdate su = new StatusUpdate(trasformedNpc.getObjectId());
  10942.         su.addAttribute(StatusUpdate.CUR_HP, (int) trasformedNpc.getCurrentHp());
  10943.         su.addAttribute(StatusUpdate.MAX_HP, trasformedNpc.getMaxHp());
  10944.         this.sendPacket(su);
  10945.         su = null;
  10946.     }
  10947.    
  10948.     /**
  10949.      * @return if the object can be killed
  10950.      */
  10951.     public boolean isUnkillable()
  10952.     {
  10953.         return _isUnkillable;
  10954.     }
  10955.    
  10956.     /**
  10957.      * @param value the _isKillable to set
  10958.      */
  10959.     public void setIsUnkillable(final boolean value)
  10960.     {
  10961.         _isUnkillable = value;
  10962.     }
  10963.    
  10964.     /**
  10965.      * @return the _isAttackDisabled
  10966.      */
  10967.     public boolean isAttackDisabled()
  10968.     {
  10969.         return _isAttackDisabled;
  10970.     }
  10971.    
  10972.     /**
  10973.      * @param value the _isAttackDisabled to set
  10974.      */
  10975.     public void setIsAttackDisabled(final boolean value)
  10976.     {
  10977.         _isAttackDisabled = value;
  10978.     }
  10979.    
  10980.     /*
  10981.      * AI not. Task
  10982.      */
  10983.     static class notifyAiTaskDelayed implements Runnable
  10984.     {
  10985.        
  10986.         CtrlEvent event;
  10987.         Object object;
  10988.         L2Object tgt;
  10989.        
  10990.         notifyAiTaskDelayed(final CtrlEvent evt, final Object obj, final L2Object target)
  10991.         {
  10992.             event = evt;
  10993.             object = obj;
  10994.             tgt = target;
  10995.         }
  10996.        
  10997.         @Override
  10998.         public void run()
  10999.         {
  11000.             ((L2Character) tgt).getAI().notifyEvent(event, object);
  11001.         }
  11002.        
  11003.     }
  11004.    
  11005.     synchronized public void reloadShots(final boolean isMagic)
  11006.     {
  11007.         if (this instanceof L2PcInstance)
  11008.         {
  11009.             ((L2PcInstance) this).rechargeAutoSoulShot(!isMagic, isMagic, false);
  11010.         }
  11011.         else if (this instanceof L2Summon)
  11012.         {
  11013.             ((L2Summon) this).getOwner().rechargeAutoSoulShot(!isMagic, isMagic, true);
  11014.         }
  11015.     }
  11016. }
  11017.  
Tags: L2Character
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement