Advertisement
Guest User

Untitled

a guest
Mar 5th, 2015
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 356.64 KB | None | 0 0
  1. /*
  2.  * This program is free software; you can redistribute it and/or modify
  3.  * it under the terms of the GNU General Public License as published by
  4.  * the Free Software Foundation; either version 2, or (at your option)
  5.  * any later version.
  6.  *
  7.  * This program is distributed in the hope that it will be useful,
  8.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  * GNU General Public License for more details.
  11.  *
  12.  * You should have received a copy of the GNU General Public License
  13.  * along with this program; if not, write to the Free Software
  14.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  15.  * 02111-1307, USA.
  16.  *
  17.  * http://www.gnu.org/copyleft/gpl.html
  18.  */
  19. package net.sf.l2j.gameserver.model.actor.instance;
  20.  
  21. import java.sql.PreparedStatement;
  22. import java.sql.ResultSet;
  23. import java.util.Calendar;
  24. import java.util.Collection;
  25. import java.util.LinkedList;
  26. import java.util.List;
  27. import java.util.Map;
  28. import java.util.Set;
  29. import java.util.concurrent.Future;
  30. import java.util.concurrent.ScheduledFuture;
  31. import java.util.concurrent.TimeUnit;
  32. import java.util.concurrent.locks.ReentrantLock;
  33. import java.util.logging.Level;
  34.  
  35. import javolution.util.FastList;
  36. import javolution.util.FastMap;
  37. import javolution.util.FastSet;
  38. import net.sf.l2j.Config;
  39. import net.sf.l2j.L2DatabaseFactory;
  40. import net.sf.l2j.gameserver.ClientThread;
  41. import net.sf.l2j.gameserver.Connection;
  42. import net.sf.l2j.gameserver.GameTimeController;
  43. import net.sf.l2j.gameserver.GeoData;
  44. import net.sf.l2j.gameserver.ItemsAutoDestroy;
  45. import net.sf.l2j.gameserver.LoginServerThread;
  46. import net.sf.l2j.gameserver.Olympiad;
  47. import net.sf.l2j.gameserver.RecipeController;
  48. import net.sf.l2j.gameserver.SevenSignsFestival;
  49. import net.sf.l2j.gameserver.ThreadPoolManager;
  50. import net.sf.l2j.gameserver.Universe;
  51. import net.sf.l2j.gameserver.ai.CtrlIntention;
  52. import net.sf.l2j.gameserver.ai.L2CharacterAI;
  53. import net.sf.l2j.gameserver.ai.L2PlayerAI;
  54. import net.sf.l2j.gameserver.ai.L2SummonAI;
  55. import net.sf.l2j.gameserver.cache.HtmCache;
  56. import net.sf.l2j.gameserver.cache.WarehouseCacheManager;
  57. import net.sf.l2j.gameserver.communitybbs.BB.Forum;
  58. import net.sf.l2j.gameserver.communitybbs.Manager.ForumsBBSManager;
  59. import net.sf.l2j.gameserver.datatables.CharTemplateTable;
  60. import net.sf.l2j.gameserver.datatables.ClanTable;
  61. import net.sf.l2j.gameserver.datatables.FishTable;
  62. import net.sf.l2j.gameserver.datatables.GmListTable;
  63. import net.sf.l2j.gameserver.datatables.HennaTable;
  64. import net.sf.l2j.gameserver.datatables.ItemTable;
  65. import net.sf.l2j.gameserver.datatables.MapRegionTable;
  66. import net.sf.l2j.gameserver.datatables.NobleSkillTable;
  67. import net.sf.l2j.gameserver.datatables.NpcTable;
  68. import net.sf.l2j.gameserver.datatables.SkillTable;
  69. import net.sf.l2j.gameserver.datatables.SkillTreeTable;
  70. import net.sf.l2j.gameserver.handler.IItemHandler;
  71. import net.sf.l2j.gameserver.handler.ItemHandler;
  72. import net.sf.l2j.gameserver.instancemanager.CastleManager;
  73. import net.sf.l2j.gameserver.instancemanager.DimensionalRiftManager;
  74. import net.sf.l2j.gameserver.instancemanager.ItemsOnGroundManager;
  75. import net.sf.l2j.gameserver.instancemanager.QuestManager;
  76. import net.sf.l2j.gameserver.instancemanager.SiegeManager;
  77. import net.sf.l2j.gameserver.lib.Rnd;
  78. import net.sf.l2j.gameserver.model.BlockList;
  79. import net.sf.l2j.gameserver.model.FishData;
  80. import net.sf.l2j.gameserver.model.Inventory;
  81. import net.sf.l2j.gameserver.model.ItemContainer;
  82. import net.sf.l2j.gameserver.model.L2Attackable;
  83. import net.sf.l2j.gameserver.model.L2CharPosition;
  84. import net.sf.l2j.gameserver.model.L2Character;
  85. import net.sf.l2j.gameserver.model.L2Clan;
  86. import net.sf.l2j.gameserver.model.L2ClanMember;
  87. import net.sf.l2j.gameserver.model.L2DropData;
  88. import net.sf.l2j.gameserver.model.L2Effect;
  89. import net.sf.l2j.gameserver.model.L2Fishing;
  90. import net.sf.l2j.gameserver.model.L2HennaInstance;
  91. import net.sf.l2j.gameserver.model.L2ItemInstance;
  92. import net.sf.l2j.gameserver.model.L2Macro;
  93. import net.sf.l2j.gameserver.model.L2ManufactureList;
  94. import net.sf.l2j.gameserver.model.L2Object;
  95. import net.sf.l2j.gameserver.model.L2Party;
  96. import net.sf.l2j.gameserver.model.L2PetData;
  97. import net.sf.l2j.gameserver.model.L2PetDataTable;
  98. import net.sf.l2j.gameserver.model.L2Radar;
  99. import net.sf.l2j.gameserver.model.L2RecipeList;
  100. import net.sf.l2j.gameserver.model.L2Request;
  101. import net.sf.l2j.gameserver.model.L2ShortCut;
  102. import net.sf.l2j.gameserver.model.L2Skill;
  103. import net.sf.l2j.gameserver.model.L2Skill.SkillTargetType;
  104. import net.sf.l2j.gameserver.model.L2Skill.SkillType;
  105. import net.sf.l2j.gameserver.model.L2SkillLearn;
  106. import net.sf.l2j.gameserver.model.L2Summon;
  107. import net.sf.l2j.gameserver.model.L2World;
  108. import net.sf.l2j.gameserver.model.L2WorldRegion;
  109. import net.sf.l2j.gameserver.model.MacroList;
  110. import net.sf.l2j.gameserver.model.PartyMatchRoom;
  111. import net.sf.l2j.gameserver.model.PartyMatchRoomList;
  112. import net.sf.l2j.gameserver.model.PcFreight;
  113. import net.sf.l2j.gameserver.model.PcInventory;
  114. import net.sf.l2j.gameserver.model.PcWarehouse;
  115. import net.sf.l2j.gameserver.model.PetInventory;
  116. import net.sf.l2j.gameserver.model.ShortCuts;
  117. import net.sf.l2j.gameserver.model.TradeList;
  118. import net.sf.l2j.gameserver.model.actor.appearance.PcAppearance;
  119. import net.sf.l2j.gameserver.model.actor.knownlist.PcKnownList;
  120. import net.sf.l2j.gameserver.model.actor.stat.PcStat;
  121. import net.sf.l2j.gameserver.model.actor.status.PcStatus;
  122. import net.sf.l2j.gameserver.model.base.ClassId;
  123. import net.sf.l2j.gameserver.model.base.Experience;
  124. import net.sf.l2j.gameserver.model.base.Race;
  125. import net.sf.l2j.gameserver.model.base.SubClass;
  126. import net.sf.l2j.gameserver.model.entity.Castle;
  127. import net.sf.l2j.gameserver.model.entity.Hero;
  128. import net.sf.l2j.gameserver.model.entity.L2Event;
  129. import net.sf.l2j.gameserver.model.entity.Siege;
  130. import net.sf.l2j.gameserver.model.entity.TvTEvent;
  131. import net.sf.l2j.gameserver.model.quest.Quest;
  132. import net.sf.l2j.gameserver.model.quest.QuestState;
  133. import net.sf.l2j.gameserver.serverpackets.ActionFailed;
  134. import net.sf.l2j.gameserver.serverpackets.ChangeWaitType;
  135. import net.sf.l2j.gameserver.serverpackets.CharInfo;
  136. import net.sf.l2j.gameserver.serverpackets.ConfirmDlg;
  137. import net.sf.l2j.gameserver.serverpackets.EtcStatusUpdate;
  138. import net.sf.l2j.gameserver.serverpackets.ExAutoSoulShot;
  139. import net.sf.l2j.gameserver.serverpackets.ExFishingEnd;
  140. import net.sf.l2j.gameserver.serverpackets.ExFishingStart;
  141. import net.sf.l2j.gameserver.serverpackets.ExOlympiadMatchEnd;
  142. import net.sf.l2j.gameserver.serverpackets.ExOlympiadMode;
  143. import net.sf.l2j.gameserver.serverpackets.ExOlympiadSpelledInfo;
  144. import net.sf.l2j.gameserver.serverpackets.ExStorageMaxCount;
  145. import net.sf.l2j.gameserver.serverpackets.FriendList;
  146. import net.sf.l2j.gameserver.serverpackets.HennaInfo;
  147. import net.sf.l2j.gameserver.serverpackets.InventoryUpdate;
  148. import net.sf.l2j.gameserver.serverpackets.ItemList;
  149. import net.sf.l2j.gameserver.serverpackets.MagicEffectIcons;
  150. import net.sf.l2j.gameserver.serverpackets.MagicSkillCanceld;
  151. import net.sf.l2j.gameserver.serverpackets.MyTargetSelected;
  152. import net.sf.l2j.gameserver.serverpackets.NicknameChanged;
  153. import net.sf.l2j.gameserver.serverpackets.NpcHtmlMessage;
  154. import net.sf.l2j.gameserver.serverpackets.ObservationMode;
  155. import net.sf.l2j.gameserver.serverpackets.ObservationReturn;
  156. import net.sf.l2j.gameserver.serverpackets.PartySmallWindowUpdate;
  157. import net.sf.l2j.gameserver.serverpackets.PartySpelled;
  158. import net.sf.l2j.gameserver.serverpackets.PetInventoryUpdate;
  159. import net.sf.l2j.gameserver.serverpackets.PledgeShowMemberListUpdate;
  160. import net.sf.l2j.gameserver.serverpackets.PrivateStoreListBuy;
  161. import net.sf.l2j.gameserver.serverpackets.PrivateStoreListSell;
  162. import net.sf.l2j.gameserver.serverpackets.QuestList;
  163. import net.sf.l2j.gameserver.serverpackets.RecipeShopSellList;
  164. import net.sf.l2j.gameserver.serverpackets.RelationChanged;
  165. import net.sf.l2j.gameserver.serverpackets.Ride;
  166. import net.sf.l2j.gameserver.serverpackets.SendTradeDone;
  167. import net.sf.l2j.gameserver.serverpackets.ServerBasePacket;
  168. import net.sf.l2j.gameserver.serverpackets.SetupGauge;
  169. import net.sf.l2j.gameserver.serverpackets.ShortCutInit;
  170. import net.sf.l2j.gameserver.serverpackets.SkillList;
  171. import net.sf.l2j.gameserver.serverpackets.Snoop;
  172. import net.sf.l2j.gameserver.serverpackets.SocialAction;
  173. import net.sf.l2j.gameserver.serverpackets.StatusUpdate;
  174. import net.sf.l2j.gameserver.serverpackets.StopMove;
  175. import net.sf.l2j.gameserver.serverpackets.SystemMessage;
  176. import net.sf.l2j.gameserver.serverpackets.TargetSelected;
  177. import net.sf.l2j.gameserver.serverpackets.TargetUnselected;
  178. import net.sf.l2j.gameserver.serverpackets.TradeStart;
  179. import net.sf.l2j.gameserver.serverpackets.UserInfo;
  180. import net.sf.l2j.gameserver.serverpackets.ValidateLocation;
  181. import net.sf.l2j.gameserver.skills.BaseStats;
  182. import net.sf.l2j.gameserver.skills.Formulas;
  183. import net.sf.l2j.gameserver.skills.Stats;
  184. import net.sf.l2j.gameserver.templates.L2Armor;
  185. import net.sf.l2j.gameserver.templates.L2ArmorType;
  186. import net.sf.l2j.gameserver.templates.L2Henna;
  187. import net.sf.l2j.gameserver.templates.L2Item;
  188. import net.sf.l2j.gameserver.templates.L2PcTemplate;
  189. import net.sf.l2j.gameserver.templates.L2Weapon;
  190. import net.sf.l2j.gameserver.templates.L2WeaponType;
  191. import net.sf.l2j.gameserver.util.Broadcast;
  192. import net.sf.l2j.gameserver.util.FloodProtector;
  193. import net.sf.l2j.gameserver.util.Util;
  194. import net.sf.l2j.util.Point3D;
  195.  
  196. /**
  197.  * This class represents all player characters in the world.
  198.  * There is always a client-thread connected to this (except if a player-store is activated upon logout).<BR><BR>
  199.  *
  200.  * @version $Revision: 1.66.2.41.2.33 $ $Date: 2005/04/11 10:06:09 $
  201.  */
  202. public final class L2PcInstance extends L2PlayableInstance
  203. {
  204.     private static final String RESTORE_SKILLS_FOR_CHAR = "SELECT skill_id,skill_level FROM character_skills WHERE char_obj_id=? AND class_index=?";
  205.     private static final String RESTORE_SKILLS_FOR_CHAR_ALT_SUBCLASS = "SELECT skill_id,skill_level FROM character_skills WHERE char_obj_id=? ORDER BY skill_id";
  206.  
  207.     private static final String ADD_NEW_SKILL = "INSERT INTO character_skills (char_obj_id,skill_id,skill_level,skill_name,class_index) VALUES (?,?,?,?,?)";
  208.     private static final String UPDATE_CHARACTER_SKILL_LEVEL = "UPDATE character_skills SET skill_level=? WHERE skill_id=? AND char_obj_id=? AND class_index=?";
  209.     private static final String DELETE_SKILL_FROM_CHAR = "DELETE FROM character_skills WHERE skill_id=? AND char_obj_id=? AND class_index=?";
  210.     private static final String DELETE_CHAR_SKILLS = "DELETE FROM character_skills WHERE char_obj_id=? AND class_index=?";
  211.  
  212.     private static final String ADD_SKILL_SAVE = "INSERT INTO character_skills_save (char_obj_id,skill_id,skill_level,effect_count,effect_cur_time,reuse_delay,systime,restore_type,class_index,buff_index) VALUES (?,?,?,?,?,?,?,?,?,?)";
  213.     private static final String RESTORE_SKILL_SAVE = "SELECT skill_id,skill_level,effect_count,effect_cur_time,reuse_delay,systime FROM character_skills_save WHERE char_obj_id=? AND class_index=? AND restore_type=? ORDER BY buff_index ASC";
  214.     private static final String RESTORE_SKILL_SAVE_ALT_SUBCLASS = "SELECT skill_id,reuse_delay,systime FROM character_skills_save WHERE char_obj_id=? AND restore_type=? ORDER BY buff_index ASC";
  215.     private static final String DELETE_SKILL_SAVE = "DELETE FROM character_skills_save WHERE char_obj_id=? AND class_index=?";
  216.  
  217.     private static final String UPDATE_CHARACTER = "UPDATE characters SET level=?,maxHp=?,curHp=?,maxCp=?,curCp=?,maxMp=?,curMp=?,str=?,con=?,dex=?,_int=?,men=?,wit=?,face=?,hairStyle=?,hairColor=?,sex=?,heading=?,x=?,y=?,z=?,exp=?,sp=?,karma=?,pvpkills=?,pkkills=?,rec_have=?,rec_left=?,clanid=?,maxload=?,race=?,classid=?,deletetime=?,title=?,accesslevel=?,online=?,clan_privs=?,wantspeace=?,clan_join_expiry_time=?,clan_create_expiry_time=?,base_class=?,onlinetime=?,in_jail=?,jail_timer=?,newbie=?,nobless=?,last_recom_date=?,varka_ketra_ally=?,char_name=? WHERE obj_Id=?";
  218.     private static final String RESTORE_CHARACTER = "SELECT account_name, obj_Id, char_name, level, maxHp, curHp, maxCp, curCp, maxMp, curMp, acc, crit, evasion, mAtk, mDef, mSpd, pAtk, pDef, pSpd, runSpd, walkSpd, str, con, dex, _int, men, wit, face, hairStyle, hairColor, sex, heading, x, y, z, movement_multiplier, attack_speed_multiplier, colRad, colHeight, exp, sp, karma, pvpkills, pkkills, clanid, maxload, race, classid, deletetime, cancraft, title, rec_have, rec_left, accesslevel, online, char_slot, lastAccess, clan_privs, wantspeace, clan_join_expiry_time, clan_create_expiry_time, base_class, onlinetime, in_jail, jail_timer, newbie, nobless, last_recom_date, varka_ketra_ally FROM characters WHERE obj_Id=?";
  219.     private static final String RESTORE_CHAR_SUBCLASSES = "SELECT class_id,exp,sp,level,class_index FROM character_subclasses WHERE char_obj_id=? ORDER BY class_index ASC";
  220.     private static final String ADD_CHAR_SUBCLASS = "INSERT INTO character_subclasses (char_obj_id,class_id,exp,sp,level,class_index) VALUES (?,?,?,?,?,?)";
  221.     private static final String UPDATE_CHAR_SUBCLASS = "UPDATE character_subclasses SET exp=?,sp=?,level=?,class_id=? WHERE char_obj_id=? AND class_index =?";
  222.     private static final String DELETE_CHAR_SUBCLASS = "DELETE FROM character_subclasses WHERE char_obj_id=? AND class_index=?";
  223.  
  224.     private static final String RESTORE_CHAR_HENNAS = "SELECT slot,symbol_id FROM character_hennas WHERE char_obj_id=? AND class_index=?";
  225.     private static final String ADD_CHAR_HENNA = "INSERT INTO character_hennas (char_obj_id,symbol_id,slot,class_index) VALUES (?,?,?,?)";
  226.     private static final String DELETE_CHAR_HENNA = "DELETE FROM character_hennas WHERE char_obj_id=? AND slot=? AND class_index=?";
  227.     private static final String DELETE_CHAR_HENNAS = "DELETE FROM character_hennas WHERE char_obj_id=? AND class_index=?";
  228.     private static final String DELETE_CHAR_SHORTCUTS = "DELETE FROM character_shortcuts WHERE char_obj_id=? AND class_index=?";
  229.  
  230.     private static final String RESTORE_CHAR_RECOMS = "SELECT char_id,target_id FROM character_recommends WHERE char_id=?";
  231.     private static final String ADD_CHAR_RECOM = "INSERT INTO character_recommends (char_id,target_id) VALUES (?,?)";
  232.     private static final String DELETE_CHAR_RECOMS = "DELETE FROM character_recommends WHERE char_id=?";
  233.  
  234.     public static final int REQUEST_TIMEOUT = 15;
  235.  
  236.     public static final int STORE_PRIVATE_NONE = 0;
  237.     public static final int STORE_PRIVATE_SELL = 1;
  238.     public static final int STORE_PRIVATE_BUY = 3;
  239.     public static final int STORE_PRIVATE_MANUFACTURE = 5;
  240.     public static final int STORE_PRIVATE_PACKAGE_SELL = 8;
  241.  
  242.     /** The table containing all minimum level needed for each Expertise (None, D, C, B, A, S)*/
  243.     private static final int[] EXPERTISE_LEVELS =
  244.     {
  245.         SkillTreeTable.getInstance().getExpertiseLevel(0), //NONE
  246.         SkillTreeTable.getInstance().getExpertiseLevel(1), //D
  247.         SkillTreeTable.getInstance().getExpertiseLevel(2), //C
  248.         SkillTreeTable.getInstance().getExpertiseLevel(3), //B
  249.         SkillTreeTable.getInstance().getExpertiseLevel(4), //A
  250.         SkillTreeTable.getInstance().getExpertiseLevel(5), //S
  251.     };
  252.  
  253.     private static final int[] COMMON_CRAFT_LEVELS =
  254.     {
  255.         5,20,28,36,43,49,55,62,70
  256.     };
  257.  
  258.     public class AIAccessor extends L2Character.AIAccessor
  259.     {
  260.         protected AIAccessor() {}
  261.  
  262.         public L2PcInstance getPlayer()
  263.         {
  264.  
  265.             return L2PcInstance.this;
  266.  
  267.         }
  268.  
  269.         public void doPickupItem(L2Object object)
  270.  
  271.         {
  272.             L2PcInstance.this.doPickupItem(object);
  273.         }
  274.  
  275.         public void doInteract(L2Character target)
  276.  
  277.         {
  278.             L2PcInstance.this.doInteract(target);
  279.         }
  280.  
  281.         public void doAttack(L2Character target)
  282.  
  283.         {
  284.             super.doAttack(target);
  285.  
  286.             // cancel the recent fake-death protection instantly if the player attacks or casts spells
  287.  
  288.             getPlayer().setRecentFakeDeath(false);
  289.             for (L2CubicInstance cubic : getCubics().values())
  290.             {
  291.                 if (cubic.getId() != L2CubicInstance.LIFE_CUBIC)
  292.                     cubic.doAction(target);
  293.             }
  294.  
  295.         }
  296.  
  297.  
  298.         public void doCast(L2Skill skill)
  299.  
  300.         {
  301.  
  302.             super.doCast(skill);
  303.  
  304.  
  305.             // cancel the recent fake-death protection instantly if the player attacks or casts spells
  306.  
  307.             getPlayer().setRecentFakeDeath(false);
  308.  
  309.             if (skill == null)
  310.                 return;
  311.  
  312.  
  313.             if(!skill.isOffensive())
  314.                 return;
  315.  
  316.  
  317.             L2Object mainTarget = skill.getFirstOfTargetList(L2PcInstance.this);
  318.  
  319.             // the code doesn't now support multiple targets
  320.  
  321.             if (mainTarget == null || !(mainTarget instanceof L2Character))
  322.                 return;
  323.  
  324.  
  325.             for (L2CubicInstance cubic : getCubics().values())
  326.             {
  327.  
  328.                 if (cubic.getId() != L2CubicInstance.LIFE_CUBIC)
  329.  
  330.                     cubic.doAction((L2Character)mainTarget);
  331.             }
  332.  
  333.         }
  334.     }
  335.  
  336.     private Connection _connection;
  337.  
  338.     private PcAppearance _appearance;
  339.  
  340.     /** The Identifier of the L2PcInstance */
  341.     private int _charId = 0x00030b7a;
  342.  
  343.     /** Last NPC Id talked on a quest */
  344.     private int _questNpcObject = 0;
  345.  
  346.     /** The Experience of the L2PcInstance before the last Death Penalty */
  347.     private long _expBeforeDeath = 0;
  348.  
  349.     private int _charges = 0;
  350.  
  351.     private int _curWeightPenalty = 0;
  352.  
  353.     /** The Siege state of the L2PcInstance */
  354.     private byte _siegeState = 0;
  355.  
  356.     private int _clanPrivileges = 0;
  357.  
  358.     public int _telemode = 0;
  359.  
  360.     /** The PvP Flag state of the L2PcInstance (0=White, 1=Purple) */
  361.     private int _pvpFlag;
  362.  
  363.     /** The Karma of the L2PcInstance (if higher than 0, the name of the L2PcInstance appears in red) */
  364.     private int _karma;
  365.  
  366.     /** The number of player killed during a PvP (the player killed was PvP Flagged) */
  367.     private int _pvpKills;
  368.  
  369.     /** The PK counter of the L2PcInstance (= Number of non PvP Flagged player killed) */
  370.     private int _pkKills;
  371.  
  372.     /** The number of recommendation obtained by the L2PcInstance */
  373.     private int _recomHave; // how much I was recommended by others
  374.  
  375.     /** The number of recommendation that the L2PcInstance can give */
  376.     private int _recomLeft; // how many recomendations I can give to others
  377.  
  378.  
  379.     /** Date when recom points were updated last time */
  380.     private long _lastRecomUpdate;
  381.  
  382.     /** List with the recomendations that I've give */
  383.     private List<Integer> _recomChars = new FastList<>();
  384.  
  385.     // Friend list
  386.     private List<Friend> _friendList = new FastList<>();
  387.  
  388.     private long _deleteTimer;
  389.     private PcInventory _inventory = new PcInventory(this);
  390.     private PcWarehouse _warehouse;
  391.     private PcFreight _freight = new PcFreight(this);
  392.  
  393.     /** True if the L2PcInstance is sitting */
  394.     private boolean _waitTypeSitting;
  395.  
  396.     /** True if the L2PcInstance is using the relax skill */
  397.     private boolean _relax;
  398.  
  399.     /** Novice State */
  400.     public static int NONE = 0;
  401.     public static int NEW = 1;
  402.     public static int OLD = 2;
  403.     private int _newbieState = 0;
  404.  
  405.     /** The table containing all Quests began by the L2PcInstance */
  406.     private Map<String, QuestState> _quests = new FastMap<>();
  407.  
  408.     /** The list containing all shortCuts of this L2PcInstance */
  409.     private ShortCuts _shortCuts = new ShortCuts(this);
  410.  
  411.     /** The list containing all macroses of this L2PcInstance */
  412.     private MacroList _macroses = new MacroList(this);
  413.  
  414.     private TradeList _activeTradeList;
  415.     private ItemContainer _activeWarehouse;
  416.     private L2ManufactureList _createList;
  417.     private TradeList _sellList;
  418.     private TradeList _buyList;
  419.  
  420.     /** The Private Store type of the L2PcInstance (STORE_PRIVATE_NONE=0, STORE_PRIVATE_SELL=1, sellmanage=2, STORE_PRIVATE_BUY=3, buymanage=4, STORE_PRIVATE_MANUFACTURE=5) */
  421.     private int _privatestore;
  422.  
  423.     private List<L2PcInstance> _SnoopListener = new FastList<>();
  424.     private List<L2PcInstance> _SnoopedPlayer = new FastList<>();
  425.  
  426.  
  427.     private ClassId _skillLearningClassId;
  428.  
  429.     // hennas
  430.     private final L2HennaInstance[] _henna = new L2HennaInstance[3];
  431.     private int _hennaSTR;
  432.     private int _hennaINT;
  433.     private int _hennaDEX;
  434.     private int _hennaMEN;
  435.     private int _hennaWIT;
  436.     private int _hennaCON;
  437.  
  438.     /** The L2Summon of the L2PcInstance */
  439.     private L2Summon _summon = null;
  440.  
  441.     // apparently, a L2PcInstance CAN have both a summon AND a tamed beast at the same time!!
  442.     private L2TamedBeastInstance _tamedBeast = null;
  443.  
  444.     // client radar
  445.     //TODO: This needs to be better intergrated and saved/loaded
  446.     private L2Radar _radar;
  447.  
  448.     private L2Party _party;
  449.    
  450.     // Party matching
  451.     private int _partyroom = 0;
  452.  
  453.     /** The Clan Identifier of the L2PcInstance */
  454.     private int _clanId;
  455.  
  456.     /** The Clan object of the L2PcInstance */
  457.     private L2Clan _clan;
  458.  
  459.     private long _clanJoinExpiryTime;
  460.     private long _clanCreateExpiryTime;
  461.  
  462.  
  463.     private boolean _isGm;
  464.     private int _accessLevel;
  465.  
  466.     private boolean _chatBanned = false;        // Chat Banned
  467.     private ScheduledFuture _chatUnbanTask = null;
  468.     private boolean _messageRefusal = false;    // message refusal mode
  469.     private boolean _dietMode = false;          // ignore weight penalty
  470.     private boolean _tradeRefusal = false;       // Trade refusal
  471.     private boolean _exchangeRefusal = false;   // Exchange refusal
  472.  
  473.     public boolean _exploring = false;
  474.  
  475.     // this is needed to find the inviting player for Party response
  476.     // there can only be one active party request at once
  477.     private L2PcInstance _activeRequester;
  478.     private long _requestExpireTime = 0;
  479.     private L2Request _request = new L2Request(this);
  480.     private L2ItemInstance _arrowItem;
  481.  
  482.     // Used for protection after teleport
  483.     private long _protectEndTime = 0;
  484.  
  485.     // protects a char from agro mobs when getting up from fake death
  486.  
  487.     private long _recentFakeDeathEndTime = 0;
  488.  
  489.     /** The fists L2Weapon of the L2PcInstance (used when no weapon is equiped) */
  490.     private L2Weapon _fistsWeaponItem;
  491.  
  492.     private long _uptime;
  493.     private String _accountName;
  494.  
  495.     private final Map<Integer, String> _chars = new FastMap<>();
  496.  
  497.     public byte _updateKnownCounter = 0;
  498.  
  499.     /** The table containing all L2RecipeList of the L2PcInstance */
  500.     private Map<Integer, L2RecipeList> _dwarvenRecipeBook = new FastMap<>();
  501.     private Map<Integer, L2RecipeList> _commonRecipeBook = new FastMap<>();
  502.  
  503.     private int _mountType;
  504.     private int _mountNpcId;
  505.     private int _mountLevel;
  506.  
  507.     /** The current higher Expertise of the L2PcInstance (None=0, D=1, C=2, B=3, A=4, S=5)*/
  508.     private int _expertiseIndex; // index in EXPERTISE_LEVELS
  509.     private int _expertisePenalty = 0;
  510.  
  511.     private int _lootInvitation = -1;
  512.  
  513.     private L2ItemInstance _activeEnchantItem = null;
  514.  
  515.     // Online status
  516.     private long _onlineTime;
  517.     private long _onlineBeginTime;
  518.     private boolean _isOnline = false;
  519.  
  520.  
  521.     protected boolean _inventoryDisable = false;
  522.  
  523.     protected Map<Integer, L2CubicInstance> _cubics = new FastMap<Integer, L2CubicInstance>().shared();
  524.  
  525.     /** The L2FolkInstance corresponding to the last Folk wich one the player talked. */
  526.     private L2FolkInstance _lastFolkNpc = null;
  527.  
  528.     protected FastSet<Integer> _activeSoulShots = new FastSet<>();
  529.  
  530.  
  531.     /** Location before entering Observer Mode */
  532.     private int _obsX;
  533.     private int _obsY;
  534.     private int _obsZ;
  535.     private boolean _observerMode = false;
  536.  
  537.     /** Event parameters */
  538.     public int eventX;
  539.     public int eventY;
  540.     public int eventZ;
  541.     public int eventkarma;
  542.     public int eventpvpkills;
  543.     public int eventpkkills;
  544.     public String eventTitle;
  545.     public LinkedList<String> kills = new LinkedList<String>();
  546.     public boolean eventSitForced = false;
  547.     public boolean atEvent = false;
  548.  
  549.     /** new loto ticket **/
  550.     public int _loto[] = new int[5];
  551.     /** new race ticket **/
  552.     public int _race[] = new int[2];
  553.  
  554.     private final BlockList _blockList = new BlockList();
  555.  
  556.     private boolean _isConnected = true;
  557.     private boolean _inOfflineMode = false;
  558.     private long _offlineShopStart = 0;
  559.  
  560.     private boolean _hero;
  561.     private int _team = 0;
  562.     private int _wantsPeace = 0;
  563.  
  564.     private boolean _noble = false;
  565.  
  566.     private boolean _inOlympiadMode = false;
  567.     private boolean _OlympiadStart = false;
  568.     private int _olympiadGameId = -1;
  569.     private int _olympiadSide = -1;
  570.     public int dmgDealt = 0;
  571.  
  572.     /** lvl of alliance with ketra orcs or varka silenos, used in quests and aggro checks
  573.      *  [-5,-1] varka, 0 neutral, [1,5] ketra
  574.      */
  575.     private int _alliedVarkaKetra = 0;
  576.  
  577.     /** The list of sub-classes this character has. */
  578.  
  579.     private Map<Integer, SubClass> _subClasses;
  580.  
  581.     private final ReentrantLock _classLock = new ReentrantLock();
  582.     protected int _baseClass;
  583.     protected int _activeClass;
  584.     protected int _classIndex = 0;
  585.  
  586.     private long _lastAccess;
  587.     private int _boatId;
  588.  
  589.     /** data for mounted pets */
  590.     private boolean _canFeed;
  591.     private int _controlItemId;
  592.     private L2PetData _data;
  593.     private int _curFeed;
  594.     protected Future<?> _mountFeedTask;
  595.     private ScheduledFuture<?> _dismountTask;
  596.  
  597.     private L2Fishing _fishCombat;
  598.     private boolean _fishing = false;
  599.     private int _fishx = 0;
  600.     private int _fishy = 0;
  601.     private int _fishz = 0;
  602.  
  603.     private ScheduledFuture _taskRentPet;
  604.     private ScheduledFuture _taskWater;
  605.  
  606.     /** Boat */
  607.     private L2BoatInstance _boat = null;
  608.     private Point3D _inBoatPosition;
  609.  
  610.     /** Stored from last ValidatePosition **/
  611.     private Point3D _lastServerPosition = new Point3D(0, 0, 0);
  612.  
  613.     /** Previous coordinate sent to party in ValidatePosition **/
  614.     private Point3D _lastPartyPosition = new Point3D(0, 0, 0);
  615.  
  616.     // during fall validations will be disabled for 10 ms.
  617.     private static final int FALLING_VALIDATION_DELAY = 10000;
  618.     private long _fallingTimestamp = 0;
  619.  
  620.     /** Bypass validations */
  621.     private List<String> _validBypass = new FastList<>();
  622.     private List<String> _validBypass2 = new FastList<>();
  623.  
  624.     private boolean _inCrystallize;
  625.     private boolean _inCraftMode;
  626.     private Forum _forumMail;
  627.     private Forum _forumMemo;
  628.  
  629.     /** Current skill in use */
  630.     private SkillDat _currentSkill;
  631.     private SkillDat _currentPetSkill;
  632.  
  633.     /** Skills queued because a skill is already in progress */
  634.     private SkillDat _queuedSkill;
  635.  
  636.     /** Store object used to summon the strider you are mounting **/
  637.     private int _mountObjectID = 0;
  638.  
  639.     private boolean _inJail = false;
  640.     private long _jailTimer = 0;
  641.  
  642.     /** Flag to disable equipment/skills while wearing formal wear **/
  643.     private boolean _IsWearingFormalWear = false;
  644.  
  645.     private int _ReviveRequested = 0;
  646.     private double _RevivePower = 0;
  647.     private boolean _RevivePet = false;
  648.  
  649.     private double _cpUpdateIncCheck = .0;
  650.     private double _cpUpdateDecCheck = .0;
  651.     private double _cpUpdateInterval = .0;
  652.     private double _mpUpdateIncCheck = .0;
  653.     private double _mpUpdateDecCheck = .0;
  654.     private double _mpUpdateInterval = .0;
  655.  
  656.     private boolean _getGainXpSp = true;
  657.     private boolean _isPendingSitting = false;
  658.  
  659.     /** Skill casting information (used to queue when several skills are cast in a short time) **/
  660.     public class SkillDat
  661.     {
  662.         private L2Skill _skill;
  663.         private boolean _ctrlPressed;
  664.         private boolean _shiftPressed;
  665.  
  666.  
  667.         protected SkillDat(L2Skill skill, boolean ctrlPressed, boolean shiftPressed)
  668.         {
  669.             _skill = skill;
  670.             _ctrlPressed = ctrlPressed;
  671.             _shiftPressed = shiftPressed;
  672.         }
  673.  
  674.         public boolean isCtrlPressed()
  675.         {
  676.             return _ctrlPressed;
  677.         }
  678.  
  679.         public boolean isShiftPressed()
  680.         {
  681.             return _shiftPressed;
  682.         }
  683.  
  684.         public L2Skill getSkill()
  685.         {
  686.             return _skill;
  687.         }
  688.  
  689.  
  690.         public int getSkillId()
  691.         {
  692.             return (getSkill() != null) ? getSkill().getId() : -1;
  693.         }
  694.     }
  695.  
  696.     private gatesRequest _gatesRequest = new gatesRequest();
  697.  
  698.     public class gatesRequest
  699.     {
  700.         private L2DoorInstance _target = null;
  701.         public void setTarget(L2DoorInstance door)
  702.         {
  703.             _target = door;
  704.             return;
  705.         }
  706.  
  707.         public L2DoorInstance getDoor()
  708.         {
  709.             return _target;
  710.         }
  711.     }
  712.  
  713.     /**
  714.      * Create a new L2PcInstance and add it in the characters table of the database.<BR><BR>
  715.      *
  716.      * <B><U> Actions</U> :</B><BR><BR>
  717.      * <li>Create a new L2PcInstance with an account name </li>
  718.      * <li>Set the name, the Hair Style, the Hair Color and  the Face type of the L2PcInstance</li>
  719.      * <li>Add the player in the characters table of the database</li><BR><BR>
  720.      *
  721.      * @param objectId Identifier of the object to initialized
  722.      * @param template The L2PcTemplate to apply to the L2PcInstance
  723.      * @param accountName The name of the L2PcInstance
  724.      * @param name The name of the L2PcInstance
  725.      * @param hairStyle The hair style Identifier of the L2PcInstance
  726.      * @param hairColor The hair color Identifier of the L2PcInstance
  727.      * @param face The face type Identifier of the L2PcInstance
  728.      *
  729.      * @return The L2PcInstance added to the database or null
  730.      *
  731.      */
  732.     public static L2PcInstance create(int objectId, L2PcTemplate template, String accountName, String name, byte hairStyle, byte hairColor, byte face, boolean sex)
  733.     {
  734.         // Create a new L2PcInstance with an account name
  735.         PcAppearance app = new PcAppearance(face, hairColor, hairStyle, sex);
  736.         L2PcInstance player = new L2PcInstance(objectId, template, accountName, app);
  737.  
  738.         // Set the name of the L2PcInstance
  739.         player.setName(name);
  740.  
  741.         // Set the base class ID to that of the actual class ID.
  742.         player.setBaseClass(player.getClassId());
  743.  
  744.         // Add the player in the characters table of the database
  745.         boolean ok = player.createDb();
  746.         if (!ok)
  747.             return null;
  748.  
  749.         return player;
  750.     }
  751.  
  752.     public static L2PcInstance createDummyPlayer(int objectId, String name)
  753.     {  
  754.         // Create a new L2PcInstance with an account name
  755.         L2PcInstance player = new L2PcInstance(objectId);
  756.         player.setName(name);
  757.  
  758.         return player;
  759.     }
  760.  
  761.     public String getAccountName()
  762.     {
  763.         if (_connection != null && _connection.getClient().getLoginName() != null)
  764.             return _connection.getClient().getLoginName();
  765.  
  766.         return _accountName;
  767.     }
  768.  
  769.     public Map<Integer, String> getAccountChars()
  770.     {
  771.         return _chars;
  772.     }
  773.  
  774.     public int getRelation(L2PcInstance target)
  775.     {
  776.         int result = 0;
  777.  
  778.  
  779.         if (getPvpFlag() != 0)
  780.             result |= RelationChanged.RELATION_PVP_FLAG;
  781.  
  782.         if (getKarma() > 0)
  783.             result |= RelationChanged.RELATION_HAS_KARMA;
  784.  
  785.         if (getClan() != null)
  786.             result |= RelationChanged.RELATION_CLAN_MEMBER;
  787.  
  788.  
  789.         if (isClanLeader())
  790.  
  791.             result |= RelationChanged.RELATION_LEADER;
  792.  
  793.         if (getParty() != null && getParty() == target.getParty())
  794.         {
  795.             result |= RelationChanged.RELATION_HAS_PARTY;
  796.             for (int i = 0; i < getParty().getPartyMembers().size(); i++)
  797.             {
  798.                 if (getParty().getPartyMembers().get(i) != this)
  799.                     continue;
  800.                 switch (i)
  801.                 {
  802.                     case 0:
  803.                         result |= RelationChanged.RELATION_PARTYLEADER; // 0x10
  804.                         break;
  805.                     case 1:
  806.                         result |= RelationChanged.RELATION_PARTY4; // 0x8
  807.                         break;
  808.                     case 2:
  809.                         result |= RelationChanged.RELATION_PARTY3+RelationChanged.RELATION_PARTY2+RelationChanged.RELATION_PARTY1; // 0x7
  810.                         break;
  811.                     case 3:
  812.                         result |= RelationChanged.RELATION_PARTY3+RelationChanged.RELATION_PARTY2; // 0x6
  813.                         break;
  814.                     case 4:
  815.                         result |= RelationChanged.RELATION_PARTY3+RelationChanged.RELATION_PARTY1; // 0x5
  816.                         break;
  817.                     case 5:
  818.                         result |= RelationChanged.RELATION_PARTY3; // 0x4
  819.                         break;
  820.                     case 6:
  821.                         result |= RelationChanged.RELATION_PARTY2+RelationChanged.RELATION_PARTY1; // 0x3
  822.                         break;
  823.                     case 7:
  824.                         result |= RelationChanged.RELATION_PARTY2; // 0x2
  825.                         break;
  826.                     case 8:
  827.                         result |= RelationChanged.RELATION_PARTY1; // 0x1
  828.                         break;
  829.                 }
  830.             }
  831.         }
  832.  
  833.         if (getSiegeState() != 0)
  834.         {
  835.  
  836.             result |= RelationChanged.RELATION_INSIEGE;
  837.  
  838.             if (getSiegeState() != target.getSiegeState())
  839.  
  840.                 result |= RelationChanged.RELATION_ENEMY;
  841.  
  842.             else
  843.  
  844.                 result |= RelationChanged.RELATION_ALLY;
  845.  
  846.  
  847.  
  848.             if (getSiegeState() == 1)
  849.  
  850.                 result |= RelationChanged.RELATION_ATTACKER;
  851.  
  852.         }
  853.  
  854.         if (getClan() != null && target.getClan() != null)
  855.  
  856.         {
  857.             if (target.getClan().isAtWarWith(getClan().getClanId()))
  858.  
  859.             {
  860.  
  861.                 result |= RelationChanged.RELATION_1SIDED_WAR;
  862.  
  863.                 if (getClan().isAtWarWith(target.getClan().getClanId()))
  864.  
  865.                     result |= RelationChanged.RELATION_MUTUAL_WAR;
  866.  
  867.             }
  868.  
  869.         }
  870.  
  871.         return result;
  872.     }
  873.  
  874.     /**
  875.      * Retrieve a L2PcInstance from the characters table of the database and add it in _allObjects of the L2world (call restore method).<BR><BR>
  876.      *
  877.      * <B><U> Actions</U> :</B><BR><BR>
  878.      * <li>Retrieve the L2PcInstance from the characters table of the database </li>
  879.      * <li>Add the L2PcInstance object in _allObjects </li>
  880.      * <li>Set the x,y,z position of the L2PcInstance and make it invisible</li>
  881.      * <li>Update the overloaded status of the L2PcInstance</li><BR><BR>
  882.      *
  883.      * @param objectId Identifier of the object to initialized
  884.      *
  885.      * @return The L2PcInstance loaded from the database
  886.      *
  887.      */
  888.     public static L2PcInstance load(int objectId)
  889.     {
  890.         return restore(objectId);
  891.     }
  892.  
  893.     private void initPcStatusUpdateValues()
  894.     {
  895.         _cpUpdateInterval = getMaxCp() / 352.0;
  896.         _cpUpdateIncCheck = getMaxCp();
  897.         _cpUpdateDecCheck = getMaxCp() - _cpUpdateInterval;
  898.         _mpUpdateInterval = getMaxMp() / 352.0;
  899.         _mpUpdateIncCheck = getMaxMp();
  900.         _mpUpdateDecCheck = getMaxMp() - _mpUpdateInterval;
  901.     }
  902.  
  903.     /**
  904.      * Constructor of L2PcInstance (use L2Character constructor).<BR><BR>
  905.      *
  906.      * <B><U> Actions</U> :</B><BR><BR>
  907.      * <li>Call the L2Character constructor to create an empty _skills slot and copy basic Calculator set to this L2PcInstance </li>
  908.      * <li>Set the name of the L2PcInstance</li><BR><BR>
  909.      *
  910.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method SET the level of the L2PcInstance to 1</B></FONT><BR><BR>
  911.      *
  912.      * @param objectId Identifier of the object to initialized
  913.      * @param template The L2PcTemplate to apply to the L2PcInstance
  914.      * @param accountName The name of the account including this L2PcInstance
  915.      *
  916.      */
  917.     private L2PcInstance(int objectId, L2PcTemplate template, String accountName, PcAppearance app)
  918.     {
  919.         super(objectId, template);
  920.         getKnownList();
  921.         getStat();
  922.         getStatus();
  923.  
  924.         super.initCharStatusUpdateValues();
  925.  
  926.         initPcStatusUpdateValues();
  927.  
  928.         _accountName  = accountName;
  929.         _appearance   = app;
  930.  
  931.         // Create an AI
  932.         _ai = new L2PlayerAI(new L2PcInstance.AIAccessor());
  933.  
  934.         // Create a L2Radar object
  935.         _radar = new L2Radar(this);
  936.  
  937.  
  938.         if (Hero.getInstance().getHeroes() != null && Hero.getInstance().getHeroes().containsKey(getObjectId()))
  939.             setHero(true);
  940.  
  941.         // Retrieve from the database all items of this L2PcInstance and add them to _inventory
  942.         getInventory().restore();
  943.         if (!Config.WAREHOUSE_CACHE)
  944.  
  945.             getWarehouse();
  946.         getFreight().restore();
  947.     }
  948.  
  949.     private L2PcInstance(int objectId)
  950.     {
  951.         super(objectId, null);
  952.  
  953.         getKnownList();
  954.         getStat();
  955.         getStatus();
  956.  
  957.         super.initCharStatusUpdateValues();
  958.  
  959.         initPcStatusUpdateValues();
  960.     }
  961.  
  962.     public final PcKnownList getKnownList()
  963.     {
  964.         if (super.getKnownList() == null || !(super.getKnownList() instanceof PcKnownList))
  965.             setKnownList(new PcKnownList(this));
  966.         return (PcKnownList)super.getKnownList();
  967.     }
  968.  
  969.     public final PcStat getStat()
  970.     {
  971.         if (super.getStat() == null || !(super.getStat() instanceof PcStat))
  972.             setStat(new PcStat(this));
  973.         return (PcStat)super.getStat();
  974.     }
  975.  
  976.     public final PcStatus getStatus()
  977.     {
  978.         if (super.getStatus() == null || !(super.getStatus() instanceof PcStatus))
  979.             setStatus(new PcStatus(this));
  980.         return (PcStatus)super.getStatus();
  981.     }
  982.  
  983.     public final PcAppearance getAppearance()
  984.     {
  985.         return _appearance;
  986.     }
  987.  
  988.     /**
  989.      * Return the base L2PcTemplate link to the L2PcInstance.<BR><BR>
  990.      */
  991.     public final L2PcTemplate getBaseTemplate()
  992.     {
  993.         return CharTemplateTable.getInstance().getTemplate(_baseClass);
  994.     }
  995.  
  996.     /** Return the L2PcTemplate link to the L2PcInstance. */
  997.     public final L2PcTemplate getTemplate()
  998.  
  999.     {
  1000.  
  1001.         return (L2PcTemplate)super.getTemplate();
  1002.  
  1003.     }
  1004.  
  1005.     public void setTemplate(ClassId newclass)
  1006.     {
  1007.  
  1008.         super.setTemplate(CharTemplateTable.getInstance().getTemplate(newclass));
  1009.     }
  1010.  
  1011.     /**
  1012.      * Return the AI of the L2PcInstance (create it if necessary).<BR><BR>
  1013.      */
  1014.     public L2CharacterAI getAI()
  1015.     {
  1016.         if (_ai == null)
  1017.         {
  1018.             synchronized(this)
  1019.             {
  1020.                 if (_ai == null)
  1021.                     _ai = new L2PlayerAI(new L2PcInstance.AIAccessor());
  1022.             }
  1023.         }
  1024.  
  1025.         return _ai;
  1026.     }
  1027.  
  1028.     /**
  1029.      * Calculate a destination to explore the area and set the AI Intension to AI_INTENTION_MOVE_TO.<BR><BR>
  1030.      */
  1031.     public void explore()
  1032.     {
  1033.         if (!_exploring)
  1034.             return;
  1035.  
  1036.         if (getMountType() == 2)
  1037.             return;
  1038.  
  1039.         // Calculate the destination point (random)
  1040.  
  1041.         int x = getX()+Rnd.nextInt(6000)-3000;
  1042.         int y = getY()+Rnd.nextInt(6000)-3000;
  1043.  
  1044.         if (x > Universe.MAX_X) x = Universe.MAX_X;
  1045.         if (x < Universe.MIN_X) x = Universe.MIN_X;
  1046.         if (y > Universe.MAX_Y) y = Universe.MAX_Y;
  1047.         if (y < Universe.MIN_Y) y = Universe.MIN_Y;
  1048.  
  1049.         int z = getZ();
  1050.  
  1051.         L2CharPosition pos = new L2CharPosition(x,y,z,0);
  1052.  
  1053.         // Set the AI Intention to AI_INTENTION_MOVE_TO
  1054.         getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO,pos);
  1055.    
  1056.     }
  1057.  
  1058.     /** Return the Level of the L2PcInstance. */
  1059.     public final int getLevel()
  1060.     {
  1061.  
  1062.         return getStat().getLevel();
  1063.     }
  1064.  
  1065.     /**
  1066.      * Return the _newbie state of the L2PcInstance.<BR><BR>
  1067.      */
  1068.     public int getNewbieState()
  1069.     {
  1070.         return _newbieState;
  1071.     }
  1072.  
  1073.     /**
  1074.      * Set the _newbie state of the L2PcInstance.<BR><BR>
  1075.      *
  1076.      * @param getNewbieState The Identifier of the _newbieState state<BR><BR>
  1077.      *
  1078.      */
  1079.     public void setNewbieState(int newbie)
  1080.     {
  1081.         _newbieState = newbie;
  1082.     }
  1083.  
  1084.     public void setBaseClass(int baseClass)
  1085.     {
  1086.         _baseClass = baseClass;
  1087.     }
  1088.  
  1089.     public void setBaseClass(ClassId classId)
  1090.     {
  1091.         _baseClass = classId.ordinal();
  1092.     }
  1093.  
  1094.     public boolean isInStoreMode()
  1095.     {
  1096.  
  1097.         return (getPrivateStoreType() > 0);
  1098.  
  1099.     }
  1100.  
  1101.     public boolean isInCraftMode()
  1102.     {
  1103.         return _inCraftMode;
  1104.     }
  1105.  
  1106.     public void isInCraftMode(boolean b)
  1107.     {
  1108.         _inCraftMode = b;
  1109.     }
  1110.  
  1111.     /**
  1112.      * Manage Logout Task.<BR><BR>
  1113.      */
  1114.     public void logout()
  1115.     {
  1116.         // Close the connection with the client
  1117.         if (_connection != null)
  1118.             _connection.close();
  1119.     }
  1120.  
  1121.     /**
  1122.      * Return a table containing all Common L2RecipeList of the L2PcInstance.<BR><BR>
  1123.      */
  1124.     public L2RecipeList[] getCommonRecipeBook()
  1125.     {
  1126.         return _commonRecipeBook.values().toArray(new L2RecipeList[_commonRecipeBook.values().size()]);
  1127.     }
  1128.  
  1129.     /**
  1130.      * Return a table containing all Dwarf L2RecipeList of the L2PcInstance.<BR><BR>
  1131.      */
  1132.     public L2RecipeList[] getDwarvenRecipeBook()
  1133.     {
  1134.         return _dwarvenRecipeBook.values().toArray(new L2RecipeList[_dwarvenRecipeBook.values().size()]);
  1135.     }
  1136.  
  1137.     /**
  1138.      * Add a new L2RecipList to the table _commonrecipebook containing all L2RecipeList of the L2PcInstance <BR><BR>
  1139.      *
  1140.      * @param recipe The L2RecipeList to add to the _recipebook
  1141.      *
  1142.      */
  1143.     public void registerCommonRecipeList(L2RecipeList recipe)
  1144.     {
  1145.         _commonRecipeBook.put(recipe.getId(), recipe);
  1146.     }
  1147.  
  1148.     /**
  1149.      * Add a new L2RecipList to the table _recipebook containing all L2RecipeList of the L2PcInstance <BR><BR>
  1150.      *
  1151.      * @param recipe The L2RecipeList to add to the _recipebook
  1152.      *
  1153.      */
  1154.     public void registerDwarvenRecipeList(L2RecipeList recipe)
  1155.     {
  1156.         _dwarvenRecipeBook.put(recipe.getId(), recipe);
  1157.     }
  1158.  
  1159.     /**
  1160.      * @param RecipeID The Identifier of the L2RecipeList to check in the player's recipe books
  1161.      *
  1162.      * @return
  1163.      * <b>TRUE</b> if player has the recipe on Common or Dwarven Recipe book else returns <b>FALSE</b>
  1164.      */
  1165.     public boolean hasRecipeList(int recipeId)
  1166.     {
  1167.         if (_dwarvenRecipeBook.containsKey(recipeId))
  1168.             return true;
  1169.         else if(_commonRecipeBook.containsKey(recipeId))
  1170.             return true;
  1171.         else
  1172.             return false;
  1173.     }
  1174.  
  1175.     /**
  1176.      * Tries to remove a L2RecipList from the table _DwarvenRecipeBook or from table _CommonRecipeBook, those table contain all L2RecipeList of the L2PcInstance <BR><BR>
  1177.      *
  1178.      * @param RecipeID The Identifier of the L2RecipeList to remove from the _recipebook
  1179.      *
  1180.      */
  1181.     public void unregisterRecipeList(int recipeId)
  1182.     {
  1183.         if (_dwarvenRecipeBook.containsKey(recipeId))
  1184.             _dwarvenRecipeBook.remove(recipeId);
  1185.         else if(_commonRecipeBook.containsKey(recipeId))
  1186.             _commonRecipeBook.remove(recipeId);
  1187.         else
  1188.             _log.warning("Attempted to remove unknown RecipeList: "+recipeId);
  1189.  
  1190.         for (L2ShortCut sc : getAllShortCuts())
  1191.         {
  1192.             if (sc == null)
  1193.                 continue;
  1194.  
  1195.             if (sc.getId() == recipeId && sc.getType() == L2ShortCut.TYPE_RECIPE)
  1196.                 deleteShortCut(sc.getSlot(), sc.getPage());
  1197.         }
  1198.     }
  1199.  
  1200.     /**
  1201.      * Returns the Id for the last talked quest NPC.<BR><BR>
  1202.      */
  1203.     public int getLastQuestNpcObject()
  1204.     {
  1205.         return _questNpcObject;
  1206.     }
  1207.  
  1208.     public void setLastQuestNpcObject(int npcId)
  1209.     {
  1210.         _questNpcObject = npcId;
  1211.     }
  1212.  
  1213.     /**
  1214.      * Add Quest drops to the table containing all possible drops of a L2NpcInstance.<BR><BR>
  1215.      *
  1216.      * @param npc The L2NpcInstance killed by the L2PcInstance
  1217.      * @param drops The table containing all possible drops of the L2NpcInstance
  1218.      *
  1219.      */
  1220.     public void fillQuestDrops(L2NpcInstance npc, List<L2DropData> drops)
  1221.     {
  1222.         for (QuestState qs : _quests.values())
  1223.             qs.fillQuestDrops(npc, drops);
  1224.     }
  1225.  
  1226.     /**
  1227.      * Return the QuestState object corresponding to the quest name.<BR><BR>
  1228.      *
  1229.      * @param quest The name of the quest
  1230.      *
  1231.      */
  1232.     public QuestState getQuestState(String quest)
  1233.     {
  1234.         return _quests.get(quest);
  1235.     }
  1236.  
  1237.     /**
  1238.      * Add a QuestState to the table _quest containing all quests began by the L2PcInstance.<BR><BR>
  1239.      *
  1240.      * @param qs The QuestState to add to _quest
  1241.      *
  1242.      */
  1243.     public void setQuestState(QuestState qs)
  1244.     {
  1245.         _quests.put(qs.getQuestName(), qs);
  1246.     }
  1247.  
  1248.     /**
  1249.      * Remove a QuestState from the table _quest containing all quests began by the L2PcInstance.<BR><BR>
  1250.      *
  1251.      * @param quest The name of the quest
  1252.      *
  1253.      */
  1254.     public void delQuestState(String quest)
  1255.     {
  1256.         _quests.remove(quest);
  1257.     }
  1258.  
  1259.     private QuestState[] addToQuestStateArray(QuestState[] questStateArray, QuestState state)
  1260.     {
  1261.         int len = questStateArray.length;
  1262.         QuestState[] tmp = new QuestState[len+1];
  1263.         for (int i=0; i < len; i++)
  1264.             tmp[i] = questStateArray[i];
  1265.         tmp[len] = state;
  1266.         return tmp;
  1267.     }
  1268.  
  1269.     /**
  1270.      * Return a table containing all Quest in progress from the table _quests.<BR><BR>
  1271.      */
  1272.     public Quest[] getAllActiveQuests()
  1273.     {
  1274.         FastList<Quest> quests = new FastList<>();
  1275.  
  1276.         for (QuestState qs : _quests.values())
  1277.         {
  1278.             if (qs.getQuest().getQuestIntId() >= 1999)
  1279.                 continue;
  1280.  
  1281.             if (qs.isCompleted() && !Config.DEVELOPER)
  1282.                 continue;
  1283.  
  1284.             if (!qs.isStarted() && !Config.DEVELOPER)
  1285.                 continue;
  1286.  
  1287.             quests.add(qs.getQuest());
  1288.         }
  1289.  
  1290.         return quests.toArray(new Quest[quests.size()]);
  1291.     }
  1292.  
  1293.     /**
  1294.      * Return a table containing all QuestState to modify after a L2Attackable killing.<BR><BR>
  1295.      *
  1296.      * @param npcId The Identifier of the L2Attackable attacked
  1297.      *
  1298.      */
  1299.     public QuestState[] getQuestsForAttacks(L2NpcInstance npc)
  1300.     {
  1301.         // Create a QuestState table that will contain all QuestState to modify
  1302.         QuestState[] states = null;
  1303.  
  1304.         // Go through the QuestState of the L2PcInstance quests
  1305.         Quest[] quests = npc.getTemplate().getEventQuests(Quest.QuestEventType.MOBGOTATTACKED);
  1306.         if (quests != null)
  1307.         {
  1308.             for (Quest quest: quests)
  1309.             {
  1310.                 if (quest != null)
  1311.                 {
  1312.                     // Copy the current L2PcInstance QuestState in the QuestState table
  1313.                     if (getQuestState(quest.getName()) != null)
  1314.                     {
  1315.                         if (states == null)
  1316.                             states = new QuestState[]{getQuestState(quest.getName())};
  1317.                         else
  1318.                             states = addToQuestStateArray(states, getQuestState(quest.getName()));
  1319.                     }
  1320.                 }
  1321.             }
  1322.         }
  1323.  
  1324.         // Return a table containing all QuestState to modify
  1325.         return states;
  1326.     }
  1327.  
  1328.     /**
  1329.      * Return a table containing all QuestState to modify after a L2Attackable killing.<BR><BR>
  1330.      *
  1331.      * @param npcId The Identifier of the L2Attackable killed
  1332.      *
  1333.      */
  1334.     public QuestState[] getQuestsForKills(L2NpcInstance npc)
  1335.     {
  1336.         // Create a QuestState table that will contain all QuestState to modify
  1337.         QuestState[] states = null;
  1338.  
  1339.         // Go through the QuestState of the L2PcInstance quests
  1340.         Quest[] quests = npc.getTemplate().getEventQuests(Quest.QuestEventType.MOBKILLED);
  1341.         if (quests != null)
  1342.         {
  1343.             for (Quest quest: quests)
  1344.             {
  1345.                 if (quest != null)
  1346.                 {
  1347.                     // Copy the current L2PcInstance QuestState in the QuestState table
  1348.                     if (getQuestState(quest.getName()) != null)
  1349.                     {
  1350.                         if (states == null)
  1351.                             states = new QuestState[]{getQuestState(quest.getName())};
  1352.                         else
  1353.                             states = addToQuestStateArray(states, getQuestState(quest.getName()));
  1354.                     }
  1355.                 }
  1356.             }
  1357.         }
  1358.  
  1359.         // Return a table containing all QuestState to modify
  1360.         return states;
  1361.     }
  1362.  
  1363.     /**
  1364.      * Return a table containing all QuestState from the table _quests in which the L2PcInstance must talk to the NPC.<BR><BR>
  1365.      *
  1366.      * @param npcId The Identifier of the NPC
  1367.      *
  1368.      */
  1369.     public QuestState[] getQuestsForTalk(int npcId)
  1370.     {
  1371.         // Create a QuestState table that will contain all QuestState to modify
  1372.         QuestState[] states = null;
  1373.  
  1374.         // Go through the QuestState of the L2PcInstance quests
  1375.         Quest[] quests = NpcTable.getInstance().getTemplate(npcId).getEventQuests(Quest.QuestEventType.QUEST_TALK);
  1376.         if (quests != null)
  1377.         {
  1378.             for (Quest quest: quests)
  1379.             {
  1380.                 if (quest != null)
  1381.                 {
  1382.                     // Copy the current L2PcInstance QuestState in the QuestState table
  1383.                     if (getQuestState(quest.getName()) != null)
  1384.                     {
  1385.                         if (states == null)
  1386.                             states = new QuestState[]{getQuestState(quest.getName())};
  1387.                         else
  1388.                             states = addToQuestStateArray(states, getQuestState(quest.getName()));
  1389.                     }
  1390.                 }
  1391.             }
  1392.         }
  1393.  
  1394.         // Return a table containing all QuestState to modify
  1395.         return states;
  1396.     }
  1397.  
  1398.     public QuestState processQuestEvent(String quest, String event)
  1399.     {
  1400.         QuestState retval = null;
  1401.         if (event == null)
  1402.             event = "";
  1403.  
  1404.         if (!_quests.containsKey(quest))
  1405.             return retval;
  1406.  
  1407.         QuestState qs = getQuestState(quest);
  1408.         if (qs == null && event.length() == 0)
  1409.             return retval;
  1410.  
  1411.         if (qs == null)
  1412.  
  1413.         {
  1414.             Quest q = QuestManager.getInstance().getQuest(quest);
  1415.             if (q == null)
  1416.                 return retval;
  1417.             qs = q.newQuestState(this);
  1418.         }
  1419.  
  1420.         if (qs != null)
  1421.  
  1422.         {
  1423.             if (getLastQuestNpcObject() > 0)
  1424.             {
  1425.                 L2Object object = L2World.getInstance().findObject(getLastQuestNpcObject());
  1426.  
  1427.                 if (object instanceof L2NpcInstance && isInsideRadius(object, L2NpcInstance.INTERACTION_DISTANCE, false, false))
  1428.                 {
  1429.                     L2NpcInstance npc = (L2NpcInstance)object;
  1430.                     QuestState[] states = getQuestsForTalk(npc.getNpcId());
  1431.  
  1432.                     if (states != null)
  1433.                     {
  1434.                         for (QuestState state : states)
  1435.                         {
  1436.                             if ((state.getQuest().getQuestIntId() == qs.getQuest().getQuestIntId()) && !qs.isCompleted())
  1437.                             {
  1438.                                 if (qs.getQuest().notifyEvent(event, npc, this))
  1439.                                     showQuestWindow(quest, qs.getStateId());
  1440.  
  1441.                                 retval = qs;
  1442.                             }
  1443.                         }
  1444.  
  1445.                         sendPacket(new QuestList());
  1446.                     }
  1447.                 }
  1448.             }
  1449.         }
  1450.  
  1451.         return retval;
  1452.     }
  1453.  
  1454.     private void showQuestWindow(String questId, String stateId)
  1455.     {
  1456.         String path = "data/scripts/quests/"+questId+"/"+stateId+".htm";
  1457.         String content = HtmCache.getInstance().getHtm(path);  //TODO path for quests html
  1458.  
  1459.         if (content != null)
  1460.         {
  1461.             if (Config.DEBUG)
  1462.                 _log.fine("Showing quest window for quest "+questId+" state "+stateId+" html path: " + path);
  1463.  
  1464.             NpcHtmlMessage npcReply = new NpcHtmlMessage(5);
  1465.             npcReply.setHtml(content);
  1466.             sendPacket(npcReply);
  1467.         }
  1468.  
  1469.         sendPacket(new ActionFailed());
  1470.     }
  1471.  
  1472.     /**
  1473.      * Return a table containing all L2ShortCut of the L2PcInstance.<BR><BR>
  1474.      */
  1475.     public L2ShortCut[] getAllShortCuts()
  1476.     {
  1477.         return _shortCuts.getAllShortCuts();
  1478.     }
  1479.  
  1480.     /**
  1481.      * Return the L2ShortCut of the L2PcInstance corresponding to the position (page-slot).<BR><BR>
  1482.      *
  1483.      * @param slot The slot in wich the shortCuts is equiped
  1484.      * @param page The page of shortCuts containing the slot
  1485.      *
  1486.      */
  1487.     public L2ShortCut getShortCut(int slot, int page)
  1488.     {
  1489.         return _shortCuts.getShortCut(slot, page);
  1490.     }
  1491.  
  1492.     /**
  1493.      * Add a L2shortCut to the L2PcInstance _shortCuts<BR><BR>
  1494.      */
  1495.     public void registerShortCut(L2ShortCut shortcut)
  1496.     {
  1497.         _shortCuts.registerShortCut(shortcut);
  1498.     }
  1499.  
  1500.     /**
  1501.      * Delete the L2ShortCut corresponding to the position (page-slot) from the L2PcInstance _shortCuts.<BR><BR>
  1502.      */
  1503.     public void deleteShortCut(int slot, int page)
  1504.     {
  1505.         _shortCuts.deleteShortCut(slot, page);
  1506.     }
  1507.  
  1508.     /**
  1509.      * Add a L2Macro to the L2PcInstance _macroses<BR><BR>
  1510.      */
  1511.     public void registerMacro(L2Macro macro)
  1512.     {
  1513.         _macroses.registerMacro(macro);
  1514.     }
  1515.  
  1516.     /**
  1517.      * Delete the L2Macro corresponding to the Identifier from the L2PcInstance _macroses.<BR><BR>
  1518.      */
  1519.     public void deleteMacro(int id)
  1520.     {
  1521.         _macroses.deleteMacro(id);
  1522.     }
  1523.  
  1524.     /**
  1525.      * Return all L2Macro of the L2PcInstance.<BR><BR>
  1526.      */
  1527.     public MacroList getMacroses()
  1528.     {
  1529.         return _macroses;
  1530.     }
  1531.  
  1532.     /**
  1533.      * Set the PvP Flag of the L2PcInstance.<BR><BR>
  1534.      */
  1535.     public void setPvpFlag(int pvpFlag)
  1536.     {
  1537.         _pvpFlag = pvpFlag;
  1538.     }
  1539.  
  1540.     public int getPvpFlag()
  1541.     {
  1542.         return _pvpFlag;
  1543.     }
  1544.  
  1545.     /**
  1546.      * Set the siege state of the L2PcInstance.<BR><BR>
  1547.      * 1 = attacker, 2 = defender, 0 = not involved
  1548.      */
  1549.     public void setSiegeState(byte siegeState)
  1550.     {
  1551.         _siegeState = siegeState;
  1552.     }
  1553.  
  1554.     public int getSiegeState()
  1555.     {
  1556.         return _siegeState;
  1557.     }
  1558.  
  1559.     @Override
  1560.     public void revalidateZone(boolean force)
  1561.     {
  1562.         // Cannot validate if not in a world region (happens during teleport)
  1563.         if (getWorldRegion() == null)
  1564.             return;
  1565.  
  1566.         if (force)
  1567.             _zoneValidateCounter = 4;
  1568.         else
  1569.         {
  1570.             _zoneValidateCounter--;
  1571.             if (_zoneValidateCounter < 0)
  1572.                 _zoneValidateCounter = 4;
  1573.             else
  1574.                 return;
  1575.         }
  1576.  
  1577.  
  1578.         getWorldRegion().revalidateZones(this);
  1579.  
  1580.  
  1581.         if (Config.ALLOW_WATER)
  1582.             checkWaterState();
  1583.  
  1584.     }
  1585.  
  1586.     public void updatePvPFlag(int value)
  1587.     {
  1588.         if (getPvpFlag() == value)
  1589.             return;
  1590.         setPvpFlag(value);
  1591.  
  1592.         sendPacket(new UserInfo(this));
  1593.  
  1594.         // If this player has a pet update the pets pvp flag as well
  1595.         if (getPet() != null)
  1596.             sendPacket(new RelationChanged(getPet(), getRelation(this), false));
  1597.  
  1598.         for (L2PcInstance target : getKnownList().getKnownPlayers().values())
  1599.  
  1600.         {
  1601.  
  1602.             target.sendPacket(new RelationChanged(this, getRelation(target), isAutoAttackable(target)));
  1603.             if (getPet() != null)
  1604.                 target.sendPacket(new RelationChanged(getPet(), getRelation(this), isAutoAttackable(target)));
  1605.         }
  1606.     }
  1607.  
  1608.     /**
  1609.      * Return True if the L2PcInstance can Craft Dwarven Recipes.<BR><BR>
  1610.      */
  1611.     public boolean hasDwarvenCraft()
  1612.     {
  1613.         return getSkillLevel(L2Skill.SKILL_CREATE_DWARVEN) >= 1;
  1614.     }
  1615.  
  1616.     public int getDwarvenCraft()
  1617.     {
  1618.         return getSkillLevel(L2Skill.SKILL_CREATE_DWARVEN);
  1619.     }
  1620.  
  1621.     /**
  1622.      * Return True if the L2PcInstance can Craft Dwarven Recipes.<BR><BR>
  1623.      */
  1624.     public boolean hasCommonCraft()
  1625.     {
  1626.         return getSkillLevel(L2Skill.SKILL_CREATE_COMMON) >= 1;
  1627.     }
  1628.  
  1629.     public int getCommonCraft()
  1630.     {
  1631.         return getSkillLevel(L2Skill.SKILL_CREATE_COMMON);
  1632.     }
  1633.  
  1634.     /**
  1635.      * Return the PK counter of the L2PcInstance.<BR><BR>
  1636.      */
  1637.     public int getPkKills()
  1638.     {
  1639.         return _pkKills;
  1640.     }
  1641.  
  1642.     /**
  1643.      * Set the PK counter of the L2PcInstance.<BR><BR>
  1644.      */
  1645.     public void setPkKills(int pkKills)
  1646.     {
  1647.         _pkKills = pkKills;
  1648.     }
  1649.  
  1650.     /**
  1651.      * Return the _deleteTimer of the L2PcInstance.<BR><BR>
  1652.      */
  1653.     public long getDeleteTimer()
  1654.     {
  1655.         return _deleteTimer;
  1656.     }
  1657.  
  1658.     /**
  1659.      * Set the _deleteTimer of the L2PcInstance.<BR><BR>
  1660.      */
  1661.     public void setDeleteTimer(long deleteTimer)
  1662.     {
  1663.         _deleteTimer = deleteTimer;
  1664.     }
  1665.  
  1666.     /**
  1667.      * Return the current weight of the L2PcInstance.<BR><BR>
  1668.      */
  1669.     public int getCurrentLoad()
  1670.     {
  1671.         return _inventory.getTotalWeight();
  1672.     }
  1673.  
  1674.     /**
  1675.      * Return date of las update of recomPoints
  1676.      */
  1677.     public long getLastRecomUpdate()
  1678.     {
  1679.         return _lastRecomUpdate;
  1680.  
  1681.     }
  1682.  
  1683.     public void setLastRecomUpdate(long date)
  1684.  
  1685.     {
  1686.  
  1687.         _lastRecomUpdate = date;
  1688.     }
  1689.  
  1690.     /**
  1691.      * Return the number of recommendation obtained by the L2PcInstance.<BR><BR>
  1692.      */
  1693.     public int getRecomHave()
  1694.     {
  1695.         return _recomHave;
  1696.     }
  1697.  
  1698.     /**
  1699.      * Increment the number of recommendation obtained by the L2PcInstance (Max : 255).<BR><BR>
  1700.      */
  1701.     protected void incRecomHave()
  1702.     {
  1703.         if (_recomHave < 255)
  1704.             _recomHave++;
  1705.     }
  1706.  
  1707.     /**
  1708.      * Set the number of recommendation obtained by the L2PcInstance (Max : 255).<BR><BR>
  1709.      */
  1710.     public void setRecomHave(int value)
  1711.     {
  1712.         if (value > 255)
  1713.             _recomHave = 255;
  1714.         else if (value < 0)
  1715.             _recomHave = 0;
  1716.         else
  1717.             _recomHave = value;
  1718.     }
  1719.  
  1720.     /**
  1721.      * Return the number of recommendation that the L2PcInstance can give.<BR><BR>
  1722.      */
  1723.     public int getRecomLeft()
  1724.     {
  1725.         return _recomLeft;
  1726.     }
  1727.  
  1728.     /**
  1729.      * Increment the number of recommendation that the L2PcInstance can give.<BR><BR>
  1730.      */
  1731.     protected void decRecomLeft()
  1732.     {
  1733.         if (_recomLeft > 0)
  1734.             _recomLeft--;
  1735.     }
  1736.  
  1737.     public void giveRecom(L2PcInstance target)
  1738.     {
  1739.  
  1740.         if (Config.ALT_RECOMMEND)
  1741.  
  1742.         {
  1743.  
  1744.             java.sql.Connection con = null;
  1745.  
  1746.             try
  1747.  
  1748.             {
  1749.  
  1750.                 con = L2DatabaseFactory.getInstance().getConnection();
  1751.  
  1752.                 PreparedStatement statement = con.prepareStatement(ADD_CHAR_RECOM);
  1753.  
  1754.                 statement.setInt(1, getObjectId());
  1755.  
  1756.                 statement.setInt(2, target.getObjectId());
  1757.  
  1758.                 statement.execute();
  1759.  
  1760.                 statement.close();
  1761.  
  1762.             }
  1763.  
  1764.             catch (Exception e)
  1765.  
  1766.             {
  1767.  
  1768.                 _log.warning("could not update char recommendations:"+e);
  1769.  
  1770.             }
  1771.  
  1772.             finally
  1773.  
  1774.             {
  1775.  
  1776.                 try
  1777.                 {
  1778.                     con.close();
  1779.                 }
  1780.                 catch (Exception e) {}
  1781.  
  1782.             }
  1783.  
  1784.         }
  1785.         target.incRecomHave();
  1786.         decRecomLeft();
  1787.         _recomChars.add(target.getObjectId());
  1788.     }
  1789.  
  1790.     public boolean canRecom(L2PcInstance target)
  1791.     {
  1792.         return !_recomChars.contains(target.getObjectId());
  1793.     }
  1794.  
  1795.     /**
  1796.      * Return the Karma of the L2PcInstance.<BR><BR>
  1797.      */
  1798.     public int getKarma()
  1799.     {
  1800.         return _karma;
  1801.     }
  1802.  
  1803.     /**
  1804.      * Set the Karma of the L2PcInstance and send a Server->Client packet StatusUpdate (broadcast).<BR><BR>
  1805.      */
  1806.     public void setKarma(int karma)
  1807.     {
  1808.         if (karma < 0)
  1809.             karma = 0;
  1810.  
  1811.         if (_karma == 0 && karma > 0)
  1812.         {
  1813.             for (L2Object object : getKnownList().getKnownObjects().values())
  1814.             {
  1815.                 if (!(object instanceof L2GuardInstance))
  1816.                     continue;
  1817.  
  1818.                 if (((L2GuardInstance)object).getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)
  1819.                     ((L2GuardInstance)object).getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null);
  1820.             }
  1821.         }
  1822.         else if (_karma > 0 && karma == 0)
  1823.         {
  1824.             // Send a Server->Client StatusUpdate packet with Karma and PvP Flag to the L2PcInstance and all L2PcInstance to inform (broadcast)
  1825.             setKarmaFlag(0);
  1826.         }
  1827.  
  1828.         _karma = karma;
  1829.         broadcastKarma();
  1830.     }
  1831.  
  1832.     /**
  1833.      * Return the max weight that the L2PcInstance can load.<BR><BR>
  1834.      */
  1835.     public int getMaxLoad()
  1836.     {
  1837.         // Weight Limit = (CON Modifier*69000) * Skills
  1838.         // Source
  1839.         double baseLoad = Math.floor(BaseStats.CON.calcBonus(this) * 69000 * Config.ALT_WEIGHT_LIMIT);
  1840.         return (int) calcStat(Stats.MAX_LOAD, baseLoad, this, null);
  1841.     }
  1842.  
  1843.     public int getExpertisePenalty()
  1844.     {
  1845.         return _expertisePenalty;
  1846.     }
  1847.  
  1848.     public int getWeightPenalty()
  1849.     {
  1850.         if (_dietMode)
  1851.             return 0;
  1852.  
  1853.  
  1854.         return _curWeightPenalty;
  1855.     }
  1856.  
  1857.     /**
  1858.      * Update the overloaded status of the L2PcInstance.<BR><BR>
  1859.      */
  1860.     public void refreshOverloaded()
  1861.     {
  1862.         if (getMaxLoad() > 0)
  1863.         {
  1864.             long weightproc = (long) ((getCurrentLoad() - calcStat(Stats.MAX_LOAD, 1, this, null)) * 1000 / getMaxLoad());
  1865.             int newWeightPenalty;
  1866.             if (weightproc < 500 || _dietMode)
  1867.                 newWeightPenalty = 0;
  1868.             else if (weightproc < 666)
  1869.                 newWeightPenalty = 1;
  1870.             else if (weightproc < 800)
  1871.                 newWeightPenalty = 2;
  1872.             else if (weightproc < 1000)
  1873.                 newWeightPenalty = 3;
  1874.             else
  1875.                 newWeightPenalty = 4;
  1876.  
  1877.             if (_curWeightPenalty != newWeightPenalty)
  1878.             {
  1879.                 _curWeightPenalty = newWeightPenalty;
  1880.                 if (newWeightPenalty > 0)
  1881.                 {
  1882.                     super.addSkill(SkillTable.getInstance().getInfo(4270,newWeightPenalty));
  1883.                     setIsOverloaded(getCurrentLoad() >= getMaxLoad());
  1884.                 }
  1885.                 else
  1886.                 {
  1887.                     super.removeSkill(getKnownSkill(4270));
  1888.                     setIsOverloaded(false);
  1889.                 }
  1890.                 sendPacket(new UserInfo(this));
  1891.  
  1892.                 sendPacket(new EtcStatusUpdate(this));
  1893.  
  1894.                 Broadcast.toKnownPlayers(this, new CharInfo(this));
  1895.             }
  1896.         }
  1897.     }
  1898.  
  1899.     public void refreshExpertisePenalty()
  1900.     {
  1901.         int newPenalty = 0;
  1902.  
  1903.  
  1904.         for (L2ItemInstance item : getInventory().getItems())
  1905.         {
  1906.             if (item != null && item.isEquipped())
  1907.             {
  1908.                 int crystaltype = item.getItem().getCrystalType();
  1909.  
  1910.                 if (crystaltype > newPenalty)
  1911.                     newPenalty = crystaltype;
  1912.             }
  1913.         }
  1914.  
  1915.         newPenalty = newPenalty - getExpertiseIndex();
  1916.  
  1917.         if (newPenalty <= 0)
  1918.  
  1919.             newPenalty = 0;
  1920.  
  1921.         if (getExpertisePenalty() != newPenalty)
  1922.         {
  1923.             _expertisePenalty = newPenalty;
  1924.  
  1925.  
  1926.             if (newPenalty > 0)
  1927.                 super.addSkill(SkillTable.getInstance().getInfo(4267, 1));
  1928.             else
  1929.  
  1930.                 super.removeSkill(getKnownSkill(4267));
  1931.  
  1932.             sendPacket(new EtcStatusUpdate(this));
  1933.         }
  1934.     }
  1935.  
  1936.     public void checkSShotsMatch(L2ItemInstance equipped, L2ItemInstance unequipped)
  1937.     {
  1938.         if (unequipped == null)
  1939.             return;
  1940.  
  1941.         // on retail auto shots are never disabled on unequip
  1942.         unequipped.setChargedSoulshot(L2ItemInstance.CHARGED_NONE);
  1943.         unequipped.setChargedSpiritshot(L2ItemInstance.CHARGED_NONE);
  1944.     }
  1945.  
  1946.  
  1947.     /**
  1948.      * Return the the PvP Kills of the L2PcInstance (Number of player killed during a PvP).<BR><BR>
  1949.      */
  1950.     public int getPvpKills()
  1951.     {
  1952.         return _pvpKills;
  1953.     }
  1954.  
  1955.     /**
  1956.      * Set the the PvP Kills of the L2PcInstance (Number of player killed during a PvP).<BR><BR>
  1957.      */
  1958.     public void setPvpKills(int pvpKills)
  1959.     {
  1960.         _pvpKills = pvpKills;
  1961.     }
  1962.  
  1963.     /**
  1964.      * Return the ClassId object of the L2PcInstance contained in L2PcTemplate.<BR><BR>
  1965.      */
  1966.     public ClassId getClassId()
  1967.     {
  1968.         return getTemplate().classId;
  1969.     }
  1970.  
  1971.     /**
  1972.      * Set the template of the L2PcInstance.<BR><BR>
  1973.      *
  1974.      * @param Id The Identifier of the L2PcTemplate to set to the L2PcInstance
  1975.      *
  1976.      */
  1977.     public void setClassId(int Id)
  1978.     {
  1979.         if (!_classLock.tryLock())
  1980.             return;
  1981.  
  1982.         try
  1983.         {
  1984.  
  1985.             if (isSubClassActive())
  1986.  
  1987.                 getSubClasses().get(_classIndex).setClassId(Id);
  1988.  
  1989.  
  1990.             setClassTemplate(Id);
  1991.  
  1992.             if (getClassId().level() == 3)
  1993.                 sendPacket(new SystemMessage(1606)); // system sound 3rd occupation
  1994.             else
  1995.                 sendPacket(new SystemMessage(1308)); // system sound for 1st and 2nd occupation
  1996.  
  1997.             if (isInParty())
  1998.                 getParty().broadcastToPartyMembers(new PartySmallWindowUpdate(this));
  1999.  
  2000.             if (getClan() != null)
  2001.                 getClan().broadcastToOtherOnlineMembers(new PledgeShowMemberListUpdate(this), this);
  2002.  
  2003.             if (Config.AUTO_LEARN_SKILLS)
  2004.                 rewardSkills();
  2005.         }
  2006.  
  2007.         finally
  2008.         {
  2009.             _classLock.unlock();
  2010.         }
  2011.     }
  2012.  
  2013.     /** Return the Experience of the L2PcInstance. */
  2014.     public long getExp()
  2015.     {
  2016.  
  2017.         return getStat().getExp();
  2018.  
  2019.     }
  2020.  
  2021.     public void setActiveEnchantItem(L2ItemInstance scroll)
  2022.     {
  2023.         _activeEnchantItem = scroll;
  2024.     }
  2025.  
  2026.     public L2ItemInstance getActiveEnchantItem()
  2027.     {
  2028.         return _activeEnchantItem;
  2029.     }
  2030.  
  2031.     /**
  2032.      * Set the fists weapon of the L2PcInstance (used when no weapon is equiped).<BR><BR>
  2033.      *
  2034.      * @param weaponItem The fists L2Weapon to set to the L2PcInstance
  2035.      *
  2036.      */
  2037.     public void setFistsWeaponItem(L2Weapon weaponItem)
  2038.     {
  2039.         _fistsWeaponItem = weaponItem;
  2040.     }
  2041.  
  2042.     /**
  2043.      * Return the fists weapon of the L2PcInstance (used when no weapon is equiped).<BR><BR>
  2044.      */
  2045.     public L2Weapon getFistsWeaponItem()
  2046.     {
  2047.         return _fistsWeaponItem;
  2048.     }
  2049.  
  2050.     /**
  2051.      * Return the fists weapon of the L2PcInstance Class (used when no weapon is equiped).<BR><BR>
  2052.      */
  2053.     public L2Weapon findFistsWeaponItem(int classId)
  2054.     {
  2055.         L2Weapon weaponItem = null;
  2056.         if ((classId >= 0x00) && (classId <= 0x09))
  2057.         {
  2058.             //human fighter fists
  2059.             L2Item temp = ItemTable.getInstance().getTemplate(246);
  2060.             weaponItem = (L2Weapon)temp;
  2061.         }
  2062.         else if ((classId >= 0x0a) && (classId <= 0x11))
  2063.         {
  2064.             //human mage fists
  2065.             L2Item temp = ItemTable.getInstance().getTemplate(251);
  2066.             weaponItem = (L2Weapon)temp;
  2067.         }
  2068.         else if ((classId >= 0x12) && (classId <= 0x18))
  2069.         {
  2070.             //elven fighter fists
  2071.             L2Item temp = ItemTable.getInstance().getTemplate(244);
  2072.             weaponItem = (L2Weapon)temp;
  2073.         }
  2074.         else if ((classId >= 0x19) && (classId <= 0x1e))
  2075.         {
  2076.             //elven mage fists
  2077.             L2Item temp = ItemTable.getInstance().getTemplate(249);
  2078.             weaponItem = (L2Weapon)temp;
  2079.         }
  2080.         else if ((classId >= 0x1f) && (classId <= 0x25))
  2081.         {
  2082.             //dark elven fighter fists
  2083.             L2Item temp = ItemTable.getInstance().getTemplate(245);
  2084.             weaponItem = (L2Weapon)temp;
  2085.         }
  2086.         else if ((classId >= 0x26) && (classId <= 0x2b))
  2087.         {
  2088.             //dark elven mage fists
  2089.             L2Item temp = ItemTable.getInstance().getTemplate(250);
  2090.             weaponItem = (L2Weapon)temp;
  2091.         }
  2092.         else if ((classId >= 0x2c) && (classId <= 0x30))
  2093.         {
  2094.             //orc fighter fists
  2095.             L2Item temp = ItemTable.getInstance().getTemplate(248);
  2096.             weaponItem = (L2Weapon)temp;
  2097.         }
  2098.         else if ((classId >= 0x31) && (classId <= 0x34))
  2099.         {
  2100.             //orc mage fists
  2101.             L2Item temp = ItemTable.getInstance().getTemplate(252);
  2102.             weaponItem = (L2Weapon)temp;
  2103.         }
  2104.         else if ((classId >= 0x35) && (classId <= 0x39))
  2105.         {
  2106.             //dwarven fists
  2107.             L2Item temp = ItemTable.getInstance().getTemplate(247);
  2108.             weaponItem = (L2Weapon)temp;
  2109.         }
  2110.  
  2111.         return weaponItem;
  2112.     }
  2113.  
  2114.     /**
  2115.      * Give Expertise skill of this level and remove beginner Lucky skill.<BR><BR>
  2116.      *
  2117.      * <B><U> Actions</U> :</B><BR><BR>
  2118.      * <li>Get the Level of the L2PcInstance </li>
  2119.      * <li>If L2PcInstance Level is 5, remove beginner Lucky skill </li>
  2120.      * <li>Add the Expertise skill corresponding to its Expertise level</li>
  2121.      * <li>Update the overloaded status of the L2PcInstance</li><BR><BR>
  2122.      *
  2123.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T give other free skills (SP needed = 0)</B></FONT><BR><BR>
  2124.      *
  2125.      */
  2126.     public void rewardSkills()
  2127.     {
  2128.         // Get the Level of the L2PcInstance
  2129.         int lvl = getLevel();
  2130.  
  2131.         // Calculate the current higher Expertise of the L2PcInstance
  2132.         for (int i=0; i < EXPERTISE_LEVELS.length; i++)
  2133.         {
  2134.             if (lvl >= EXPERTISE_LEVELS[i])
  2135.                 setExpertiseIndex(i);
  2136.         }
  2137.  
  2138.         // Add the Expertise skill corresponding to its Expertise level
  2139.         if (getExpertiseIndex() > 0)
  2140.         {
  2141.             L2Skill skill = SkillTable.getInstance().getInfo(239, getExpertiseIndex());
  2142.             addSkill(skill, true);
  2143.         }
  2144.  
  2145.  
  2146.         for (int i = 0; i < COMMON_CRAFT_LEVELS.length; i++)
  2147.         {
  2148.             if (lvl >= COMMON_CRAFT_LEVELS[i] && getSkillLevel(1320) < (i+1))
  2149.             {
  2150.                 L2Skill skill = SkillTable.getInstance().getInfo(1320, (i+1));
  2151.                 addSkill(skill, true);
  2152.             }
  2153.         }
  2154.  
  2155.  
  2156.         // Auto-Learn skills if activated
  2157.  
  2158.         if (Config.AUTO_LEARN_SKILLS)
  2159.  
  2160.             giveAvailableSkills();
  2161.  
  2162.  
  2163.         // This function gets called on login, so not such a bad place to check weight
  2164.         refreshOverloaded();        // Update the overloaded status of the L2PcInstance
  2165.         refreshExpertisePenalty();  // Update the expertise status of the L2PcInstance
  2166.     }
  2167.  
  2168.     /**
  2169.      * Give all available skills to the player.<br><br>
  2170.      *
  2171.      */
  2172.     private void giveAvailableSkills()
  2173.     {
  2174.         // Check if 3rd class skills are auto-learned
  2175.         if (!Config.AUTO_LEARN_3RD_SKILLS && getClassId().level() == 3)
  2176.             return;
  2177.  
  2178.         int skillCounter = 0;
  2179.  
  2180.         // Get available skills
  2181.         L2SkillLearn[] skills = SkillTreeTable.getInstance().getMaxAvailableSkills(this, getClassId());
  2182.         for (L2SkillLearn s : skills)
  2183.         {
  2184.             L2Skill sk = SkillTable.getInstance().getInfo(s.getId(), s.getLevel());
  2185.             if (sk == null || !sk.getCanLearn(getClassId()))
  2186.                 continue;
  2187.  
  2188.             if (getSkillLevel(sk.getId()) == -1)
  2189.                 skillCounter++;
  2190.  
  2191.             addSkill(sk, true);
  2192.         }
  2193.  
  2194.  
  2195.         if (skillCounter > 0)
  2196.             sendMessage("You just acquired " + skillCounter + " new skills.");
  2197.  
  2198.     }
  2199.  
  2200.     /** Set the Experience value of the L2PcInstance. */
  2201.     public void setExp(long exp)
  2202.     {
  2203.         if (exp < 0)
  2204.             exp = 0;
  2205.  
  2206.  
  2207.         getStat().setExp(exp);
  2208.  
  2209.     }
  2210.  
  2211.     /**
  2212.      * Return the Race object of the L2PcInstance.<BR><BR>
  2213.      */
  2214.     public Race getRace()
  2215.     {
  2216.         if (!isSubClassActive())
  2217.             return getTemplate().race;
  2218.  
  2219.         L2PcTemplate charTemp = CharTemplateTable.getInstance().getTemplate(_baseClass);
  2220.         return charTemp.race;
  2221.     }
  2222.  
  2223.  
  2224.     public L2Radar getRadar()
  2225.     {
  2226.  
  2227.         return _radar;
  2228.     }
  2229.  
  2230.     /** Return the SP amount of the L2PcInstance. */
  2231.     public int getSp()
  2232.  
  2233.     {
  2234.  
  2235.         return getStat().getSp();
  2236.     }
  2237.  
  2238.     /** Set the SP amount of the L2PcInstance. */
  2239.     public void setSp(int sp)
  2240.  
  2241.     {
  2242.         if (sp < 0)
  2243.             sp = 0;
  2244.  
  2245.  
  2246.         super.getStat().setSp(sp);
  2247.  
  2248.     }
  2249.  
  2250.     /**
  2251.      * Return true if this L2PcInstance is a clan leader in
  2252.      * ownership of the passed castle
  2253.      */
  2254.     public boolean isCastleLord(int castleId)
  2255.     {
  2256.         L2Clan clan = getClan();
  2257.  
  2258.  
  2259.         // player has clan and is the clan leader, check the castle info
  2260.         if ((clan != null) && (clan.getLeader().getPlayerInstance() == this))
  2261.         {
  2262.             // if the clan has a castle and it is actually the queried castle, return true
  2263.             Castle castle = CastleManager.getInstance().getCastleByOwner(clan);
  2264.             if ((castle != null) && (castle == CastleManager.getInstance().getCastleById(castleId)))
  2265.                 return true;
  2266.         }
  2267.  
  2268.  
  2269.         return false;
  2270.     }
  2271.  
  2272.     /**
  2273.      * Return the Clan Identifier of the L2PcInstance.<BR><BR>
  2274.      */
  2275.     public int getClanId()
  2276.     {
  2277.         return _clanId;
  2278.     }
  2279.  
  2280.     /**
  2281.      * Return the Clan Crest Identifier of the L2PcInstance or 0.<BR><BR>
  2282.      */
  2283.     public int getClanCrestId()
  2284.     {        
  2285.         if (_clan != null && _clan.hasCrest())
  2286.             return _clan.getCrestId();
  2287.  
  2288.         return 0;
  2289.     }
  2290.  
  2291.     /**
  2292.      * @return The Clan CrestLarge Identifier or 0
  2293.      */
  2294.     public int getClanCrestLargeId()
  2295.     {        
  2296.         if (_clan != null && _clan.hasCrestLarge())
  2297.             return _clan.getCrestLargeId();
  2298.  
  2299.         return 0;
  2300.     }
  2301.  
  2302.     public long getClanJoinExpiryTime()
  2303.  
  2304.     {
  2305.  
  2306.         return _clanJoinExpiryTime;
  2307.  
  2308.     }
  2309.  
  2310.     public void setClanJoinExpiryTime(long time)
  2311.     {
  2312.         _clanJoinExpiryTime = time;
  2313.     }
  2314.  
  2315.     public long getClanCreateExpiryTime()
  2316.     {
  2317.         return _clanCreateExpiryTime;
  2318.     }
  2319.  
  2320.     public void setClanCreateExpiryTime(long time)
  2321.     {
  2322.         _clanCreateExpiryTime = time;
  2323.     }
  2324.  
  2325.     public void setOnlineTime(long time)
  2326.     {
  2327.         _onlineTime = time;
  2328.         _onlineBeginTime = System.currentTimeMillis();
  2329.     }
  2330.  
  2331.     /**
  2332.      * Return the PcInventory Inventory of the L2PcInstance contained in _inventory.<BR><BR>
  2333.      */
  2334.     public PcInventory getInventory()
  2335.     {
  2336.         return _inventory;
  2337.     }
  2338.  
  2339.     /**
  2340.      * Delete a ShortCut of the L2PcInstance _shortCuts.<BR><BR>
  2341.      */
  2342.     public void removeItemFromShortCut(int objectId)
  2343.     {
  2344.         _shortCuts.deleteShortCutByObjectId(objectId);
  2345.     }
  2346.  
  2347.     /**
  2348.      * Return True if the L2PcInstance is sitting.<BR><BR>
  2349.      */
  2350.     public boolean isSitting()
  2351.     {
  2352.         return _waitTypeSitting;
  2353.     }
  2354.  
  2355.     /**
  2356.      * Set _waitTypeSitting to given value
  2357.      */
  2358.     public void setIsSitting(boolean state)
  2359.     {
  2360.         _waitTypeSitting = state;
  2361.     }
  2362.  
  2363.     /**
  2364.      * Sit down the L2PcInstance, set the AI Intention to AI_INTENTION_REST and send a Server->Client ChangeWaitType packet (broadcast)<BR><BR>
  2365.      */
  2366.     public void sitDown()
  2367.     {
  2368.         if (!_waitTypeSitting)
  2369.         {
  2370.             abortAttack();
  2371.  
  2372.             setIsSitting(true);
  2373.  
  2374.             broadcastPacket(new ChangeWaitType (this, ChangeWaitType.WT_SITTING));
  2375.             // Schedule a sit down task to wait for the animation to finish
  2376.             ThreadPoolManager.getInstance().scheduleGeneral(new SitDownTask(this), 2500);
  2377.             setIsParalyzed(true);
  2378.         }
  2379.     }
  2380.  
  2381.     /**
  2382.      * Sit down Task
  2383.      */
  2384.     class SitDownTask implements Runnable
  2385.     {
  2386.         L2PcInstance _player;
  2387.         SitDownTask(L2PcInstance player)
  2388.         {
  2389.             _player = player;
  2390.         }
  2391.  
  2392.         public void run()
  2393.         {
  2394.             _player.setIsParalyzed(false);
  2395.             _player.getAI().setIntention(CtrlIntention.AI_INTENTION_REST);
  2396.         }
  2397.     }
  2398.  
  2399.     /**
  2400.      * Stand up Task
  2401.      */
  2402.     class StandUpTask implements Runnable
  2403.     {
  2404.         L2PcInstance _player;
  2405.         StandUpTask(L2PcInstance player)
  2406.         {
  2407.             _player = player;
  2408.         }
  2409.  
  2410.         public void run()
  2411.         {
  2412.             _player.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  2413.             _player.setIsSitting(false);
  2414.             if (_player.getAI().getNextIntention() != null)
  2415.             {
  2416.                 _player.getAI().setIntention(_player.getAI().getNextIntention()._crtlIntention, _player.getAI().getNextIntention()._arg0, _player.getAI().getNextIntention()._arg1);
  2417.                 _player.getAI().setNextIntention(null);
  2418.             }
  2419.         }
  2420.     }
  2421.  
  2422.     /**
  2423.      * Stand up the L2PcInstance, set the AI Intention to AI_INTENTION_IDLE and send a Server->Client ChangeWaitType packet (broadcast)<BR><BR>
  2424.      */
  2425.     public void standUp()
  2426.     {
  2427.         if (L2Event.active && eventSitForced)
  2428.             sendMessage("A dark force beyond your mortal understanding makes your knees to shake when you try to stand up ...");
  2429.         else if (isFakeDeath())
  2430.             stopEffects(L2Effect.EffectType.FAKE_DEATH);
  2431.         else if (_waitTypeSitting && !isInStoreMode() && !isDead())
  2432.         {
  2433.             broadcastPacket(new ChangeWaitType (this, ChangeWaitType.WT_STANDING));
  2434.  
  2435.             // Schedule a stand up task to wait for the animation to finish
  2436.  
  2437.             ThreadPoolManager.getInstance().scheduleGeneral(new StandUpTask(this), 2500);
  2438.         }
  2439.     }
  2440.  
  2441.     /**
  2442.      * Set the value of the _relax value. Must be True if using skill Relax and False if not.
  2443.      */
  2444.     public void setRelax(boolean val)
  2445.     {
  2446.         _relax = val;
  2447.     }
  2448.  
  2449.     /**
  2450.      * Return the PcWarehouse object of the L2PcInstance.<BR><BR>
  2451.      */
  2452.     public PcWarehouse getWarehouse()
  2453.     {
  2454.  
  2455.         if (_warehouse == null)
  2456.  
  2457.         {
  2458.  
  2459.             _warehouse = new PcWarehouse(this);
  2460.  
  2461.             _warehouse.restore();
  2462.  
  2463.         }
  2464.  
  2465.  
  2466.         if (Config.WAREHOUSE_CACHE)
  2467.  
  2468.             WarehouseCacheManager.getInstance().addCacheTask(this);
  2469.  
  2470.         return _warehouse;
  2471.     }
  2472.  
  2473.     /**
  2474.      * Free memory used by Warehouse
  2475.      */
  2476.     public void clearWarehouse()
  2477.     {
  2478.         if (_warehouse != null)
  2479.             _warehouse.deleteMe();
  2480.         _warehouse = null;
  2481.     }
  2482.  
  2483.     /**
  2484.      * Return the PcFreight object of the L2PcInstance.<BR><BR>
  2485.      */
  2486.     public PcFreight getFreight()
  2487.     {
  2488.         return _freight;
  2489.     }
  2490.  
  2491.     /**
  2492.      * Return the Identifier of the L2PcInstance.<BR><BR>
  2493.      */
  2494.     public int getCharId()
  2495.     {
  2496.         return _charId;
  2497.     }
  2498.  
  2499.     /**
  2500.      * Set the Identifier of the L2PcInstance.<BR><BR>
  2501.      */
  2502.     public void setCharId(int charId)
  2503.     {
  2504.         _charId = charId;
  2505.     }
  2506.  
  2507.     /**
  2508.      * Return the Adena amount of the L2PcInstance.<BR><BR>
  2509.      */
  2510.     public int getAdena()
  2511.     {
  2512.         return _inventory.getAdena();
  2513.     }
  2514.  
  2515.     /**
  2516.      * Return the Ancient Adena amount of the L2PcInstance.<BR><BR>
  2517.      */
  2518.     public int getAncientAdena()
  2519.     {
  2520.         return _inventory.getAncientAdena();
  2521.     }
  2522.  
  2523.     /**
  2524.      * Add adena to Inventory of the L2PcInstance and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  2525.      * @param process : String Identifier of process triggering this action
  2526.      * @param count : int Quantity of adena to be added
  2527.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  2528.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  2529.      */
  2530.     public void addAdena(String process, int count, L2Object reference, boolean sendMessage)
  2531.     {
  2532.         if (sendMessage)
  2533.         {
  2534.             SystemMessage sm = new SystemMessage(SystemMessage.EARNED_ADENA);
  2535.             sm.addNumber(count);
  2536.             sendPacket(sm);
  2537.         }
  2538.  
  2539.         if (count > 0)
  2540.         {
  2541.             _inventory.addAdena(process, count, this, reference);
  2542.  
  2543.             // Send update packet
  2544.             if (!Config.FORCE_INVENTORY_UPDATE)
  2545.             {
  2546.                 InventoryUpdate iu = new InventoryUpdate();
  2547.                 iu.addItem(_inventory.getAdenaInstance());
  2548.                 sendPacket(iu);
  2549.             }
  2550.             else
  2551.                 sendPacket(new ItemList(this, false));
  2552.         }
  2553.     }
  2554.  
  2555.     /**
  2556.      * Reduce adena in Inventory of the L2PcInstance and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  2557.      * @param process : String Identifier of process triggering this action
  2558.      * @param count : int Quantity of adena to be reduced
  2559.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  2560.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  2561.      * @return boolean informing if the action was successful
  2562.      */
  2563.     public boolean reduceAdena(String process, int count, L2Object reference, boolean sendMessage)
  2564.     {
  2565.         if (count > getAdena())
  2566.         {
  2567.             if (sendMessage)
  2568.                 sendPacket(new SystemMessage(SystemMessage.YOU_NOT_ENOUGH_ADENA));
  2569.  
  2570.             return false;
  2571.         }
  2572.  
  2573.         if (count > 0)
  2574.         {
  2575.             L2ItemInstance adenaItem = _inventory.getAdenaInstance();
  2576.             _inventory.reduceAdena(process, count, this, reference);
  2577.  
  2578.             // Send update packet
  2579.             if (!Config.FORCE_INVENTORY_UPDATE)
  2580.             {
  2581.                 InventoryUpdate iu = new InventoryUpdate();
  2582.                 iu.addItem(adenaItem);
  2583.                 sendPacket(iu);
  2584.             }
  2585.             else
  2586.                 sendPacket(new ItemList(this, false));
  2587.  
  2588.             if (sendMessage)
  2589.             {
  2590.                 SystemMessage sm = new SystemMessage(SystemMessage.DISSAPEARED_ADENA);
  2591.                 sm.addNumber(count);
  2592.                 sendPacket(sm);
  2593.             }
  2594.         }
  2595.  
  2596.         return true;
  2597.     }
  2598.  
  2599.     /**
  2600.      * Add ancient adena to Inventory of the L2PcInstance and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  2601.      *
  2602.      * @param process : String Identifier of process triggering this action
  2603.      * @param count : int Quantity of ancient adena to be added
  2604.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  2605.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  2606.      */
  2607.     public void addAncientAdena(String process, int count, L2Object reference, boolean sendMessage)
  2608.     {
  2609.         if (sendMessage)
  2610.         {
  2611.             SystemMessage sm = new SystemMessage(SystemMessage.EARNED_S2_S1_s);
  2612.             sm.addItemName(PcInventory.ANCIENT_ADENA_ID);
  2613.  
  2614.             sm.addNumber(count);
  2615.             sendPacket(sm);
  2616.         }
  2617.  
  2618.         if (count > 0)
  2619.         {
  2620.             _inventory.addAncientAdena(process, count, this, reference);
  2621.  
  2622.             if (!Config.FORCE_INVENTORY_UPDATE)
  2623.             {
  2624.                 InventoryUpdate iu = new InventoryUpdate();
  2625.                 iu.addItem(_inventory.getAncientAdenaInstance());
  2626.                 sendPacket(iu);
  2627.             }
  2628.             else
  2629.                 sendPacket(new ItemList(this, false));
  2630.         }
  2631.     }
  2632.  
  2633.     /**
  2634.      * Reduce ancient adena in Inventory of the L2PcInstance and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  2635.      * @param process : String Identifier of process triggering this action
  2636.      * @param count : int Quantity of ancient adena to be reduced
  2637.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  2638.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  2639.      * @return boolean informing if the action was successful
  2640.      */
  2641.     public boolean reduceAncientAdena(String process, int count, L2Object reference, boolean sendMessage)
  2642.     {
  2643.         if (count > getAncientAdena())
  2644.         {
  2645.             if (sendMessage)
  2646.                 sendPacket(new SystemMessage(SystemMessage.YOU_NOT_ENOUGH_ADENA));
  2647.  
  2648.             return false;
  2649.         }
  2650.  
  2651.         if (count > 0)
  2652.         {
  2653.             L2ItemInstance ancientAdenaItem = _inventory.getAncientAdenaInstance();
  2654.             _inventory.reduceAncientAdena(process, count, this, reference);
  2655.  
  2656.             if (!Config.FORCE_INVENTORY_UPDATE)
  2657.             {
  2658.                 InventoryUpdate iu = new InventoryUpdate();
  2659.                 iu.addItem(ancientAdenaItem);
  2660.                 sendPacket(iu);
  2661.             }
  2662.             else
  2663.                 sendPacket(new ItemList(this, false));
  2664.  
  2665.             if (sendMessage)
  2666.             {
  2667.                 SystemMessage sm = new SystemMessage(SystemMessage.DISSAPEARED_ITEM);
  2668.                 sm.addNumber(count);
  2669.                 sm.addItemName(PcInventory.ANCIENT_ADENA_ID);
  2670.                 sendPacket(sm);
  2671.             }
  2672.         }
  2673.  
  2674.         return true;
  2675.     }
  2676.  
  2677.  
  2678.     /**
  2679.      * Adds item to inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  2680.      * @param process : String Identifier of process triggering this action
  2681.      * @param item : L2ItemInstance to be added
  2682.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  2683.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  2684.      */
  2685.     public void addItem(String process, L2ItemInstance item, L2Object reference, boolean sendMessage)
  2686.     {
  2687.         if (item.getCount() > 0)
  2688.         {
  2689.             // Sends message to client if requested
  2690.             if (sendMessage)
  2691.             {
  2692.                 if (item.getCount() > 1)
  2693.                 {
  2694.                     SystemMessage sm = new SystemMessage(SystemMessage.YOU_PICKED_UP_S1_S2);
  2695.                     sm.addItemName(item.getItemId());
  2696.                     sm.addNumber(item.getCount());
  2697.                     sendPacket(sm);
  2698.                 }
  2699.                 else if (item.getEnchantLevel() > 0)
  2700.                 {
  2701.                     SystemMessage sm = new SystemMessage(SystemMessage.YOU_PICKED_UP_A_S1_S2);
  2702.                     sm.addNumber(item.getEnchantLevel());
  2703.                     sm.addItemName(item.getItemId());
  2704.                     sendPacket(sm);
  2705.                 }
  2706.                 else
  2707.                 {
  2708.                     SystemMessage sm = new SystemMessage(SystemMessage.YOU_PICKED_UP_S1);
  2709.                     sm.addItemName(item.getItemId());
  2710.                     sendPacket(sm);
  2711.                 }
  2712.             }
  2713.  
  2714.             // Add the item to inventory
  2715.             L2ItemInstance newitem = _inventory.addItem(process, item, this, reference);
  2716.  
  2717.             // Send inventory update packet
  2718.             if (!Config.FORCE_INVENTORY_UPDATE)
  2719.             {
  2720.                 InventoryUpdate playerIU = new InventoryUpdate();
  2721.                 playerIU.addItem(newitem);
  2722.                 sendPacket(playerIU);
  2723.             }
  2724.             else
  2725.                 sendPacket(new ItemList(this, false));
  2726.  
  2727.             // Update current load as well
  2728.             StatusUpdate su = new StatusUpdate(getObjectId());
  2729.             su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  2730.             sendPacket(su);
  2731.  
  2732.             // If over capacity, drop the item
  2733.             if (!isGM() && !_inventory.validateCapacity(0) && item.isDropable() && (!item.isStackable() || item.getLastChange() != L2ItemInstance.MODIFIED))
  2734.                 dropItem("InvDrop", item, null, true, true);
  2735.         }
  2736.     }
  2737.  
  2738.     /**
  2739.      * Adds item to Inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  2740.      * @param process : String Identifier of process triggering this action
  2741.      * @param itemId : int Item Identifier of the item to be added
  2742.      * @param count : int Quantity of items to be added
  2743.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  2744.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  2745.      */
  2746.     public void addItem(String process, int itemId, int count, L2Object reference, boolean sendMessage)
  2747.     {
  2748.         if (count > 0)
  2749.         {
  2750.             // Sends message to client if requested
  2751.             if (sendMessage)
  2752.             {
  2753.                 if (count > 1)
  2754.                 {
  2755.                     if (process.equalsIgnoreCase("sweep") || process.equalsIgnoreCase("Quest"))
  2756.                     {
  2757.                         SystemMessage sm = new SystemMessage(SystemMessage.EARNED_S2_S1_s);
  2758.                         sm.addItemName(itemId);
  2759.                         sm.addNumber(count);
  2760.                         sendPacket(sm);
  2761.                     }
  2762.                     else
  2763.                     {
  2764.                         SystemMessage sm = new SystemMessage(SystemMessage.YOU_PICKED_UP_S1_S2);
  2765.                         sm.addItemName(itemId);
  2766.                         sm.addNumber(count);
  2767.                         sendPacket(sm);
  2768.                     }
  2769.                 }
  2770.                 else
  2771.                 {
  2772.                     if (process.equalsIgnoreCase("sweep") || process.equalsIgnoreCase("Quest"))
  2773.                     {
  2774.                         SystemMessage sm = new SystemMessage(SystemMessage.EARNED_ITEM);
  2775.                         sm.addItemName(itemId);
  2776.                         sendPacket(sm);
  2777.                     }
  2778.                     else
  2779.                     {
  2780.                         SystemMessage sm = new SystemMessage(SystemMessage.YOU_PICKED_UP_S1);
  2781.                         sm.addItemName(itemId);
  2782.                         sendPacket(sm);
  2783.                     }
  2784.                 }
  2785.             }
  2786.  
  2787.             // Add the item to inventory
  2788.             L2ItemInstance item = _inventory.addItem(process, itemId, count, this, reference);
  2789.  
  2790.             // Send inventory update packet
  2791.             if (!Config.FORCE_INVENTORY_UPDATE)
  2792.             {
  2793.                 InventoryUpdate playerIU = new InventoryUpdate();
  2794.                 playerIU.addItem(item);
  2795.                 sendPacket(playerIU);
  2796.             }
  2797.             else
  2798.                 sendPacket(new ItemList(this, false));
  2799.  
  2800.             // Update current load as well
  2801.             StatusUpdate su = new StatusUpdate(getObjectId());
  2802.             su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  2803.             sendPacket(su);
  2804.  
  2805.             // If over capacity, drop the item
  2806.             if (!isGM() && !_inventory.validateCapacity(0) && item.isDropable() && (!item.isStackable() || item.getLastChange() != L2ItemInstance.MODIFIED))
  2807.                 dropItem("InvDrop", item, null, true);
  2808.         }
  2809.     }
  2810.  
  2811.     /**
  2812.      * Destroy item from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  2813.      * @param process : String Identifier of process triggering this action
  2814.      * @param item : L2ItemInstance to be destroyed
  2815.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  2816.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  2817.      * @return boolean informing if the action was successfull
  2818.      */
  2819.     public boolean destroyItem(String process, L2ItemInstance item, L2Object reference, boolean sendMessage)
  2820.     {
  2821.         return destroyItem(process, item, item.getCount(), reference, sendMessage);
  2822.     }
  2823.  
  2824.     /**
  2825.      * Destroy item from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  2826.      * @param process : String Identifier of process triggering this action
  2827.      * @param item : L2ItemInstance to be destroyed
  2828.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  2829.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  2830.      * @return boolean informing if the action was successful
  2831.      */
  2832.     public boolean destroyItem(String process, L2ItemInstance item, int count, L2Object reference, boolean sendMessage)
  2833.     {
  2834.         item = _inventory.destroyItem(process, item, count, this, reference);
  2835.  
  2836.         if (item == null)
  2837.         {
  2838.             if (sendMessage)
  2839.                 sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_ITEMS));
  2840.  
  2841.  
  2842.             return false;
  2843.         }
  2844.  
  2845.         // Send inventory update packet
  2846.         if (!Config.FORCE_INVENTORY_UPDATE)
  2847.         {
  2848.             InventoryUpdate playerIU = new InventoryUpdate();
  2849.             playerIU.addItem(item);
  2850.             sendPacket(playerIU);
  2851.         }
  2852.         else
  2853.             sendPacket(new ItemList(this, false));
  2854.  
  2855.         // Update current load as well
  2856.         StatusUpdate su = new StatusUpdate(getObjectId());
  2857.         su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  2858.         sendPacket(su);
  2859.  
  2860.         // Sends message to client if requested
  2861.         if (sendMessage)
  2862.         {
  2863.             SystemMessage sm = new SystemMessage(SystemMessage.DISSAPEARED_ITEM);
  2864.             sm.addNumber(count);
  2865.             sm.addItemName(item.getItemId());
  2866.             sendPacket(sm);
  2867.         }
  2868.  
  2869.         return true;
  2870.     }
  2871.  
  2872.     /**
  2873.      * Destroys item from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  2874.      * @param process : String Identifier of process triggering this action
  2875.      * @param objectId : int Item Instance identifier of the item to be destroyed
  2876.      * @param count : int Quantity of items to be destroyed
  2877.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  2878.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  2879.      * @return boolean informing if the action was successfull
  2880.      */
  2881.     public boolean destroyItem(String process, int objectId, int count, L2Object reference, boolean sendMessage)
  2882.     {
  2883.  
  2884.         L2ItemInstance item = _inventory.getItemByObjectId(objectId);
  2885.  
  2886.         if (item == null)
  2887.         {
  2888.             if (sendMessage)
  2889.                 sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_ITEMS));
  2890.  
  2891.  
  2892.             return false;
  2893.         }
  2894.  
  2895.         return destroyItem(process, item, count, reference, sendMessage);
  2896.     }
  2897.  
  2898.     /**
  2899.      * Destroys shots from inventory without logging and only occasional saving to database.
  2900.      * Sends a Server->Client InventoryUpdate packet to the L2PcInstance.
  2901.      * @param process : String Identifier of process triggering this action
  2902.      * @param objectId : int Item Instance identifier of the item to be destroyed
  2903.      * @param count : int Quantity of items to be destroyed
  2904.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  2905.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  2906.      * @return boolean informing if the action was successfull
  2907.      */
  2908.     public boolean destroyItemWithoutTrace(String process, int objectId, int count, L2Object reference, boolean sendMessage)
  2909.     {
  2910.         L2ItemInstance item = _inventory.getItemByObjectId(objectId);
  2911.  
  2912.         if (item == null || item.getCount() < count)
  2913.         {
  2914.             if (sendMessage)
  2915.                 sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_ITEMS));
  2916.             return false;
  2917.         }
  2918.  
  2919.         return destroyItem(null, item, count, reference, sendMessage);
  2920.     }
  2921.  
  2922.     /**
  2923.      * Destroy item from inventory by using its <B>itemId</B> and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  2924.      * @param process : String Identifier of process triggering this action
  2925.      * @param itemId : int Item identifier of the item to be destroyed
  2926.      * @param count : int Quantity of items to be destroyed
  2927.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  2928.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  2929.      * @return boolean informing if the action was successfull
  2930.      */
  2931.     public boolean destroyItemByItemId(String process, int itemId, int count, L2Object reference, boolean sendMessage)
  2932.     {
  2933.  
  2934.         L2ItemInstance item = _inventory.getItemByItemId(itemId);
  2935.  
  2936.         if (item == null || item.getCount() < count || _inventory.destroyItemByItemId(process, itemId, count, this, reference) == null)
  2937.         {
  2938.             if (sendMessage)
  2939.  
  2940.                 sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_ITEMS));
  2941.  
  2942.  
  2943.             return false;
  2944.         }
  2945.  
  2946.         // Send inventory update packet
  2947.         if (!Config.FORCE_INVENTORY_UPDATE)
  2948.         {
  2949.             InventoryUpdate playerIU = new InventoryUpdate();
  2950.             playerIU.addItem(item);
  2951.             sendPacket(playerIU);
  2952.         }
  2953.         else
  2954.             sendPacket(new ItemList(this, false));
  2955.  
  2956.         // Update current load as well
  2957.         StatusUpdate su = new StatusUpdate(getObjectId());
  2958.         su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  2959.         sendPacket(su);
  2960.  
  2961.         // Sends message to client if requested
  2962.         if (sendMessage)
  2963.         {
  2964.             SystemMessage sm = new SystemMessage(SystemMessage.DISSAPEARED_ITEM);
  2965.  
  2966.             sm.addNumber(count);
  2967.  
  2968.             sm.addItemName(itemId);
  2969.             sendPacket(sm);
  2970.         }
  2971.  
  2972.  
  2973.         return true;
  2974.     }
  2975.  
  2976.     /**
  2977.      * Destroy all weared items from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  2978.      * @param process : String Identifier of process triggering this action
  2979.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  2980.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  2981.      * @return boolean informing if the action was successfull
  2982.      */
  2983.     public void destroyWearedItems(String process, L2Object reference, boolean sendMessage)
  2984.     {
  2985.  
  2986.         // Go through all Items of the inventory
  2987.  
  2988.         for (L2ItemInstance item : getInventory().getItems())
  2989.         {
  2990.             if (item == null)
  2991.                 continue;
  2992.  
  2993.  
  2994.             // Check if the item is a Try On item in order to remove it
  2995.             if (item.isWear())
  2996.             {
  2997.  
  2998.                 if (item.isEquipped())
  2999.  
  3000.                     getInventory().unEquipItemInSlotAndRecord(item.getEquipSlot());
  3001.  
  3002.  
  3003.                 if (_inventory.destroyItem(process, item, this, reference) == null)
  3004.                 {
  3005.                     _log.warning("Player " + getName() + " can't destroy weared item: " + item.getName() + "[ " + item.getObjectId() + " ]");
  3006.                     continue;
  3007.                 }
  3008.  
  3009.  
  3010.                 // Send an Unequipped Message in system window of the player for each Item
  3011.                 SystemMessage sm = new SystemMessage(0x1a1);
  3012.                 sm.addItemName(item.getItemId());
  3013.                 sendPacket(sm);
  3014.  
  3015.             }
  3016.         }
  3017.  
  3018.  
  3019.  
  3020.         // Send the StatusUpdate Server->Client Packet to the player with new CUR_LOAD (0x0e) information
  3021.         StatusUpdate su = new StatusUpdate(getObjectId());
  3022.         su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  3023.         sendPacket(su);
  3024.    
  3025.  
  3026.         // Send the ItemList Server->Client Packet to the player in order to refresh its Inventory
  3027.  
  3028.         ItemList il = new ItemList(getInventory().getItemList(), true);
  3029.  
  3030.         sendPacket(il);
  3031.  
  3032.  
  3033.  
  3034.         // Send a Server->Client packet UserInfo to this L2PcInstance and CharInfo to all L2PcInstance in its _KnownPlayers
  3035.         broadcastUserInfo();
  3036.  
  3037.         // Sends message to client if requested
  3038.         sendMessage("Trying-on mode has ended.");
  3039.  
  3040.     }
  3041.  
  3042.     /**
  3043.      * Transfers item to another ItemContainer and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3044.      * @param process : String Identifier of process triggering this action
  3045.      * @param itemId : int Item Identifier of the item to be transfered
  3046.      * @param count : int Quantity of items to be transfered
  3047.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3048.      * @return L2ItemInstance corresponding to the new item or the updated item in inventory
  3049.      */
  3050.     public L2ItemInstance transferItem(String process, int objectId, int count, Inventory target, L2Object reference)
  3051.     {
  3052.         L2ItemInstance oldItem = checkItemManipulation(objectId, count, "transfer");
  3053.         if (oldItem == null)
  3054.             return null;
  3055.  
  3056.         L2ItemInstance newItem = getInventory().transferItem(process, objectId, count, target, this, reference);
  3057.         if (newItem == null)
  3058.             return null;
  3059.  
  3060.         // Send inventory update packet
  3061.         if (!Config.FORCE_INVENTORY_UPDATE)
  3062.         {
  3063.             InventoryUpdate playerIU = new InventoryUpdate();
  3064.  
  3065.             if (oldItem.getCount() > 0 && oldItem != newItem)
  3066.  
  3067.                 playerIU.addModifiedItem(oldItem);
  3068.             else
  3069.  
  3070.                 playerIU.addRemovedItem(oldItem);
  3071.  
  3072.             sendPacket(playerIU);
  3073.         }
  3074.         else
  3075.             sendPacket(new ItemList(this, false));
  3076.  
  3077.         // Update current load as well
  3078.         StatusUpdate playerSU = new StatusUpdate(getObjectId());
  3079.         playerSU.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  3080.         sendPacket(playerSU);
  3081.  
  3082.         // Send target update packet
  3083.         if (target instanceof PcInventory)
  3084.         {
  3085.             L2PcInstance targetPlayer = ((PcInventory)target).getOwner();
  3086.  
  3087.             if (!Config.FORCE_INVENTORY_UPDATE)
  3088.             {
  3089.                 InventoryUpdate playerIU = new InventoryUpdate();
  3090.  
  3091.                 if (newItem.getCount() > count)
  3092.  
  3093.                     playerIU.addModifiedItem(newItem);
  3094.                 else
  3095.  
  3096.                     playerIU.addNewItem(newItem);
  3097.  
  3098.  
  3099.                 targetPlayer.sendPacket(playerIU);
  3100.             }
  3101.             else
  3102.                 targetPlayer.sendPacket(new ItemList(targetPlayer, false));
  3103.  
  3104.             // Update current load as well
  3105.             playerSU = new StatusUpdate(targetPlayer.getObjectId());
  3106.             playerSU.addAttribute(StatusUpdate.CUR_LOAD, targetPlayer.getCurrentLoad());
  3107.             targetPlayer.sendPacket(playerSU);
  3108.         }
  3109.         else if (target instanceof PetInventory)
  3110.         {
  3111.             PetInventoryUpdate petIU = new PetInventoryUpdate();
  3112.             if (newItem.getCount() > count)
  3113.  
  3114.                 petIU.addModifiedItem(newItem);
  3115.             else
  3116.  
  3117.                 petIU.addNewItem(newItem);
  3118.  
  3119.  
  3120.             ((PetInventory)target).getOwner().getOwner().sendPacket(petIU);
  3121.             getPet().getInventory().refreshWeight();
  3122.  
  3123.         }
  3124.  
  3125.         return newItem;
  3126.     }
  3127.  
  3128.     /**
  3129.      * Drop item from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3130.      * @param process : String Identifier of process triggering this action
  3131.      * @param item : L2ItemInstance to be dropped
  3132.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3133.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3134.      * @param protectItem: whether or not dropped item must be protected temporary against other players
  3135.      * @return boolean informing if the action was successfull
  3136.      */
  3137.     public boolean dropItem(String process, L2ItemInstance item, L2Object reference, boolean sendMessage, boolean protectItem)
  3138.     {
  3139.         item = _inventory.dropItem(process, item, this, reference);
  3140.  
  3141.         if (item == null)
  3142.         {
  3143.             if (sendMessage)
  3144.  
  3145.                 sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_ITEMS));
  3146.  
  3147.  
  3148.             return false;
  3149.         }
  3150.  
  3151.         item.dropMe(this, getX() + Rnd.get(50) - 25, getY() + Rnd.get(50) - 25, getZ() + 20);
  3152.  
  3153.  
  3154.         if (Config.AUTODESTROY_ITEM_AFTER > 0 && Config.DESTROY_DROPPED_PLAYER_ITEM && !Config.LIST_PROTECTED_ITEMS.contains(item.getItemId()))
  3155.  
  3156.         {
  3157.  
  3158.             if ((item.isEquipable() && Config.DESTROY_EQUIPABLE_PLAYER_ITEM) || !item.isEquipable())
  3159.  
  3160.  
  3161.  
  3162.                 ItemsAutoDestroy.getInstance().addItem(item);
  3163.  
  3164.         }
  3165.  
  3166.  
  3167.         if (Config.DESTROY_DROPPED_PLAYER_ITEM)
  3168.  
  3169.         {
  3170.  
  3171.             if (!item.isEquipable() || (item.isEquipable()  && Config.DESTROY_EQUIPABLE_PLAYER_ITEM))
  3172.  
  3173.                 item.setProtected(false);
  3174.  
  3175.             else
  3176.  
  3177.                 item.setProtected(true);
  3178.  
  3179.         }
  3180.  
  3181.         else
  3182.  
  3183.             item.setProtected(true);
  3184.  
  3185.         // retail drop protection
  3186.         if (protectItem)
  3187.             item.getDropProtection().protect(this);
  3188.  
  3189.         // Send inventory update packet
  3190.         if (!Config.FORCE_INVENTORY_UPDATE)
  3191.         {
  3192.             InventoryUpdate playerIU = new InventoryUpdate();
  3193.             playerIU.addItem(item);
  3194.             sendPacket(playerIU);
  3195.         }
  3196.         else
  3197.             sendPacket(new ItemList(this, false));
  3198.  
  3199.         // Update current load as well
  3200.         StatusUpdate su = new StatusUpdate(getObjectId());
  3201.         su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  3202.         sendPacket(su);
  3203.  
  3204.         // Sends message to client if requested
  3205.         if (sendMessage)
  3206.         {
  3207.             SystemMessage sm = new SystemMessage(SystemMessage.YOU_DROPPED_S1);
  3208.             sm.addItemName(item.getItemId());
  3209.             sendPacket(sm);
  3210.         }
  3211.  
  3212.  
  3213.         return true;
  3214.     }
  3215.  
  3216.     public boolean dropItem(String process, L2ItemInstance item, L2Object reference, boolean sendMessage)
  3217.     {
  3218.         return dropItem(process, item, reference, sendMessage, false);
  3219.     }
  3220.  
  3221.     /**
  3222.      * Drop item from inventory by using its <B>objectID</B> and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3223.      * @param process : String Identifier of process triggering this action
  3224.      * @param objectId : int Item Instance identifier of the item to be dropped
  3225.      * @param count : int Quantity of items to be dropped
  3226.      * @param x : int coordinate for drop X
  3227.      * @param y : int coordinate for drop Y
  3228.      * @param z : int coordinate for drop Z
  3229.      * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3230.      * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3231.      * @return L2ItemInstance corresponding to the new item or the updated item in inventory
  3232.      */
  3233.     public L2ItemInstance dropItem(String process, int objectId, int count, int x, int y, int z, L2Object reference, boolean sendMessage, boolean protectItem)
  3234.     {
  3235.         L2ItemInstance invitem = _inventory.getItemByObjectId(objectId);
  3236.         L2ItemInstance item = _inventory.dropItem(process, objectId, count, this, reference);
  3237.  
  3238.  
  3239.         if (item == null)
  3240.         {
  3241.             if (sendMessage)
  3242.  
  3243.                 sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_ITEMS));
  3244.  
  3245.  
  3246.             return null;
  3247.         }
  3248.  
  3249.         item.dropMe(this, x, y, z);
  3250.  
  3251.  
  3252.         if (Config.AUTODESTROY_ITEM_AFTER > 0 && Config.DESTROY_DROPPED_PLAYER_ITEM && !Config.LIST_PROTECTED_ITEMS.contains(item.getItemId()))
  3253.  
  3254.         {
  3255.  
  3256.             if ((item.isEquipable() && Config.DESTROY_EQUIPABLE_PLAYER_ITEM) || !item.isEquipable())
  3257.  
  3258.             {
  3259.  
  3260.                 ItemsAutoDestroy.getInstance().addItem(item);
  3261.  
  3262.             }
  3263.  
  3264.         }
  3265.  
  3266.  
  3267.         if (Config.DESTROY_DROPPED_PLAYER_ITEM)
  3268.  
  3269.         {
  3270.  
  3271.             if (!item.isEquipable() || (item.isEquipable()  && Config.DESTROY_EQUIPABLE_PLAYER_ITEM))
  3272.  
  3273.                 item.setProtected(false);
  3274.  
  3275.             else
  3276.  
  3277.                 item.setProtected(true);
  3278.  
  3279.         }
  3280.  
  3281.         else
  3282.  
  3283.             item.setProtected(true);
  3284.  
  3285.         // retail drop protection
  3286.         if (protectItem)
  3287.             item.getDropProtection().protect(this);
  3288.  
  3289.         // Send inventory update packet
  3290.         if (!Config.FORCE_INVENTORY_UPDATE)
  3291.         {
  3292.             InventoryUpdate playerIU = new InventoryUpdate();
  3293.             playerIU.addItem(invitem);
  3294.             sendPacket(playerIU);
  3295.         }
  3296.         else
  3297.             sendPacket(new ItemList(this, false));
  3298.  
  3299.         // Update current load as well
  3300.         StatusUpdate su = new StatusUpdate(getObjectId());
  3301.         su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  3302.         sendPacket(su);
  3303.  
  3304.         // Sends message to client if requested
  3305.         if (sendMessage)
  3306.         {
  3307.             SystemMessage sm = new SystemMessage(SystemMessage.YOU_DROPPED_S1);
  3308.             sm.addItemName(item.getItemId());
  3309.             sendPacket(sm);
  3310.         }
  3311.  
  3312.  
  3313.         return item;
  3314.     }
  3315.  
  3316.     public L2ItemInstance checkItemManipulation(int objectId, int count, String action)
  3317.     {
  3318.  
  3319.         //TODO: if we remove objects that are not visible from the L2World, we'll have to remove this check
  3320.         if (L2World.getInstance().findObject(objectId) == null)
  3321.         {
  3322.             _log.finest(getObjectId()+": player tried to " + action + " item not available in L2World");
  3323.             return null;
  3324.         }
  3325.  
  3326.         L2ItemInstance item = getInventory().getItemByObjectId(objectId);
  3327.         if (item == null || item.getOwnerId() != getObjectId())
  3328.         {
  3329.             _log.finest(getObjectId()+": player tried to " + action + " item he is not owner of");
  3330.             return null;
  3331.         }
  3332.  
  3333.         if (count < 0 || (count > 1 && !item.isStackable()))
  3334.         {
  3335.             _log.finest(getObjectId()+": player tried to " + action + " item with invalid count: "+ count);
  3336.             return null;
  3337.         }
  3338.  
  3339.         if (count > item.getCount())
  3340.         {
  3341.             _log.finest(getObjectId()+": player tried to " + action + " more items than he owns");
  3342.             return null;
  3343.         }
  3344.  
  3345.         // Pet is summoned and not the item that summoned the pet AND not the buggle from strider you're mounting
  3346.         if (getPet() != null && getPet().getControlItemId() == objectId || getMountObjectID() == objectId)
  3347.         {
  3348.             if (Config.DEBUG)
  3349.                 _log.finest(getObjectId()+": player tried to " + action + " item controling pet");
  3350.  
  3351.  
  3352.             return null;
  3353.         }
  3354.  
  3355.         if (getActiveEnchantItem() != null && getActiveEnchantItem().getObjectId() == objectId)
  3356.         {
  3357.             if (Config.DEBUG)
  3358.                 _log.finest(getObjectId()+":player tried to " + action + " an enchant scroll he was using");
  3359.  
  3360.  
  3361.             return null;
  3362.         }
  3363.  
  3364.         if (item.isWear())
  3365.             return null;
  3366.  
  3367.         return item;
  3368.     }
  3369.  
  3370.     /**
  3371.      * Set _protectEndTime according settings.
  3372.      */
  3373.     public void setProtection(boolean protect)
  3374.     {
  3375.         if (Config.DEVELOPER && (protect || isSpawnProtected()))
  3376.  
  3377.             System.out.println(this.getName() + ": Protection " + (protect?"ON " + (GameTimeController.getGameTicks() + Config.PLAYER_SPAWN_PROTECTION * GameTimeController.TICKS_PER_SECOND) :"OFF") + " (currently " + GameTimeController.getGameTicks() + ")");
  3378.  
  3379.  
  3380.         _protectEndTime = protect ? GameTimeController.getGameTicks() + Config.PLAYER_SPAWN_PROTECTION * GameTimeController.TICKS_PER_SECOND : 0;
  3381.     }
  3382.  
  3383.     /**
  3384.      * Set protection from agro mobs when getting up from fake death, according settings.
  3385.      */
  3386.     public void setRecentFakeDeath(boolean protect)
  3387.     {
  3388.         _recentFakeDeathEndTime = protect ? GameTimeController.getGameTicks() + Config.PLAYER_FAKEDEATH_UP_PROTECTION * GameTimeController.TICKS_PER_SECOND : 0;
  3389.     }
  3390.  
  3391.     public boolean isRecentFakeDeath()
  3392.     {
  3393.         return _recentFakeDeathEndTime > GameTimeController.getGameTicks();
  3394.     }
  3395.  
  3396.  
  3397.     /**
  3398.      * Return the active connection with the client.<BR><BR>
  3399.      */
  3400.     public Connection getNetConnection()
  3401.     {
  3402.         return _connection;
  3403.     }
  3404.  
  3405.     /**
  3406.      * Set the active connection with the client.<BR><BR>
  3407.      */
  3408.     public void setNetConnection(Connection connection)
  3409.     {
  3410.         _connection = connection;
  3411.     }
  3412.  
  3413.     /**
  3414.      * Close the active connection with the client.<BR><BR>
  3415.      */
  3416.     public void closeNetConnection()
  3417.     {
  3418.         if (getNetConnection() != null)
  3419.  
  3420.             getNetConnection().close();
  3421.     }
  3422.  
  3423.     /**
  3424.      * Manage actions when a player click on this L2PcInstance.<BR><BR>
  3425.      *
  3426.      * <B><U> Actions on first click on the L2PcInstance (Select it)</U> :</B><BR><BR>
  3427.      * <li>Set the target of the player</li>
  3428.      * <li>Send a Server->Client packet MyTargetSelected to the player (display the select window)</li><BR><BR>
  3429.      *
  3430.      * <B><U> Actions on second click on the L2PcInstance (Follow it/Attack it/Intercat with it)</U> :</B><BR><BR>
  3431.      * <li>Send a Server->Client packet MyTargetSelected to the player (display the select window)</li>
  3432.      * <li>If this L2PcInstance has a Private Store, notify the player AI with AI_INTENTION_INTERACT</li>
  3433.      * <li>If this L2PcInstance is autoAttackable, notify the player AI with AI_INTENTION_ATTACK</li><BR><BR>
  3434.      * <li>If this L2PcInstance is NOT autoAttackable, notify the player AI with AI_INTENTION_FOLLOW</li><BR><BR>
  3435.      *
  3436.      * <B><U> Example of use </U> :</B><BR><BR>
  3437.      * <li> Client packet : Action, AttackRequest</li><BR><BR>
  3438.      *
  3439.      * @param player The player that start an action on this L2PcInstance
  3440.      *
  3441.      */
  3442.     public void onAction(L2PcInstance player)
  3443.     {
  3444.         // Check if the L2PcInstance is confused
  3445.         if (player.isOutOfControl())
  3446.         {
  3447.             // Send a Server->Client packet ActionFailed to the player
  3448.             player.sendPacket(new ActionFailed());
  3449.  
  3450.             return;
  3451.         }
  3452.  
  3453.         // Check if the player already target this L2PcInstance
  3454.         if (player.getTarget() != this)
  3455.         {
  3456.             // Set the target of the player
  3457.             player.setTarget(this);
  3458.  
  3459.             // Send a Server->Client packet MyTargetSelected to the player
  3460.             // The color to display in the select window is White
  3461.             player.sendPacket(new MyTargetSelected(getObjectId(), 0));
  3462.  
  3463.             if (player != this && !isInBoat())
  3464.                 player.sendPacket(new ValidateLocation(this));
  3465.         }
  3466.         else
  3467.         {
  3468.  
  3469.             if (player != this && !isInBoat())
  3470.                 player.sendPacket(new ValidateLocation(this));
  3471.  
  3472.             // Check if this L2PcInstance has a Private Store
  3473.             if (getPrivateStoreType() != 0)
  3474.  
  3475.                 player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
  3476.  
  3477.             else
  3478.             {
  3479.                 // Check if this L2PcInstance is autoAttackable
  3480.                 if (isAutoAttackable(player))
  3481.  
  3482.                 {
  3483.  
  3484.                     if (Config.GEODATA > 0)
  3485.  
  3486.                     {
  3487.  
  3488.                         if (GeoData.getInstance().canSeeTarget(player, this))
  3489.  
  3490.                         {
  3491.  
  3492.                             player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
  3493.  
  3494.                             player.onActionRequest();
  3495.  
  3496.                         }
  3497.  
  3498.                     }
  3499.  
  3500.                     else
  3501.  
  3502.                     {
  3503.  
  3504.                         player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
  3505.  
  3506.                         player.onActionRequest();
  3507.  
  3508.                     }
  3509.  
  3510.                 }
  3511.                 else
  3512.  
  3513.                 {
  3514.  
  3515.                     // This Action Failed packet avoids player getting stuck when clicking three or more times
  3516.  
  3517.                     player.sendPacket(new ActionFailed());
  3518.                     if (Config.GEODATA > 0)
  3519.  
  3520.                     {
  3521.  
  3522.                         if (GeoData.getInstance().canSeeTarget(player, this))
  3523.  
  3524.                             player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
  3525.  
  3526.                     }
  3527.  
  3528.                     else
  3529.  
  3530.                         player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
  3531.  
  3532.                 }
  3533.             }
  3534.         }
  3535.     }
  3536.  
  3537.     public void onActionShift(ClientThread client)
  3538.     {
  3539.         // Get the L2PcInstance corresponding to the thread
  3540.         L2PcInstance player = client.getActiveChar();
  3541.         if (player == null)
  3542.             return;
  3543.  
  3544.         // Check if the L2PcInstance is confused
  3545.         if (player.isOutOfControl())
  3546.         {
  3547.             // Send a Server->Client packet ActionFailed to the player
  3548.             player.sendPacket(new ActionFailed());
  3549.  
  3550.             return;
  3551.         }
  3552.  
  3553.         // Check if the player already target this L2PcInstance
  3554.         if (player.getTarget() != this)
  3555.         {
  3556.             // Set the target of the player
  3557.             player.setTarget(this);
  3558.  
  3559.             // Send a Server->Client packet MyTargetSelected to the player
  3560.             // The color to display in the select window is White
  3561.             player.sendPacket(new MyTargetSelected(getObjectId(), 0));
  3562.         }
  3563.  
  3564.         if (player != this && !isInBoat())
  3565.             player.sendPacket(new ValidateLocation(this));
  3566.  
  3567.         // This Action Failed packet avoids player getting stuck when shift-clicking
  3568.  
  3569.         player.sendPacket(new ActionFailed());
  3570.     }
  3571.  
  3572.     /**
  3573.      * Returns true if cp update should be done, false if not
  3574.      * @return boolean
  3575.      */
  3576.     private boolean needCpUpdate(int barPixels)
  3577.     {
  3578.         double currentCp = getCurrentCp();
  3579.  
  3580.         if (currentCp <= 1.0 || getMaxCp() < barPixels)
  3581.             return true;
  3582.  
  3583.         if (currentCp <= _cpUpdateDecCheck || currentCp >= _cpUpdateIncCheck)
  3584.         {
  3585.             if (currentCp == getMaxCp())
  3586.             {
  3587.                 _cpUpdateIncCheck = currentCp + 1;
  3588.                 _cpUpdateDecCheck = currentCp - _cpUpdateInterval;
  3589.             }
  3590.             else
  3591.             {
  3592.                 double doubleMulti = currentCp / _cpUpdateInterval;
  3593.                 int intMulti = (int)doubleMulti;
  3594.  
  3595.                 _cpUpdateDecCheck = _cpUpdateInterval * (doubleMulti < intMulti ? intMulti-- : intMulti);
  3596.                 _cpUpdateIncCheck = _cpUpdateDecCheck + _cpUpdateInterval;
  3597.             }
  3598.  
  3599.             return true;
  3600.         }
  3601.  
  3602.         return false;
  3603.     }
  3604.  
  3605.     /**
  3606.      * Returns true if mp update should be done, false if not
  3607.      * @return boolean
  3608.      */
  3609.     private boolean needMpUpdate(int barPixels)
  3610.     {
  3611.         double currentMp = getCurrentMp();
  3612.  
  3613.         if (currentMp <= 1.0 || getMaxMp() < barPixels)
  3614.             return true;
  3615.  
  3616.         if (currentMp <= _mpUpdateDecCheck || currentMp >= _mpUpdateIncCheck)
  3617.         {
  3618.             if (currentMp == getMaxMp())
  3619.             {
  3620.                 _mpUpdateIncCheck = currentMp + 1;
  3621.                 _mpUpdateDecCheck = currentMp - _mpUpdateInterval;
  3622.             }
  3623.             else
  3624.             {
  3625.                 double doubleMulti = currentMp / _mpUpdateInterval;
  3626.                 int intMulti = (int)doubleMulti;
  3627.  
  3628.                 _mpUpdateDecCheck = _mpUpdateInterval * (doubleMulti < intMulti ? intMulti-- : intMulti);
  3629.                 _mpUpdateIncCheck = _mpUpdateDecCheck + _mpUpdateInterval;
  3630.             }
  3631.  
  3632.             return true;
  3633.         }
  3634.  
  3635.         return false;
  3636.     }
  3637.  
  3638.     /**
  3639.      * Send packet StatusUpdate with current HP,MP and CP to the L2PcInstance and only current HP, MP and Level to all other L2PcInstance of the Party.<BR><BR>
  3640.      *
  3641.      * <B><U> Actions</U> :</B><BR><BR>
  3642.      * <li>Send the Server->Client packet StatusUpdate with current HP, MP and CP to this L2PcInstance </li><BR>
  3643.      * <li>Send the Server->Client packet PartySmallWindowUpdate with current HP, MP and Level to all other L2PcInstance of the Party </li><BR><BR>
  3644.      *
  3645.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T SEND current HP and MP to all L2PcInstance of the _statusListener</B></FONT><BR><BR>
  3646.      *
  3647.      */
  3648.     public void broadcastStatusUpdate()
  3649.     {
  3650.         //TODO We mustn't send these informations to other players
  3651.         // Send the Server->Client packet StatusUpdate with current HP and MP to all L2PcInstance that must be informed of HP/MP updates of this L2PcInstance
  3652.  
  3653.  
  3654.         // Send the Server->Client packet StatusUpdate with current HP, MP and CP to this L2PcInstance
  3655.         StatusUpdate su = new StatusUpdate(getObjectId());
  3656.         su.addAttribute(StatusUpdate.CUR_HP, (int) getCurrentHp());
  3657.         su.addAttribute(StatusUpdate.CUR_MP, (int) getCurrentMp());
  3658.         su.addAttribute(StatusUpdate.CUR_CP, (int) getCurrentCp());
  3659.  
  3660.         sendPacket(su);
  3661.  
  3662.  
  3663.         // Check if a party is in progress and party window update is usefull
  3664.         if (isInParty() && (needCpUpdate(352) || super.needHpUpdate(352) || needMpUpdate(352)))
  3665.         {
  3666.  
  3667.             if (Config.DEBUG)
  3668.  
  3669.                 _log.fine("Send status for party window of " + getObjectId() + "(" + getName() + ") to his party. CP: " + getCurrentCp() + " HP: " + getCurrentHp() + " MP: " + getCurrentMp());
  3670.             // Send the Server->Client packet PartySmallWindowUpdate with current HP, MP and Level to all other L2PcInstance of the Party
  3671.             PartySmallWindowUpdate update = new PartySmallWindowUpdate(this);
  3672.             getParty().broadcastToPartyMembers(this, update);
  3673.         }
  3674.  
  3675.  
  3676.         if (isInOlympiadMode() && isOlympiadStart() && (needCpUpdate(352) || super.needHpUpdate(352)))
  3677.             Olympiad.sendUserInfo(this);
  3678.     }
  3679.  
  3680.     public final void updateEffectIcons(boolean partyOnly)
  3681.     {
  3682.  
  3683.         // Create the main packet if needed
  3684.         MagicEffectIcons mi = null;
  3685.  
  3686.         if (!partyOnly)
  3687.             mi = new MagicEffectIcons();
  3688.  
  3689.  
  3690.         // Create the party packet if needed
  3691.         PartySpelled ps = null;
  3692.  
  3693.         if (isInParty())
  3694.             ps = new PartySpelled(this);
  3695.        
  3696.         // Create the olympiad spectator packet if needed
  3697.         ExOlympiadSpelledInfo os = null;
  3698.         if (isInOlympiadMode() && isOlympiadStart())
  3699.             os = new ExOlympiadSpelledInfo(this);
  3700.        
  3701.         if (mi == null && ps ==null && os == null)
  3702.             return; // nothing to do (should not happen)
  3703.  
  3704.         // Go through all effects if any
  3705.         L2Effect[] effects = getAllEffects();
  3706.     if (effects != null && effects.length > 0)
  3707.         {
  3708.             for (L2Effect effect : effects)
  3709.             {
  3710.                 if (effect == null || !effect.getShowIcon())
  3711.                     continue;
  3712.  
  3713.                 if (effect.getInUse())
  3714.                 {
  3715.                     if (mi != null)
  3716.                         effect.addIcon(mi);
  3717.                     if (ps != null)
  3718.                         effect.addPartySpelledIcon(ps);
  3719.                     if (os != null)
  3720.                         effect.addOlympiadSpelledIcon(os);
  3721.                 }
  3722.             }
  3723.  
  3724.         }
  3725.  
  3726.         // Send the packets if needed
  3727.         if (mi != null)
  3728.             sendPacket(mi);
  3729.  
  3730.         if (ps != null)
  3731.  
  3732.             getParty().broadcastToPartyMembers(this, ps);
  3733.  
  3734.  
  3735.         if (os != null)
  3736.         {
  3737.             if (Olympiad.getInstance().getSpectators(getOlympiadGameId()) != null)
  3738.             {
  3739.                 for (L2PcInstance spectator : Olympiad.getInstance().getSpectators(getOlympiadGameId()))
  3740.                 {
  3741.                     if (spectator == null)
  3742.                         continue;
  3743.  
  3744.                     spectator.sendPacket(os);
  3745.                 }
  3746.             }
  3747.         }
  3748.     }
  3749.  
  3750.     /**
  3751.      * Send a Server->Client packet UserInfo to this L2PcInstance and CharInfo to all L2PcInstance in its _KnownPlayers.<BR><BR>
  3752.      *
  3753.      * <B><U> Concept</U> :</B><BR><BR>
  3754.      * Others L2PcInstance in the detection area of the L2PcInstance are identified in <B>_knownPlayers</B>.
  3755.      * In order to inform other players of this L2PcInstance state modifications, server just need to go through _knownPlayers to send Server->Client Packet<BR><BR>
  3756.      *
  3757.      * <B><U> Actions</U> :</B><BR><BR>
  3758.      * <li>Send a Server->Client packet UserInfo to this L2PcInstance (Public and Private Data)</li>
  3759.      * <li>Send a Server->Client packet CharInfo to all L2PcInstance in _KnownPlayers of the L2PcInstance (Public data only)</li><BR><BR>
  3760.      *
  3761.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : DON'T SEND UserInfo packet to other players instead of CharInfo packet.
  3762.      * Indeed, UserInfo packet contains PRIVATE DATA as MaxHP, STR, DEX...</B></FONT><BR><BR>
  3763.      *
  3764.      */
  3765.     public final void broadcastUserInfo()
  3766.     {
  3767.         // Send a Server->Client packet UserInfo to this L2PcInstance
  3768.         sendPacket(new UserInfo(this));
  3769.  
  3770.         // Send a Server->Client packet CharInfo to all L2PcInstance in _KnownPlayers of the L2PcInstance
  3771.         if (Config.DEBUG)
  3772.             _log.fine("players to notify:" + getKnownList().getKnownPlayers().size() + " packet: [S] 03 CharInfo");
  3773.  
  3774.  
  3775.         Broadcast.toKnownPlayers(this, new CharInfo(this));
  3776.     }
  3777.  
  3778.  
  3779.     public final void broadcastTitleInfo()
  3780.     {
  3781.         // Send a Server->Client packet UserInfo to this L2PcInstance
  3782.         sendPacket(new UserInfo(this));
  3783.  
  3784.         // Send a Server->Client packet NicknameChanged to all L2PcInstance in _KnownPlayers of the L2PcInstance
  3785.         if (Config.DEBUG)
  3786.  
  3787.             _log.fine("players to notify:" + getKnownList().getKnownPlayers().size() + " packet: [S] cc NicknameChanged");
  3788.  
  3789.  
  3790.         Broadcast.toKnownPlayers(this, new NicknameChanged(this));
  3791.     }
  3792.  
  3793.     public final void broadcastPacket(ServerBasePacket mov)
  3794.     {
  3795.         if (!(mov instanceof CharInfo))
  3796.  
  3797.             sendPacket(mov);
  3798.  
  3799.  
  3800.         for (L2PcInstance player : getKnownList().getKnownPlayers().values())
  3801.  
  3802.         {
  3803.  
  3804.             player.sendPacket(mov);
  3805.  
  3806.             if (mov instanceof CharInfo)
  3807.  
  3808.             {
  3809.  
  3810.                 int relation = getRelation(player);
  3811.  
  3812.                 if (getKnownList().getKnownRelations().get(player.getObjectId()) != null && getKnownList().getKnownRelations().get(player.getObjectId()) != relation)
  3813.  
  3814.                 {
  3815.                     player.sendPacket(new RelationChanged(this, relation, player.isAutoAttackable(this)));
  3816.                     if (getPet() != null)
  3817.                         player.sendPacket(new RelationChanged(getPet(), relation, player.isAutoAttackable(this)));
  3818.                 }
  3819.  
  3820.             }
  3821.  
  3822.         }
  3823.  
  3824.     }
  3825.  
  3826.     public void broadcastPacket(ServerBasePacket mov, int radiusInKnownlist)
  3827.     {
  3828.         if (!(mov instanceof CharInfo))
  3829.             sendPacket(mov);
  3830.  
  3831.         for (L2PcInstance player : getKnownList().getKnownPlayers().values())
  3832.         {
  3833.             if (isInsideRadius(player, radiusInKnownlist, false, false))
  3834.             {
  3835.                 player.sendPacket(mov);
  3836.                 if (mov instanceof CharInfo)
  3837.                 {
  3838.                     int relation = getRelation(player);
  3839.                     if (getKnownList().getKnownRelations().get(player.getObjectId()) != null && getKnownList().getKnownRelations().get(player.getObjectId()) != relation)
  3840.                     {
  3841.                         player.sendPacket(new RelationChanged(this, relation, player.isAutoAttackable(this)));
  3842.                         if (getPet() != null)
  3843.                             player.sendPacket(new RelationChanged(getPet(), relation, player.isAutoAttackable(this)));
  3844.                     }
  3845.                 }
  3846.             }
  3847.         }
  3848.     }
  3849.  
  3850.     /**
  3851.      * Return the Alliance Identifier of the L2PcInstance.<BR><BR>
  3852.      */
  3853.     public int getAllyId()
  3854.     {
  3855.         if (_clan == null)
  3856.             return 0;
  3857.  
  3858.         else
  3859.             return _clan.getAllyId();
  3860.     }
  3861.  
  3862.     public int getAllyCrestId()
  3863.     {
  3864.         if (getClanId() == 0)
  3865.             return 0;
  3866.  
  3867.  
  3868.  
  3869.         if (getClan().getAllyId() == 0)
  3870.  
  3871.             return 0;
  3872.  
  3873.         return getClan().getAllyCrestId();
  3874.     }
  3875.  
  3876.     /**
  3877.      * Manage hit process (called by Hit Task of L2Character).<BR><BR>
  3878.      *
  3879.      * <B><U> Actions</U> :</B><BR><BR>
  3880.      * <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>
  3881.      * <li>If attack isn't aborted, send a message system (critical hit, missed...) to attacker/target if they are L2PcInstance </li>
  3882.      * <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>
  3883.      * <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><BR>
  3884.      *
  3885.      * @param target The L2Character targeted
  3886.      * @param damage Nb of HP to reduce
  3887.      * @param crit True if hit is critical
  3888.      * @param miss True if hit is missed
  3889.      * @param soulshot True if SoulShot are charged
  3890.      * @param shld True if shield is efficient
  3891.      *
  3892.      */
  3893.     protected void onHitTimer(L2Character target, int damage, boolean crit, boolean miss, boolean soulshot, boolean shld)
  3894.     {
  3895.         super.onHitTimer(target, damage, crit, miss, soulshot, shld);
  3896.     }
  3897.  
  3898.     /**
  3899.      * Send a Server->Client packet StatusUpdate to the L2PcInstance.<BR><BR>
  3900.      */
  3901.     public void sendPacket(ServerBasePacket packet)
  3902.     {
  3903.         if (_isConnected)
  3904.         {
  3905.  
  3906.             try
  3907.             {
  3908.                 if (_connection != null)
  3909.                     _connection.sendPacket(packet);
  3910.             }
  3911.             catch (Exception e)
  3912.             {
  3913.                 _log.log(Level.INFO, "", e);
  3914.             }
  3915.         }
  3916.  
  3917.     }
  3918.  
  3919.     /**
  3920.      * Manage Interact Task with another L2PcInstance.<BR><BR>
  3921.      *
  3922.      * <B><U> Actions</U> :</B><BR><BR>
  3923.      * <li>If the private store is a STORE_PRIVATE_SELL, send a Server->Client PrivateBuyListSell packet to the L2PcInstance</li>
  3924.      * <li>If the private store is a STORE_PRIVATE_BUY, send a Server->Client PrivateBuyListBuy packet to the L2PcInstance</li>
  3925.      * <li>If the private store is a STORE_PRIVATE_MANUFACTURE, send a Server->Client RecipeShopSellList packet to the L2PcInstance</li><BR><BR>
  3926.      *
  3927.      * @param target The L2Character targeted
  3928.      *
  3929.      */
  3930.     public void doInteract(L2Character target)
  3931.     {
  3932.         if (target instanceof L2PcInstance)
  3933.         {
  3934.             L2PcInstance temp = (L2PcInstance) target;
  3935.             sendPacket(new ActionFailed());
  3936.  
  3937.             if (temp.getPrivateStoreType() == STORE_PRIVATE_SELL || temp.getPrivateStoreType() == STORE_PRIVATE_PACKAGE_SELL)
  3938.                 sendPacket(new PrivateStoreListSell(this, temp));
  3939.             else if (temp.getPrivateStoreType() == STORE_PRIVATE_BUY)
  3940.                 sendPacket(new PrivateStoreListBuy(this, temp));
  3941.             else if (temp.getPrivateStoreType() == STORE_PRIVATE_MANUFACTURE)
  3942.                 sendPacket(new RecipeShopSellList(this, temp));
  3943.  
  3944.         }
  3945.         else
  3946.         {
  3947.             // _interactTarget=null should never happen but one never knows ^^;
  3948.             if (target != null)
  3949.                 target.onAction(this);
  3950.         }
  3951.     }
  3952.  
  3953.     /**
  3954.      * Manage AutoLoot Task.<BR><BR>
  3955.      *
  3956.      * <B><U> Actions</U> :</B><BR><BR>
  3957.      * <li>Send a System Message to the L2PcInstance : YOU_PICKED_UP_S1_ADENA or YOU_PICKED_UP_S1_S2</li>
  3958.      * <li>Add the Item to the L2PcInstance inventory</li>
  3959.      * <li>Send a Server->Client packet InventoryUpdate to this L2PcInstance with NewItem (use a new slot) or ModifiedItem (increase amount)</li>
  3960.      * <li>Send a Server->Client packet StatusUpdate to this L2PcInstance with current weight</li><BR><BR>
  3961.      *
  3962.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : If a Party is in progress, distribute Items between party members</B></FONT><BR><BR>
  3963.      *
  3964.      * @param target The L2ItemInstance dropped
  3965.      *
  3966.      */
  3967.     public void doAutoLoot(L2Attackable target, L2Attackable.RewardItem item)
  3968.     {
  3969.         if (isInParty())
  3970.             getParty().distributeItem(this, item, false, target);
  3971.         else if (item.getItemId() == 57)
  3972.             addAdena("Loot", item.getCount(), target, true);
  3973.         else
  3974.             addItem("Loot", item.getItemId(), item.getCount(), target, true);
  3975.     }
  3976.  
  3977.     /**
  3978.      * Manage Pickup Task.<BR><BR>
  3979.      *
  3980.      * <B><U> Actions</U> :</B><BR><BR>
  3981.      * <li>Send a Server->Client packet StopMove to this L2PcInstance </li>
  3982.      * <li>Remove the L2ItemInstance from the world and send server->client GetItem packets </li>
  3983.      * <li>Send a System Message to the L2PcInstance : YOU_PICKED_UP_S1_ADENA or YOU_PICKED_UP_S1_S2</li>
  3984.      * <li>Add the Item to the L2PcInstance inventory</li>
  3985.      * <li>Send a Server->Client packet InventoryUpdate to this L2PcInstance with NewItem (use a new slot) or ModifiedItem (increase amount)</li>
  3986.      * <li>Send a Server->Client packet StatusUpdate to this L2PcInstance with current weight</li><BR><BR>
  3987.      *
  3988.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : If a Party is in progress, distribute Items between party members</B></FONT><BR><BR>
  3989.      *
  3990.      * @param object The L2ItemInstance to pick up
  3991.      *
  3992.      */
  3993.     protected void doPickupItem(L2Object object)
  3994.     {
  3995.         if (isAlikeDead() || isFakeDeath())
  3996.             return;
  3997.  
  3998.         // Set the AI Intention to AI_INTENTION_IDLE
  3999.         getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  4000.  
  4001.         // Check if the L2Object to pick up is a L2ItemInstance
  4002.         if (!(object instanceof L2ItemInstance))
  4003.         {
  4004.             // dont try to pickup anything that is not an item :)
  4005.             _log.warning("trying to pickup wrong target."+getTarget());
  4006.             return;
  4007.         }
  4008.  
  4009.         L2ItemInstance target = (L2ItemInstance) object;
  4010.  
  4011.  
  4012.         // Send a Server->Client packet ActionFailed to this L2PcInstance
  4013.         sendPacket(new ActionFailed());
  4014.  
  4015.         // Send a Server->Client packet StopMove to this L2PcInstance
  4016.         StopMove sm = new StopMove(getObjectId(), getX(), getY(), getZ(), getHeading());
  4017.         if (Config.DEBUG)
  4018.             _log.fine("pickup pos: "+ target.getX() + " "+target.getY()+ " "+target.getZ() );
  4019.  
  4020.         sendPacket(sm);
  4021.  
  4022.         synchronized (target)
  4023.         {
  4024.             // Check if the target to pick up is visible
  4025.             if (!target.isVisible())
  4026.             {
  4027.                 // Send a Server->Client packet ActionFailed to this L2PcInstance
  4028.                 sendPacket(new ActionFailed());
  4029.                 return;
  4030.             }
  4031.  
  4032.             if (!target.getDropProtection().tryPickUp(this))
  4033.             {
  4034.                 sendPacket(new ActionFailed());
  4035.                 SystemMessage smsg = new SystemMessage(SystemMessage.FAILED_TO_PICKUP_S1);
  4036.                 smsg.addItemName(target.getItemId());
  4037.                 sendPacket(smsg);
  4038.                 return;
  4039.             }
  4040.  
  4041.             if (((isInParty() && getParty().getLootDistribution() == L2Party.ITEM_LOOTER) || !isInParty()) && !_inventory.validateCapacity(target))
  4042.             {
  4043.                 sendPacket(new ActionFailed());
  4044.                 sendPacket(new SystemMessage(SystemMessage.SLOTS_FULL));
  4045.                 return;
  4046.             }
  4047.  
  4048.  
  4049.             if (target.getOwnerId() != 0 && target.getOwnerId() != getObjectId() && !isInLooterParty(target.getOwnerId()))
  4050.  
  4051.             {
  4052.  
  4053.                 sendPacket(new ActionFailed());
  4054.  
  4055.  
  4056.  
  4057.                 if (target.getItemId() == 57)
  4058.  
  4059.                 {
  4060.  
  4061.                     SystemMessage smsg = new SystemMessage(SystemMessage.FAILED_TO_PICKUP_S1_ADENA);
  4062.  
  4063.                     smsg.addNumber(target.getCount());
  4064.  
  4065.                     sendPacket(smsg);
  4066.  
  4067.                 }
  4068.  
  4069.                 else if (target.getCount() > 1)
  4070.  
  4071.                 {
  4072.  
  4073.                     SystemMessage smsg = new SystemMessage(SystemMessage.FAILED_TO_PICKUP_S2_S1_s);
  4074.  
  4075.                     smsg.addItemName(target.getItemId());
  4076.  
  4077.                     smsg.addNumber(target.getCount());
  4078.  
  4079.                     sendPacket(smsg);
  4080.  
  4081.                 }
  4082.  
  4083.                 else
  4084.  
  4085.                 {
  4086.  
  4087.                     SystemMessage smsg = new SystemMessage(SystemMessage.FAILED_TO_PICKUP_S1);
  4088.  
  4089.                     smsg.addItemName(target.getItemId());
  4090.  
  4091.                     sendPacket(smsg);
  4092.  
  4093.                 }
  4094.  
  4095.                 return;
  4096.             }
  4097.  
  4098.  
  4099.  
  4100.             if (target.getItemLootSchedule() != null && (target.getOwnerId() == getObjectId()
  4101.  || isInLooterParty(target.getOwnerId())))
  4102.  
  4103.                 target.resetOwnerTimer();
  4104.  
  4105.  
  4106.             // Remove the L2ItemInstance from the world and send server->client GetItem packets
  4107.             target.pickupMe(this);
  4108.  
  4109.             if (Config.SAVE_DROPPED_ITEM) // item must be removed from ItemsOnGroundManager if is active
  4110.  
  4111.                 ItemsOnGroundManager.getInstance().removeObject(target);
  4112.         }
  4113.  
  4114.         // if item is instance of L2ArmorType or L2WeaponType broadcast an "Attention" system message
  4115.         if (target.getItemType() instanceof L2ArmorType || target.getItemType() instanceof L2WeaponType)
  4116.         {
  4117.             if (target.getEnchantLevel() > 0)
  4118.             {
  4119.                 SystemMessage msg = new SystemMessage(SystemMessage.ATTENTION_S1_PICKED_UP_S2_S3);
  4120.                 msg.addString(getName());
  4121.                 msg.addNumber(target.getEnchantLevel());
  4122.                 msg.addItemName(target.getItemId());
  4123.                 broadcastPacket(msg, 1400);
  4124.             }
  4125.             else
  4126.             {
  4127.                 SystemMessage msg = new SystemMessage(SystemMessage.ATTENTION_S1_PICKED_UP_S2);
  4128.                 msg.addString(getName());
  4129.                 msg.addItemName(target.getItemId());
  4130.                 broadcastPacket(msg, 1400);
  4131.             }
  4132.         }
  4133.  
  4134.         // Check if a Party is in progress
  4135.         if (isInParty())
  4136.             getParty().distributeItem(this, target);
  4137.         // Target is adena
  4138.         else if (target.getItemId() == 57 && getInventory().getAdenaInstance() != null)
  4139.         {
  4140.             addAdena("Pickup", target.getCount(), null, true);
  4141.             ItemTable.getInstance().destroyItem("Pickup", target, this, null);
  4142.         }
  4143.         // Target is regular item
  4144.         else
  4145.             addItem("Pickup", target, null, true);
  4146.     }
  4147.  
  4148.     /**
  4149.      * Set a target.<BR><BR>
  4150.      *
  4151.      * <B><U> Actions</U> :</B><BR><BR>
  4152.      * <li>Remove the L2PcInstance from the _statusListener of the old target if it was a L2Character </li>
  4153.      * <li>Add the L2PcInstance to the _statusListener of the new target if it's a L2Character </li>
  4154.      * <li>Target the new L2Object (add the target to the L2PcInstance _target, _knownObject and L2PcInstance to _KnownObject of the L2Object)</li><BR><BR>
  4155.      *
  4156.      * @param newTarget The L2Object to target
  4157.      *
  4158.      */
  4159.     public void setTarget(L2Object newTarget)
  4160.     {
  4161.         // Check if the new target is visible
  4162.         if (newTarget != null && !newTarget.isVisible())
  4163.             newTarget = null;
  4164.  
  4165.  
  4166.         // Prevents /target exploiting
  4167.         if (newTarget != null && Math.abs(newTarget.getZ() - getZ()) > 1000)
  4168.             newTarget = null;
  4169.  
  4170.         if (!isGM())
  4171.         {
  4172.             // Can't target and attack festival monsters if not participant
  4173.             if (newTarget != null && newTarget instanceof L2FestivalMonsterInstance && !isFestivalParticipant())
  4174.                 newTarget = null;
  4175.  
  4176.             // Can't target and attack rift invaders if not in the same room
  4177.             if (isInParty() && getParty().isInDimensionalRift())
  4178.             {
  4179.                 byte riftType = getParty().getDimensionalRift().getType();
  4180.                 byte riftRoom = getParty().getDimensionalRift().getCurrentRoom();
  4181.                 if (newTarget != null && !DimensionalRiftManager.getInstance().getRoom(riftType, riftRoom).checkIfInZone(newTarget.getX(), newTarget.getY(), newTarget.getZ()))
  4182.                     newTarget = null;
  4183.             }
  4184.         }
  4185.  
  4186.         // Get the current target
  4187.         L2Object oldTarget = getTarget();
  4188.  
  4189.         if (oldTarget != null)
  4190.         {
  4191.             if (newTarget != null && oldTarget.equals(newTarget))
  4192.                 return; // no target change
  4193.  
  4194.             // Remove the L2PcInstance from the _statusListener of the old target if it was a L2Character
  4195.             if (oldTarget instanceof L2Character)
  4196.                 ((L2Character) oldTarget).removeStatusListener(this);
  4197.         }
  4198.  
  4199.         // Add the L2PcInstance to the _statusListener of the new target if it's a L2Character
  4200.         if (newTarget != null && newTarget instanceof L2Character)
  4201.         {
  4202.             ((L2Character) newTarget).addStatusListener(this);
  4203.             TargetSelected my = new TargetSelected(getObjectId(), newTarget.getObjectId(), getX(), getY(), getZ());
  4204.             broadcastPacket(my);
  4205.         }
  4206.  
  4207.         if (newTarget == null && getTarget() != null)
  4208.  
  4209.             broadcastPacket(new TargetUnselected(this));
  4210.  
  4211.         // Target the new L2Object (add the target to the L2PcInstance _target, _knownObject and L2PcInstance to _KnownObject of the L2Object)
  4212.         super.setTarget(newTarget);
  4213.     }
  4214.  
  4215.     /**
  4216.      * Return the active weapon instance (always equiped in the right hand).<BR><BR>
  4217.      */
  4218.     public L2ItemInstance getActiveWeaponInstance()
  4219.     {
  4220.         return getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
  4221.     }
  4222.  
  4223.     /**
  4224.      * Return the active weapon item (always equiped in the right hand).<BR><BR>
  4225.      */
  4226.     public L2Weapon getActiveWeaponItem()
  4227.     {
  4228.         L2ItemInstance weapon = getActiveWeaponInstance();
  4229.         if (weapon == null)
  4230.             return getFistsWeaponItem();
  4231.  
  4232.         return (L2Weapon) weapon.getItem();
  4233.     }
  4234.  
  4235.     public L2ItemInstance getChestArmorInstance()
  4236.     {
  4237.         return getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST);
  4238.     }
  4239.  
  4240.     public L2Armor getActiveChestArmorItem()
  4241.     {
  4242.         L2ItemInstance armor = getChestArmorInstance();
  4243.         if (armor == null)
  4244.             return null;
  4245.  
  4246.         return (L2Armor) armor.getItem();
  4247.     }
  4248.  
  4249.     public boolean isWearingHeavyArmor()
  4250.     {
  4251.         L2ItemInstance armor = getChestArmorInstance();
  4252.  
  4253.         if ((L2ArmorType)armor.getItemType() == L2ArmorType.HEAVY)
  4254.             return true;
  4255.  
  4256.  
  4257.         return false;
  4258.     }
  4259.  
  4260.     public boolean isWearingLightArmor()
  4261.     {
  4262.         L2ItemInstance armor = getChestArmorInstance();
  4263.  
  4264.         if ((L2ArmorType)armor.getItemType() == L2ArmorType.LIGHT)
  4265.             return true;
  4266.  
  4267.  
  4268.         return false;
  4269.     }
  4270.  
  4271.     public boolean isWearingMagicArmor()
  4272.     {
  4273.         L2ItemInstance armor = getChestArmorInstance();
  4274.  
  4275.         if ((L2ArmorType)armor.getItemType() == L2ArmorType.MAGIC)
  4276.             return true;
  4277.  
  4278.  
  4279.         return false;
  4280.     }
  4281.  
  4282.     public boolean isWearingFormalWear()
  4283.     {
  4284.         return _IsWearingFormalWear;
  4285.     }
  4286.  
  4287.     public void setIsWearingFormalWear(boolean value)
  4288.     {
  4289.  
  4290.         _IsWearingFormalWear = value;
  4291.     }
  4292.  
  4293.     /**
  4294.      * Return the secondary weapon instance (always equiped in the left hand).<BR><BR>
  4295.      */
  4296.     public L2ItemInstance getSecondaryWeaponInstance()
  4297.     {
  4298.         return getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
  4299.     }
  4300.  
  4301.     /**
  4302.      * Return the secondary weapon item (always equiped in the left hand) or the fists weapon.<BR><BR>
  4303.      */
  4304.     public L2Weapon getSecondaryWeaponItem()
  4305.     {
  4306.         L2ItemInstance weapon = getSecondaryWeaponInstance();
  4307.         if (weapon == null)
  4308.             return getFistsWeaponItem();
  4309.  
  4310.         L2Item item = weapon.getItem();
  4311.         if (item instanceof L2Weapon)
  4312.             return (L2Weapon)item;
  4313.  
  4314.         return null;
  4315.     }
  4316.  
  4317.     /**
  4318.      * Kill the L2Character, Apply Death Penalty, Manage gain/loss Karma and Item Drop.<BR><BR>
  4319.      *
  4320.      * <B><U> Actions</U> :</B><BR><BR>
  4321.      * <li>Reduce the Experience of the L2PcInstance in function of the calculated Death Penalty </li>
  4322.      * <li>If necessary, unsummon the Pet of the killed L2PcInstance </li>
  4323.      * <li>Manage Karma gain for attacker and Karma loss for the killed L2PcInstance </li>
  4324.      * <li>If the killed L2PcInstance has Karma, manage Drop Item</li>
  4325.      * <li>Kill the L2PcInstance </li><BR><BR>
  4326.      *
  4327.      *
  4328.      * @param i The HP decrease value
  4329.      * @param killer - The dead player
  4330.      *
  4331.      */
  4332.     public boolean doDie(L2Character killer)
  4333.     {
  4334.         // Kill the L2PcInstance
  4335.         if (!super.doDie(killer))
  4336.  
  4337.             return false;
  4338.  
  4339.         if (isMounted())
  4340.             stopFeed();
  4341.  
  4342.         if (killer != null)
  4343.         {
  4344.             L2PcInstance pk = null;
  4345.             if (killer instanceof L2PcInstance)
  4346.                 pk = (L2PcInstance) killer;
  4347.             else if (killer instanceof L2Summon)
  4348.                 pk = ((L2Summon)killer).getOwner();
  4349.  
  4350.             if (pk != null)
  4351.             {
  4352.                 if (atEvent)
  4353.                     pk.kills.add(getName());
  4354.  
  4355.                 if (pk.getEventTeam() == 1)
  4356.                     TvTEvent.increaseBlueKills();
  4357.                 else if (pk.getEventTeam() == 2)
  4358.                     TvTEvent.increaseRedKills();
  4359.             }
  4360.  
  4361.  
  4362.             if (getEventTeam() > 0)
  4363.             {
  4364.                 broadcastPacket(new ChangeWaitType(this, ChangeWaitType.WT_START_FAKEDEATH));
  4365.  
  4366.                 sendMessage("You will be respawned in 20 seconds.");
  4367.                 ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
  4368.                 {
  4369.                     @Override
  4370.                 public void run()
  4371.                     {
  4372.                         if (!isDead() || isPendingRevive())
  4373.                             return;
  4374.  
  4375.                         setIsPendingRevive(true);
  4376.  
  4377.                         if (getEventTeam() == 1)
  4378.                             teleToLocation(148476, 46061, -3411, true);
  4379.                         else if (getEventTeam() == 2)
  4380.                             teleToLocation(150480, 47444, -3411, true);
  4381.                         else
  4382.                             teleToLocation(MapRegionTable.TeleportWhereType.Town);
  4383.                     }
  4384.                 }, 20000);
  4385.             }
  4386.             else
  4387.             {
  4388.  
  4389.                 // Clear resurrect xp calculation
  4390.  
  4391.                 _expBeforeDeath = 0;
  4392.  
  4393.                 onDieDropItem(killer);  // Check if any item should be dropped
  4394.  
  4395.                 if (!(isInsideZone(ZONE_PVP) && !isInsideZone(ZONE_SIEGE)))
  4396.                 {
  4397.                     if (Config.ALT_GAME_DELEVEL)
  4398.                     {
  4399.                         // Reduce the Experience of the L2PcInstance in function of the calculated Death Penalty
  4400.                         // NOTE: deathPenalty +- Exp will update karma
  4401.                         if (getSkillLevel(L2Skill.SKILL_LUCKY) < 0 || getStat().getLevel() > 4)
  4402.                             deathPenalty((killer instanceof L2PcInstance && this.getClan() != null && ((L2PcInstance)killer).getClan() != null && ((L2PcInstance)killer).getClan().isAtWarWith(this.getClanId())));
  4403.                     }
  4404.                     else
  4405.                         onDieUpdateKarma(); // Update karma if delevel is not allowed
  4406.                 }
  4407.             }
  4408.         }
  4409.  
  4410.         _charges = 0;
  4411.  
  4412.         setPvpFlag(0); // Clear the pvp flag
  4413.  
  4414.         // Unsummon Cubics
  4415.         if (_cubics.size() > 0)
  4416.  
  4417.         {
  4418.             for (L2CubicInstance cubic : _cubics.values())
  4419.             {
  4420.                 cubic.stopAction();
  4421.                 cubic.cancelDisappear();
  4422.             }
  4423.  
  4424.  
  4425.             _cubics.clear();
  4426.         }
  4427.  
  4428.         if (isInParty() && getParty().isInDimensionalRift())
  4429.             getParty().getDimensionalRift().memberDead(this);
  4430.  
  4431.         stopRentPet();
  4432.         stopWaterTask();
  4433.  
  4434.         return true;
  4435.     }
  4436.  
  4437.     private void onDieDropItem(L2Character killer)
  4438.     {
  4439.         if (atEvent || killer == null)
  4440.  
  4441.             return;
  4442.  
  4443.  
  4444.         if (getKarma() <= 0 && killer instanceof L2PcInstance
  4445.  
  4446.      && ((L2PcInstance)killer).getClan()!=null && getClan()!=null
  4447.  
  4448.      && (((L2PcInstance)killer).getClan().isAtWarWith(getClanId())))
  4449.             return;
  4450.  
  4451.         if (!isInsideZone(ZONE_PVP) && (!isGM() || Config.KARMA_DROP_GM))
  4452.         {
  4453.             boolean isKarmaDrop = false;
  4454.             boolean isKillerNpc = (killer instanceof L2NpcInstance);
  4455.             boolean hasLuckyCharm = getCharmOfLuck() && (killer instanceof L2RaidBossInstance || killer instanceof L2GrandBossInstance);
  4456.  
  4457.             int pkLimit = Config.KARMA_PK_LIMIT;
  4458.             int dropEquip = 0;
  4459.             int dropEquipWeapon = 0;
  4460.             int dropItem = 0;
  4461.             int dropLimit = 0;
  4462.             int dropPercent = 0;
  4463.  
  4464.             if (getKarma() > 0 && getPkKills() >= pkLimit)
  4465.             {
  4466.                 isKarmaDrop = true;
  4467.                 dropPercent = Config.KARMA_RATE_DROP;
  4468.                 dropEquip = Config.KARMA_RATE_DROP_EQUIP;
  4469.                 dropEquipWeapon = Config.KARMA_RATE_DROP_EQUIP_WEAPON;
  4470.                 dropItem = Config.KARMA_RATE_DROP_ITEM;
  4471.                 dropLimit = Config.KARMA_DROP_LIMIT;
  4472.             }
  4473.             else if (isKillerNpc && getLevel() > 4 && !hasLuckyCharm && !isFestivalParticipant())
  4474.             {
  4475.                 dropPercent = Config.PLAYER_RATE_DROP;
  4476.                 dropEquip = Config.PLAYER_RATE_DROP_EQUIP;
  4477.                 dropEquipWeapon = Config.PLAYER_RATE_DROP_EQUIP_WEAPON;
  4478.                 dropItem = Config.PLAYER_RATE_DROP_ITEM;
  4479.                 dropLimit = Config.PLAYER_DROP_LIMIT;
  4480.             }
  4481.  
  4482.             int dropCount = 0;
  4483.             while (dropPercent > 0 && Rnd.get(100) < dropPercent && dropCount < dropLimit)
  4484.             {
  4485.  
  4486.                 int itemDropPercent = 0;
  4487.                 List<Integer> nonDroppableList = new FastList<>();
  4488.                 List<Integer> nonDroppableListPet = new FastList<>();
  4489.  
  4490.                 nonDroppableList = Config.KARMA_LIST_NONDROPPABLE_ITEMS;
  4491.                 nonDroppableListPet = Config.KARMA_LIST_NONDROPPABLE_PET_ITEMS;
  4492.  
  4493.                 for (L2ItemInstance itemDrop : getInventory().getItems())
  4494.                 {
  4495.                     if (itemDrop == null)
  4496.                         continue;
  4497.  
  4498.                     // Don't drop
  4499.                     if (!itemDrop.isDropable() ||
  4500.                            itemDrop.getItemId() == 57 ||                                           // Adena
  4501.                            itemDrop.getItem().getType2() == L2Item.TYPE2_QUEST ||                  // Quest Items
  4502.                            nonDroppableList.contains(itemDrop.getItemId()) ||                      // Item listed in the non droppable item list
  4503.                            nonDroppableListPet.contains(itemDrop.getItemId()) ||                   // Item listed in the non droppable pet item list
  4504.                            getPet() != null && getPet().getControlItemId() == itemDrop.getItemId()) // Control Item of active pet
  4505.                         continue;
  4506.  
  4507.                     if (itemDrop.isEquipped())
  4508.                     {
  4509.                         // Set proper chance according to Item type of equipped Item
  4510.  
  4511.                         itemDropPercent = itemDrop.getItem().getType2() == L2Item.TYPE2_WEAPON ? dropEquipWeapon : dropEquip;
  4512.                         getInventory().unEquipItemInSlotAndRecord(itemDrop.getEquipSlot());
  4513.                     }
  4514.                     else
  4515.                         itemDropPercent = dropItem; // Item in inventory
  4516.  
  4517.                     // NOTE: Each time an item is dropped, the chance of another item being dropped gets lesser (dropCount * 2)
  4518.                     if (Rnd.get(100) < itemDropPercent)
  4519.                     {
  4520.                         dropItem("DieDrop", itemDrop, killer, true);
  4521.  
  4522.  
  4523.                         if (isKarmaDrop)
  4524.  
  4525.                             _log.warning(getName() + " has karma and dropped id = " + itemDrop.getItemId() + ", count = " + itemDrop.getCount());
  4526.  
  4527.  
  4528.                         else
  4529.  
  4530.                             _log.warning(getName() + " dropped id = " + itemDrop.getItemId() + ", count = " + itemDrop.getCount());
  4531.  
  4532.  
  4533.                         dropCount++;
  4534.                         break;
  4535.                     }
  4536.                 }
  4537.             }
  4538.         }
  4539.     }
  4540.  
  4541.     private void onDieUpdateKarma()
  4542.     {
  4543.         // Karma lose for server that does not allow delevel
  4544.         if (getKarma() > 0)
  4545.         {
  4546.             // this formula seems to work relatively well:
  4547.             // baseKarma * thisLVL * (thisLVL/100)
  4548.             // Calculate the new Karma of the attacker : newKarma = baseKarma*pkCountMulti*lvlDiffMulti
  4549.             double karmaLost = Config.KARMA_LOST_BASE;
  4550.             karmaLost *= getLevel(); // multiply by char lvl
  4551.             karmaLost *= (getLevel() / 100); // divide by 0.charLVL
  4552.             karmaLost = Math.round(karmaLost);
  4553.             if (karmaLost < 0)
  4554.                 karmaLost = 1;
  4555.  
  4556.             // Decrease Karma of the L2PcInstance and Send it a Server->Client StatusUpdate packet with Karma and PvP Flag if necessary
  4557.             setKarma(getKarma() - (int)karmaLost);
  4558.         }
  4559.     }
  4560.  
  4561.     public void onKillUpdatePvPKarma(L2Character target)
  4562.     {
  4563.         if (target == null)
  4564.             return;
  4565.  
  4566.         if (!(target instanceof L2PlayableInstance))
  4567.             return;
  4568.  
  4569.         L2PcInstance targetPlayer = null;
  4570.         if (target instanceof L2PcInstance)
  4571.             targetPlayer = (L2PcInstance)target;
  4572.         else if (target instanceof L2Summon)
  4573.             targetPlayer = ((L2Summon)target).getOwner();
  4574.  
  4575.         if (targetPlayer == null)
  4576.             return;  // Target player is null
  4577.  
  4578.         if (targetPlayer == this)
  4579.             return;  // Target player is self
  4580.  
  4581.  
  4582.         // If in Arena, do nothing
  4583.         if (isInsideZone(ZONE_PVP) || targetPlayer.isInsideZone(ZONE_PVP))
  4584.             return;
  4585.  
  4586.         // Check if it's pvp
  4587.         if ((checkIfPvP(target) &&              //   Can pvp and
  4588.                targetPlayer.getPvpFlag() != 0)  //   Target player has pvp flag set
  4589.                || (isInsideZone(ZONE_PVP) &&            //   or Player is inside pvp zone and
  4590.                targetPlayer.isInsideZone(ZONE_PVP)))    //   Target player is inside pvp zone
  4591.  
  4592.  
  4593.         {
  4594.             if (target instanceof L2PcInstance)
  4595.                 increasePvpKills();
  4596.         }
  4597.  
  4598.         else                                    // Target player doesn't have pvp flag set
  4599.         {
  4600.             // check about wars
  4601.             if (targetPlayer.getClan() != null && this.getClan() != null)
  4602.             {
  4603.                 if (getClan().isAtWarWith(targetPlayer.getClanId()))
  4604.                 {
  4605.                     if (targetPlayer.getClan().isAtWarWith(getClanId()))
  4606.                     {
  4607.                         // 'Both way war' -> 'PvP Kill'
  4608.                         if (target instanceof L2PcInstance)
  4609.                             increasePvpKills();
  4610.                         return;
  4611.                     }
  4612.                 }
  4613.             }
  4614.  
  4615.  
  4616.             // 'No war' or 'One way war' -> 'Normal PK'
  4617.             if (targetPlayer.getKarma() > 0)   // Target player has karma
  4618.             {
  4619.                 if (Config.KARMA_AWARD_PK_KILL)
  4620.                 {
  4621.                     if (target instanceof L2PcInstance)
  4622.  
  4623.                         increasePvpKills();
  4624.                 }
  4625.             }
  4626.             else if (targetPlayer.getPvpFlag() == 0)   // Target player doesn't have karma
  4627.  
  4628.  
  4629.                 increasePkKillsAndKarma(targetPlayer.getLevel(), target instanceof L2PcInstance);
  4630.         }
  4631.  
  4632.     }
  4633.  
  4634.     /**
  4635.      * Increase the pvp kills count and send the info to the player
  4636.      *
  4637.      */
  4638.     public void increasePvpKills()
  4639.     {
  4640.         // Add karma to attacker and increase its PK counter
  4641.         setPvpKills(getPvpKills() + 1);
  4642.  
  4643.  
  4644.         // Send a Server->Client UserInfo packet to attacker with its Karma and PK Counter
  4645.         sendPacket(new UserInfo(this));
  4646.     }
  4647.  
  4648.     /**
  4649.      * Increase pk count, karma and send the info to the player
  4650.      *
  4651.      * @param targLVL : level of the killed player
  4652.      */
  4653.     public void increasePkKillsAndKarma(int targLVL, boolean increasePk)
  4654.     {
  4655.         int baseKarma           = Config.KARMA_MIN_KARMA;
  4656.         int newKarma            = baseKarma;
  4657.         int karmaLimit          = Config.KARMA_MAX_KARMA;
  4658.  
  4659.  
  4660.         int pkLVL               = getLevel();
  4661.         int pkPKCount           = getPkKills();
  4662.  
  4663.  
  4664.         int lvlDiffMulti = 0;
  4665.         int pkCountMulti = 0;
  4666.  
  4667.  
  4668.         // Check if the attacker has a PK counter greater than 0
  4669.         if (pkPKCount > 0)
  4670.             pkCountMulti = pkPKCount / 2;
  4671.         else
  4672.             pkCountMulti = 1;
  4673.  
  4674.         if (pkCountMulti < 1)
  4675.             pkCountMulti = 1;
  4676.  
  4677.  
  4678.         // Calculate the level difference Multiplier between attacker and killed L2PcInstance
  4679.         if (pkLVL > targLVL)
  4680.             lvlDiffMulti = pkLVL / targLVL;
  4681.         else
  4682.             lvlDiffMulti = 1;
  4683.  
  4684.         if (lvlDiffMulti < 1)
  4685.             lvlDiffMulti = 1;
  4686.  
  4687.  
  4688.         // Calculate the new Karma of the attacker : newKarma = baseKarma*pkCountMulti*lvlDiffMulti
  4689.         newKarma *= pkCountMulti;
  4690.         newKarma *= lvlDiffMulti;
  4691.  
  4692.  
  4693.         // Make sure newKarma is less than karmaLimit and higher than baseKarma
  4694.         if (newKarma < baseKarma)
  4695.             newKarma = baseKarma;
  4696.  
  4697.         if (newKarma > karmaLimit)
  4698.             newKarma = karmaLimit;
  4699.  
  4700.  
  4701.         // Fix to prevent overflow (=> karma has a  max value of 2 147 483 647)
  4702.         if (getKarma() > (Integer.MAX_VALUE - newKarma))
  4703.             newKarma = Integer.MAX_VALUE - getKarma();
  4704.  
  4705.  
  4706.         // Add karma to attacker and increase its PK counter
  4707.  
  4708.         setKarma(getKarma() + newKarma);
  4709.         if (increasePk)
  4710.             setPkKills(getPkKills() + 1);
  4711.  
  4712.  
  4713.         // Send a Server->Client UserInfo packet to attacker with its Karma and PK Counter
  4714.         sendPacket(new UserInfo(this));
  4715.     }
  4716.  
  4717.     public int calculateKarmaLost(long exp)
  4718.     {
  4719.         // KARMA LOSS
  4720.         // When a PKer gets killed by another player or a L2MonsterInstance, it loses a certain amount of Karma based on their level.
  4721.         // this (with defaults) results in a level 1 losing about ~2 karma per death, and a lvl 70 loses about 11760 karma per death...
  4722.         // You lose karma as long as you were not in a pvp zone and you did not kill urself.
  4723.         // NOTE: exp for death (if delevel is allowed) is based on the players level
  4724.  
  4725.         long expGained = Math.abs(exp);
  4726.  
  4727.         expGained /= Config.KARMA_XP_DIVIDER;
  4728.  
  4729.         int karmaLost = 0;
  4730.         if (expGained > Integer.MAX_VALUE)
  4731.             karmaLost = Integer.MAX_VALUE;
  4732.         else
  4733.             karmaLost = (int)expGained;
  4734.  
  4735.         if (karmaLost < Config.KARMA_LOST_BASE)
  4736.             karmaLost = Config.KARMA_LOST_BASE;
  4737.  
  4738.         if (karmaLost > getKarma())
  4739.             karmaLost = getKarma();
  4740.  
  4741.         return karmaLost;
  4742.     }
  4743.  
  4744.     public void updatePvPStatus()
  4745.     {
  4746.  
  4747.         if (isInsideZone(ZONE_PVP))
  4748.             return;
  4749.  
  4750.  
  4751.         setPvpFlagLasts(System.currentTimeMillis() + Config.PVP_NORMAL_TIME);
  4752.  
  4753.  
  4754.  
  4755.         if (getPvpFlag() == 0)
  4756.  
  4757.             startPvPFlag();
  4758.     }
  4759.  
  4760.     public void updatePvPStatus(L2Character target)
  4761.     {
  4762.         L2PcInstance player_target = null;
  4763.  
  4764.         if (target instanceof L2PcInstance)
  4765.  
  4766.             player_target = (L2PcInstance)target;
  4767.  
  4768.         else if (target instanceof L2Summon)
  4769.  
  4770.             player_target = ((L2Summon) target).getOwner();
  4771.  
  4772.  
  4773.         if (player_target == null)
  4774.  
  4775.             return;
  4776.  
  4777.  
  4778.         if ((!isInsideZone(ZONE_PVP) || !player_target.isInsideZone(ZONE_PVP)) && player_target.getKarma() == 0)
  4779.  
  4780.         {
  4781.  
  4782.             if (checkIfPvP(player_target))
  4783.  
  4784.                 setPvpFlagLasts(System.currentTimeMillis() + Config.PVP_PVP_TIME);
  4785.  
  4786.             else
  4787.  
  4788.                 setPvpFlagLasts(System.currentTimeMillis() + Config.PVP_NORMAL_TIME);
  4789.  
  4790.  
  4791.             if (getPvpFlag() == 0)
  4792.  
  4793.                 startPvPFlag();
  4794.  
  4795.         }
  4796.  
  4797.     }
  4798.  
  4799.     /**
  4800.      * Restore the specified % of experience this L2PcInstance has
  4801.      * lost and sends a Server->Client StatusUpdate packet.<BR><BR>
  4802.      */
  4803.     public void restoreExp(double restorePercent)
  4804.     {
  4805.         if (_expBeforeDeath > 0)
  4806.         {  
  4807.             // Restore the specified % of lost experience.
  4808.             getStat().addExp(Math.round((_expBeforeDeath - getExp()) * restorePercent / 100));
  4809.             _expBeforeDeath = 0;
  4810.         }
  4811.     }
  4812.  
  4813.     /**
  4814.      * Reduce the Experience (and level if necessary) of the L2PcInstance in function of the calculated Death Penalty.<BR><BR>
  4815.      *
  4816.      * <B><U> Actions</U> :</B><BR><BR>
  4817.      * <li>Calculate the Experience loss </li>
  4818.      * <li>Set the value of _expBeforeDeath </li>
  4819.      * <li>Set the new Experience value of the L2PcInstance and Decrease its level if necessary </li>
  4820.      * <li>Send a Server->Client StatusUpdate packet with its new Experience </li><BR><BR>
  4821.      *
  4822.      */
  4823.     public void deathPenalty(boolean atwar)
  4824.     {
  4825.         // TODO Need Correct Penalty
  4826.         // Get the level of the L2PcInstance
  4827.         final int lvl = getLevel();
  4828.  
  4829.         // The death steal you some Exp
  4830.         double percentLost = -0.07 * lvl + 6.5;
  4831.  
  4832.  
  4833.         if (getKarma() > 0)
  4834.  
  4835.             percentLost *= Config.RATE_KARMA_EXP_LOST;
  4836.  
  4837.  
  4838.         if (isFestivalParticipant() || atwar || isInsideZone(ZONE_SIEGE))
  4839.  
  4840.             percentLost /= 4.0;
  4841.  
  4842.         // Calculate the Experience loss
  4843.         long lostExp = 0;
  4844.         if (!atEvent)
  4845.         {
  4846.             if (lvl < Experience.MAX_LEVEL)
  4847.                 lostExp = Math.round((getStat().getExpForLevel(lvl+1) - getStat().getExpForLevel(lvl)) * percentLost /100);
  4848.             else
  4849.                 lostExp = Math.round((getStat().getExpForLevel(Experience.MAX_LEVEL) - getStat().getExpForLevel(Experience.MAX_LEVEL - 1)) * percentLost /100);
  4850.         }
  4851.  
  4852.         // Get the Experience before applying penalty
  4853.         _expBeforeDeath = getExp();
  4854.  
  4855.         if (Config.DEBUG)
  4856.             _log.fine(getName() + " died and lost " + lostExp + " experience.");
  4857.  
  4858.         // Set the new Experience value of the L2PcInstance
  4859.         getStat().addExp(-lostExp);
  4860.     }
  4861.  
  4862.     public void setPartyRoom(int id)
  4863.     {
  4864.         _partyroom = id;
  4865.     }
  4866.  
  4867.     public int getPartyRoom()
  4868.     {
  4869.         return _partyroom;
  4870.     }
  4871.  
  4872.     public boolean isInPartyMatchRoom()
  4873.     {
  4874.         return _partyroom > 0;
  4875.     }
  4876.  
  4877.     public boolean isLookingForParty()
  4878.     {
  4879.         if (_partyroom > 0 && _party != null)
  4880.             return true;
  4881.  
  4882.         PartyMatchRoom room = PartyMatchRoomList.getInstance().getRoom(_partyroom);
  4883.         if (room != null)
  4884.         {
  4885.             if (room.getOwner() == this)
  4886.                 return true;
  4887.         }
  4888.  
  4889.         return false;
  4890.     }
  4891.  
  4892.     /**
  4893.      * Manage the increase level task of a L2PcInstance (Max MP, Max MP, recommendation, Expertise and beginner skills...).<BR><BR>
  4894.      *
  4895.      * <B><U> Actions</U> :</B><BR><BR>
  4896.      * <li>Send a Server->Client System Message to the L2PcInstance : YOU_INCREASED_YOUR_LEVEL </li>
  4897.      * <li>Send a Server->Client packet StatusUpdate to the L2PcInstance with new LEVEL, MAX_HP and MAX_MP </li>
  4898.      * <li>Set the current HP and MP of the L2PcInstance, Launch/Stop a HP/MP/CP Regeneration Task and send StatusUpdate packet to all other L2PcInstance to inform (exclusive broadcast)</li>
  4899.      * <li>Recalculate the party level</li>
  4900.      * <li>Recalculate the number of recommendation that the L2PcInstance can give</li>
  4901.      * <li>Give Expertise skill of this level and remove beginner Lucky skill</li><BR><BR>
  4902.      *
  4903.      */
  4904.     public void increaseLevel()
  4905.     {
  4906.         // Set the current HP and MP of the L2Character, Launch/Stop a HP/MP/CP Regeneration Task and send StatusUpdate packet to all other L2PcInstance to inform (exclusive broadcast)
  4907.         setCurrentHpMp(getMaxHp(),getMaxMp());
  4908.         setCurrentCp(getMaxCp());
  4909.     }
  4910.  
  4911.     /**
  4912.      * Stop the HP/MP/CP Regeneration task.<BR><BR>
  4913.      *
  4914.      * <B><U> Actions</U> :</B><BR><BR>
  4915.      * <li>Set the RegenActive flag to False </li>
  4916.      * <li>Stop the HP/MP/CP Regeneration task </li><BR><BR>
  4917.      *
  4918.      */
  4919.     public void stopAllTimers()
  4920.     {
  4921.         stopHpMpRegeneration();
  4922.         stopWarnUserTakeBreak();
  4923.         stopWaterTask();
  4924.         stopFeed();
  4925.         clearPetData();
  4926.         storePetFood(_mountNpcId);
  4927.         stopRentPet();
  4928.  
  4929.         stopJailTask(true);
  4930.     }
  4931.  
  4932.     /**
  4933.      * Return the L2Summon of the L2PcInstance or null.<BR><BR>
  4934.      */
  4935.     public L2Summon getPet()
  4936.     {
  4937.         return _summon;
  4938.     }
  4939.  
  4940.     /**
  4941.      * Set the L2Summon of the L2PcInstance.<BR><BR>
  4942.      */
  4943.     public void setPet(L2Summon summon)
  4944.     {
  4945.         _summon = summon;
  4946.     }
  4947.  
  4948.     public L2TamedBeastInstance getTrainedBeast()
  4949.     {
  4950.         return _tamedBeast;
  4951.     }
  4952.  
  4953.     public void setTrainedBeast(L2TamedBeastInstance tamedBeast)
  4954.     {
  4955.         _tamedBeast = tamedBeast;
  4956.     }
  4957.  
  4958.  
  4959.     /**
  4960.  
  4961.      * Return the L2PcInstance requester of a transaction (ex : FriendInvite, JoinAlly, JoinParty...).<BR><BR>
  4962.      */
  4963.     public L2Request getRequest()
  4964.     {
  4965.         return _request;
  4966.     }
  4967.  
  4968.     /**
  4969.      * Set the L2PcInstance requester of a transaction (ex : FriendInvite, JoinAlly, JoinParty...).<BR><BR>
  4970.      */
  4971.     public synchronized void setActiveRequester(L2PcInstance requester)
  4972.     {
  4973.         _activeRequester = requester;
  4974.     }
  4975.  
  4976.     /**
  4977.      * Return the L2PcInstance requester of a transaction (ex : FriendInvite, JoinAlly, JoinParty...).<BR><BR>
  4978.      */
  4979.     public L2PcInstance getActiveRequester()
  4980.     {
  4981.         if (_activeRequester != null)
  4982.         {
  4983.             if (_activeRequester.isOnline() == 0 || _activeRequester.isRequestExpired())
  4984.             {
  4985.                 _activeRequester.setLootInvitation(-1);
  4986.                 _activeRequester = null;
  4987.             }
  4988.         }
  4989.         return _activeRequester;
  4990.     }
  4991.  
  4992.     /**
  4993.      * Return True if a transaction is in progress.<BR><BR>
  4994.      */
  4995.     public boolean isProcessingRequest()
  4996.     {
  4997.         return getActiveRequester() != null || _requestExpireTime > GameTimeController.getGameTicks();
  4998.     }
  4999.  
  5000.     /**
  5001.      * Return True if a transaction is in progress.<BR><BR>
  5002.      */
  5003.     public boolean isProcessingTransaction()
  5004.     {
  5005.  
  5006.         return getActiveRequester() != null || _activeTradeList != null || _requestExpireTime > GameTimeController.getGameTicks();
  5007.  
  5008.     }
  5009.  
  5010.     public void onTransactionRequest(L2PcInstance partner)
  5011.     {
  5012.         _requestExpireTime = GameTimeController.getGameTicks() + REQUEST_TIMEOUT * GameTimeController.TICKS_PER_SECOND;
  5013.         partner.setActiveRequester(this);
  5014.     }
  5015.  
  5016.     public boolean isRequestExpired()
  5017.     {
  5018.         return !(_requestExpireTime > GameTimeController.getGameTicks());
  5019.     }
  5020.  
  5021.     public void onTransactionResponse()
  5022.  
  5023.     {
  5024.  
  5025.         _requestExpireTime = 0;
  5026.  
  5027.     }
  5028.  
  5029.     /**
  5030.      * Select the Warehouse to be used in next activity.<BR><BR>
  5031.      */
  5032.     public void setActiveWarehouse(ItemContainer warehouse)
  5033.  
  5034.     {
  5035.  
  5036.         _activeWarehouse = warehouse;
  5037.  
  5038.     }
  5039.  
  5040.     /**
  5041.      * Return active Warehouse.<BR><BR>
  5042.      */
  5043.     public ItemContainer getActiveWarehouse()
  5044.  
  5045.     {
  5046.  
  5047.         return _activeWarehouse;
  5048.  
  5049.     }
  5050.  
  5051.     /**
  5052.      * Select the TradeList to be used in next activity.<BR><BR>
  5053.      */
  5054.     public void setActiveTradeList(TradeList tradeList)
  5055.  
  5056.     {
  5057.  
  5058.         _activeTradeList = tradeList;
  5059.  
  5060.     }
  5061.  
  5062.     /**
  5063.      * Return active TradeList.<BR><BR>
  5064.      */
  5065.     public TradeList getActiveTradeList()
  5066.  
  5067.     {
  5068.         return _activeTradeList;
  5069.  
  5070.     }
  5071.  
  5072.     public void onTradeStart(L2PcInstance partner)
  5073.     {
  5074.         _activeTradeList = new TradeList(this);
  5075.         _activeTradeList.setPartner(partner);
  5076.  
  5077.         SystemMessage msg = new SystemMessage(SystemMessage.BEGIN_TRADE_WITH_S1);
  5078.         msg.addString(partner.getName());
  5079.         sendPacket(msg);
  5080.         sendPacket(new TradeStart(this));
  5081.     }
  5082.  
  5083.     public void onTradeConfirm(L2PcInstance partner)
  5084.     {
  5085.  
  5086.         SystemMessage msg = new SystemMessage(SystemMessage.S1_CONFIRMED_TRADE);
  5087.         msg.addString(partner.getName());
  5088.         sendPacket(msg);
  5089.     }
  5090.  
  5091.     public void onTradeCancel(L2PcInstance partner)
  5092.     {
  5093.         if (_activeTradeList == null)
  5094.             return;
  5095.  
  5096.  
  5097.         _activeTradeList.Lock();
  5098.         _activeTradeList = null;
  5099.  
  5100.  
  5101.         sendPacket(new SendTradeDone(0));
  5102.         SystemMessage msg = new SystemMessage(SystemMessage.S1_CANCELED_TRADE);
  5103.         msg.addString(partner.getName());
  5104.         sendPacket(msg);
  5105.     }
  5106.  
  5107.     public void onTradeFinish(boolean successful)
  5108.     {
  5109.         _activeTradeList = null;
  5110.         sendPacket(new SendTradeDone(1));
  5111.  
  5112.         if (successful)
  5113.  
  5114.             sendPacket(new SystemMessage(SystemMessage.TRADE_SUCCESSFUL));
  5115.     }
  5116.  
  5117.     public void startTrade(L2PcInstance partner)
  5118.     {
  5119.         onTradeStart(partner);
  5120.         partner.onTradeStart(this);
  5121.     }
  5122.  
  5123.     public void cancelActiveTrade()
  5124.     {
  5125.         if (_activeTradeList == null)
  5126.  
  5127.             return;
  5128.  
  5129.         L2PcInstance partner = _activeTradeList.getPartner();
  5130.         if (partner != null)
  5131.             partner.onTradeCancel(this);
  5132.  
  5133.         onTradeCancel(this);
  5134.     }
  5135.  
  5136.     /**
  5137.      * Return the _createList object of the L2PcInstance.<BR><BR>
  5138.      */
  5139.     public L2ManufactureList getCreateList()
  5140.     {
  5141.         return _createList;
  5142.     }
  5143.  
  5144.     /**
  5145.      * Set the _createList object of the L2PcInstance.<BR><BR>
  5146.      */
  5147.     public void setCreateList(L2ManufactureList x)
  5148.     {
  5149.         _createList = x;
  5150.     }
  5151.  
  5152.     /**
  5153.      * Return the _buyList object of the L2PcInstance.<BR><BR>
  5154.      */
  5155.     public TradeList getSellList()
  5156.     {
  5157.         if (_sellList == null)
  5158.             _sellList = new TradeList(this);
  5159.  
  5160.         return _sellList;
  5161.     }
  5162.  
  5163.     /**
  5164.      * Return the _buyList object of the L2PcInstance.<BR><BR>
  5165.      */
  5166.     public TradeList getBuyList()
  5167.     {
  5168.         if (_buyList == null)
  5169.             _buyList = new TradeList(this);
  5170.  
  5171.         return _buyList;
  5172.     }
  5173.  
  5174.     /**
  5175.      * Set the Private Store type of the L2PcInstance.<BR><BR>
  5176.      *
  5177.      * <B><U> Values </U> :</B><BR><BR>
  5178.      * <li>0 : STORE_PRIVATE_NONE</li>
  5179.      * <li>1 : STORE_PRIVATE_SELL</li>
  5180.      * <li>2 : sellmanage</li><BR>
  5181.      * <li>3 : STORE_PRIVATE_BUY</li><BR>
  5182.      * <li>4 : buymanage</li><BR>
  5183.      * <li>5 : STORE_PRIVATE_MANUFACTURE</li><BR>
  5184.      * <li>8 : STORE_PRIVATE_PACKAGE_SELL</li><BR>
  5185.      *
  5186.      */
  5187.     public void setPrivateStoreType(int type)
  5188.     {
  5189.         _privatestore = type;
  5190.  
  5191.         if (Config.OFFLINE_DISCONNECT_FINISHED && _privatestore == STORE_PRIVATE_NONE && inOfflineMode())
  5192.             closeNetConnection();
  5193.     }
  5194.  
  5195.     /**
  5196.      * Return the Private Store type of the L2PcInstance.<BR><BR>
  5197.      *
  5198.      * <B><U> Values </U> :</B><BR><BR>
  5199.      * <li>0 : STORE_PRIVATE_NONE</li>
  5200.      * <li>1 : STORE_PRIVATE_SELL</li>
  5201.      * <li>2 : sellmanage</li><BR>
  5202.      * <li>3 : STORE_PRIVATE_BUY</li><BR>
  5203.      * <li>4 : buymanage</li><BR>
  5204.      * <li>5 : STORE_PRIVATE_MANUFACTURE</li><BR>
  5205.      * <li>8 : STORE_PRIVATE_PACKAGE_SELL</li><BR>
  5206.      *
  5207.      */
  5208.     public int getPrivateStoreType()
  5209.     {
  5210.         return _privatestore;
  5211.     }
  5212.  
  5213.     /**
  5214.      * Set the _skillLearningClassId object of the L2PcInstance.<BR><BR>
  5215.      */
  5216.     public void setSkillLearningClassId(ClassId classId)
  5217.     {
  5218.         _skillLearningClassId = classId;
  5219.     }
  5220.  
  5221.     /**
  5222.      * Return the _skillLearningClassId object of the L2PcInstance.<BR><BR>
  5223.      */
  5224.     public ClassId getSkillLearningClassId()
  5225.     {
  5226.         return _skillLearningClassId;
  5227.     }
  5228.  
  5229.     /**
  5230.      * Set the _clan object, _clanId, Flag and title of the L2PcInstance.<BR><BR>
  5231.      */
  5232.     public void setClan(L2Clan clan)
  5233.     {
  5234.         _clan = clan;
  5235.  
  5236.         if (clan == null)
  5237.         {
  5238.             _clanId = 0;
  5239.             _clanPrivileges = 0;
  5240.             _activeWarehouse = null;
  5241.             return;
  5242.         }
  5243.  
  5244.         if (!clan.isMember(getObjectId()))
  5245.         {
  5246.             // char has been kicked from clan
  5247.             setClan(null);
  5248.             return;
  5249.         }
  5250.  
  5251.         _clanId = clan.getClanId();
  5252.     }
  5253.  
  5254.     /**
  5255.      * Return the _clan object of the L2PcInstance.<BR><BR>
  5256.      */
  5257.     public L2Clan getClan()
  5258.     {
  5259.         return _clan;
  5260.     }
  5261.  
  5262.     /**
  5263.      * Return True if the L2PcInstance is the leader of its clan.<BR><BR>
  5264.      */
  5265.     public boolean isClanLeader()
  5266.     {
  5267.         if (getClan() == null)
  5268.  
  5269.             return false;
  5270.  
  5271.  
  5272.         return getObjectId() == getClan().getLeaderId();
  5273.     }
  5274.  
  5275.     /**
  5276.      * Reduce the number of arrows owned by the L2PcInstance and send it Server->Client Packet InventoryUpdate or ItemList (to unequip if the last arrow was consummed).<BR><BR>
  5277.      */
  5278.     protected void reduceArrowCount()
  5279.     {
  5280.         L2ItemInstance arrows = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
  5281.         if (arrows == null)
  5282.         {
  5283.             getInventory().unEquipItemInSlot(Inventory.PAPERDOLL_LHAND);
  5284.             _arrowItem = null;
  5285.             sendPacket(new ItemList(this, false));
  5286.             return;
  5287.         }
  5288.  
  5289.         // Adjust item quantity
  5290.         if (arrows.getCount() > 1)
  5291.         {
  5292.             synchronized(arrows)
  5293.             {
  5294.                 arrows.changeCountWithoutTrace(-1, this, null);
  5295.                 arrows.setLastChange(L2ItemInstance.MODIFIED);
  5296.  
  5297.                 // could do also without saving, but let's save approx 1 of 10
  5298.                 if (GameTimeController.getGameTicks() % 10 == 0)
  5299.                     arrows.updateDatabase();
  5300.                 _inventory.refreshWeight();
  5301.             }
  5302.         }
  5303.         else
  5304.         {
  5305.             // Destroy entire item and save to database
  5306.             _inventory.destroyItem("Consume", arrows, this, null);
  5307.             getInventory().unEquipItemInSlot(Inventory.PAPERDOLL_LHAND);
  5308.             _arrowItem = null;
  5309.  
  5310.             if (Config.DEBUG)
  5311.                 _log.fine("removed arrows count");
  5312.  
  5313.             sendPacket(new ItemList(this, false));
  5314.             return;
  5315.         }
  5316.  
  5317.  
  5318.         if (!Config.FORCE_INVENTORY_UPDATE)
  5319.         {
  5320.             InventoryUpdate iu = new InventoryUpdate();
  5321.             iu.addModifiedItem(arrows);
  5322.             sendPacket(iu);
  5323.         }
  5324.         else
  5325.             sendPacket(new ItemList(this, false));
  5326.  
  5327.     }
  5328.  
  5329.     /**
  5330.      * Equip arrows needed in left hand and send a Server->Client packet ItemList to the L2PcINstance then return True.<BR><BR>
  5331.      */
  5332.     protected boolean checkAndEquipArrows()
  5333.     {
  5334.         // Check if nothing is equiped in left hand
  5335.         if (getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND) == null)
  5336.         {
  5337.             // Get the L2ItemInstance of the arrows needed for this bow
  5338.             _arrowItem = getInventory().findArrowForBow(getActiveWeaponItem());
  5339.  
  5340.             if (_arrowItem != null)
  5341.             {
  5342.                 // Equip arrows needed in left hand
  5343.                 getInventory().setPaperdollItem(Inventory.PAPERDOLL_LHAND, _arrowItem);
  5344.  
  5345.                 // Send a Server->Client packet ItemList to this L2PcINstance to update left hand equipement
  5346.                 ItemList il = new ItemList(this, false);
  5347.                 sendPacket(il);
  5348.             }
  5349.         }
  5350.         else
  5351.  
  5352.             // Get the L2ItemInstance of arrows equiped in left hand
  5353.             _arrowItem = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
  5354.  
  5355.  
  5356.         return _arrowItem != null;
  5357.     }
  5358.  
  5359.     /**
  5360.      * Disarm the player's weapon and shield.<BR><BR>
  5361.      */
  5362.     public boolean disarmWeapons()
  5363.     {
  5364.         // Unequip the weapon
  5365.         L2ItemInstance wpn = getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
  5366.         if (wpn == null) wpn = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LRHAND);
  5367.         if (wpn != null)
  5368.         {
  5369.             if (wpn.isWear())
  5370.                 return false;
  5371.  
  5372.             L2ItemInstance[] unequiped = getInventory().unEquipItemInBodySlotAndRecord(wpn.getItem().getBodyPart());
  5373.             InventoryUpdate iu = new InventoryUpdate();
  5374.             for (int i = 0; i < unequiped.length; i++)
  5375.                 iu.addModifiedItem(unequiped[i]);
  5376.             sendPacket(iu);
  5377.  
  5378.             abortAttack();
  5379.             broadcastUserInfo();
  5380.  
  5381.             // this can be 0 if the user pressed the right mousebutton twice very fast
  5382.             if (unequiped.length > 0)
  5383.             {
  5384.                 SystemMessage sm = null;
  5385.                 if (unequiped[0].getEnchantLevel() > 0)
  5386.                 {
  5387.                     sm = new SystemMessage(SystemMessage.EQUIPMENT_S1_S2_REMOVED);
  5388.                     sm.addNumber(unequiped[0].getEnchantLevel());
  5389.                     sm.addItemName(unequiped[0].getItemId());
  5390.                 }
  5391.                 else
  5392.                 {
  5393.                     sm = new SystemMessage(SystemMessage.S1_DISARMED);
  5394.                     sm.addItemName(unequiped[0].getItemId());
  5395.                 }
  5396.                 sendPacket(sm);
  5397.             }
  5398.         }
  5399.  
  5400.         // Unequip the shield
  5401.         L2ItemInstance sld = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
  5402.         if (sld != null)
  5403.         {
  5404.             if (sld.isWear())
  5405.                 return false;
  5406.  
  5407.             L2ItemInstance[] unequiped = getInventory().unEquipItemInBodySlotAndRecord(sld.getItem().getBodyPart());
  5408.             InventoryUpdate iu = new InventoryUpdate();
  5409.             for (int i = 0; i < unequiped.length; i++)
  5410.                 iu.addModifiedItem(unequiped[i]);
  5411.             sendPacket(iu);
  5412.  
  5413.             abortAttack();
  5414.             broadcastUserInfo();
  5415.  
  5416.             // this can be 0 if the user pressed the right mousebutton twice very fast
  5417.             if (unequiped.length > 0)
  5418.             {
  5419.                 SystemMessage sm = null;
  5420.                 if (unequiped[0].getEnchantLevel() > 0)
  5421.                 {
  5422.                     sm = new SystemMessage(SystemMessage.EQUIPMENT_S1_S2_REMOVED);
  5423.                     sm.addNumber(unequiped[0].getEnchantLevel());
  5424.                     sm.addItemName(unequiped[0].getItemId());
  5425.                 }
  5426.                 else
  5427.                 {
  5428.                     sm = new SystemMessage(SystemMessage.S1_DISARMED);
  5429.                     sm.addItemName(unequiped[0].getItemId());
  5430.                 }
  5431.                 sendPacket(sm);
  5432.             }
  5433.         }
  5434.         return true;
  5435.     }
  5436.  
  5437.     /**
  5438.      * Return True if the L2PcInstance use a dual weapon.<BR><BR>
  5439.      */
  5440.     public boolean isUsingDualWeapon()
  5441.     {
  5442.         L2Weapon weaponItem = getActiveWeaponItem();
  5443.  
  5444.         if (weaponItem == null)
  5445.  
  5446.             return false;
  5447.  
  5448.         if (weaponItem.getItemType() == L2WeaponType.DUAL)
  5449.             return true;
  5450.         else if (weaponItem.getItemType() == L2WeaponType.DUALFIST)
  5451.             return true;
  5452.         else if (weaponItem.getItemId() == 248) // orc fighter fists
  5453.             return true;
  5454.         else if (weaponItem.getItemId() == 252) // orc mage fists
  5455.             return true;
  5456.         else
  5457.             return false;
  5458.     }
  5459.  
  5460.     public void setUptime(long time)
  5461.     {
  5462.         _uptime = time;
  5463.     }
  5464.  
  5465.     public long getUptime()
  5466.     {
  5467.         return System.currentTimeMillis() - _uptime;
  5468.     }
  5469.  
  5470.     /**
  5471.      * Return True if the L2PcInstance is invulnerable.<BR><BR>
  5472.      */
  5473.     public boolean isInvul()
  5474.     {
  5475.         return _IsInvul || _IsTeleporting || _protectEndTime > GameTimeController.getGameTicks();
  5476.     }
  5477.  
  5478.     /**
  5479.      * Return True if the L2PcInstance has a Party in progress.<BR><BR>
  5480.      */
  5481.     public boolean isInParty()
  5482.     {
  5483.         return _party != null;
  5484.     }
  5485.  
  5486.     /**
  5487.      * Set the _party object of the L2PcInstance (without joining it).<BR><BR>
  5488.      */
  5489.     public void setParty(L2Party party)
  5490.     {
  5491.         _party = party;
  5492.     }
  5493.  
  5494.     /**
  5495.      * Set the _party object of the L2PcInstance AND join it.<BR><BR>
  5496.      */
  5497.     public void joinParty(L2Party party)
  5498.     {
  5499.         if (party != null)
  5500.         {
  5501.  
  5502.             // First set the party otherwise this wouldn't be considered
  5503.  
  5504.             // as in a party into the L2Character.updateEffectIcons() call.
  5505.  
  5506.             _party = party;
  5507.             party.addPartyMember(this);
  5508.         }
  5509.     }
  5510.  
  5511.     /**
  5512.      * Manage the Leave Party task of the L2PcInstance.<BR><BR>
  5513.      */
  5514.     public void leaveParty()
  5515.     {
  5516.         if (isInParty())
  5517.         {
  5518.             _party.removePartyMember(this, true);
  5519.             _party = null;
  5520.         }
  5521.     }
  5522.  
  5523.     /**
  5524.      * Return the _party object of the L2PcInstance.<BR><BR>
  5525.      */
  5526.     public L2Party getParty()
  5527.     {
  5528.         return _party;
  5529.     }
  5530.  
  5531.     /**
  5532.      * Set the _isGm Flag of the L2PcInstance.<BR><BR>
  5533.      */
  5534.     public void setIsGM(boolean status)
  5535.     {
  5536.         _isGm = status;
  5537.     }
  5538.  
  5539.     /**
  5540.      * Return True if the L2PcInstance is a GM.<BR><BR>
  5541.      */
  5542.     public boolean isGM()
  5543.     {
  5544.         return _isGm;
  5545.     }
  5546.  
  5547.     /**
  5548.      * Manage a cancel cast task for the L2PcInstance.<BR><BR>
  5549.      *
  5550.      * <B><U> Actions</U> :</B><BR><BR>
  5551.      * <li>Set the Intention of the AI to AI_INTENTION_IDLE </li>
  5552.      * <li>Enable all skills (set _allSkillsDisabled to False) </li>
  5553.      * <li>Send a Server->Client Packet MagicSkillCanceld to the L2PcInstance and all L2PcInstance in the _KnownPlayers of the L2Character (broadcast) </li><BR><BR>
  5554.      *
  5555.      */
  5556.     public void cancelCastMagic()
  5557.     {
  5558.         // Set the Intention of the AI to AI_INTENTION_IDLE
  5559.         getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  5560.  
  5561.         // Enable all skills (set _allSkillsDisabled to False)
  5562.         enableAllSkills();
  5563.  
  5564.         // Send a Server->Client Packet MagicSkillCanceld to the L2PcInstance and all L2PcInstance in the _KnownPlayers of the L2Character (broadcast)
  5565.         MagicSkillCanceld msc = new MagicSkillCanceld(getObjectId());
  5566.  
  5567.  
  5568.         // Broadcast the packet to self and known players.
  5569.  
  5570.         Broadcast.toSelfAndKnownPlayersInRadius(this, msc, 810000/*900*/);
  5571.     }
  5572.  
  5573.     /**
  5574.      * Set the _accessLevel of the L2PcInstance.<BR><BR>
  5575.      */
  5576.     public void setAccessLevel(int level)
  5577.     {
  5578.         _accessLevel = level;
  5579.  
  5580.  
  5581.         if (_accessLevel > 0 || Config.EVERYBODY_HAS_ADMIN_RIGHTS)
  5582.             setIsGM(true);
  5583.     }
  5584.  
  5585.     public void setAccountAccesslevel(int level)
  5586.     {
  5587.         if (_connection != null)
  5588.             LoginServerThread.getInstance().sendAccessLevel(getAccountName(),level);
  5589.         else
  5590.             _log.info("Couldnt set the player's account access level");
  5591.     }
  5592.  
  5593.     /**
  5594.      * Return the _accessLevel of the L2PcInstance.<BR><BR>
  5595.      */
  5596.     public int getAccessLevel()
  5597.     {
  5598.         if (Config.EVERYBODY_HAS_ADMIN_RIGHTS && _accessLevel <= 200)
  5599.             return 200;
  5600.  
  5601.  
  5602.         return _accessLevel;
  5603.     }
  5604.  
  5605.     public double getLevelMod()
  5606.     {
  5607.         return (100.0 - 11 + getLevel()) / 100.0;
  5608.     }
  5609.  
  5610.     /**
  5611.      * Update Stats of the L2PcInstance client side by sending Server->Client packet UserInfo/StatusUpdate to this L2PcInstance and CharInfo/StatusUpdate to all L2PcInstance in its _KnownPlayers (broadcast).<BR><BR>
  5612.      */
  5613.     public void updateAndBroadcastStatus(int broadcastType)
  5614.  
  5615.     {
  5616.         refreshOverloaded();
  5617.         refreshExpertisePenalty();
  5618.         // Send a Server->Client packet UserInfo to this L2PcInstance and CharInfo to all L2PcInstance in its _KnownPlayers (broadcast)
  5619.  
  5620.         if (broadcastType == 1)
  5621.             sendPacket(new UserInfo(this));
  5622.  
  5623.         if (broadcastType == 2)
  5624.             broadcastUserInfo();
  5625.     }
  5626.  
  5627.     /**
  5628.      * Send a Server->Client StatusUpdate packet with Karma and PvP Flag to the L2PcInstance and all L2PcInstance to inform (broadcast).<BR><BR>
  5629.      */
  5630.     public void setKarmaFlag(int flag)
  5631.     {
  5632.         sendPacket(new UserInfo(this));
  5633.         for (L2PcInstance player : getKnownList().getKnownPlayers().values())
  5634.  
  5635.         {
  5636.  
  5637.             player.sendPacket(new RelationChanged(this, getRelation(player), isAutoAttackable(player)));
  5638.             if (getPet() != null)
  5639.                 player.sendPacket(new RelationChanged(getPet(), getRelation(player), isAutoAttackable(player)));
  5640.         }
  5641.     }
  5642.  
  5643.     /**
  5644.      * Send a Server->Client StatusUpdate packet with Karma to the L2PcInstance and all L2PcInstance to inform (broadcast).<BR><BR>
  5645.      */
  5646.     public void broadcastKarma()
  5647.     {
  5648.         StatusUpdate su = new StatusUpdate(getObjectId());
  5649.  
  5650.         su.addAttribute(StatusUpdate.KARMA, getKarma());
  5651.  
  5652.         sendPacket(su);
  5653.  
  5654.         for (L2PcInstance player : getKnownList().getKnownPlayers().values())
  5655.  
  5656.         {
  5657.  
  5658.             player.sendPacket(new RelationChanged(this, getRelation(player), isAutoAttackable(player)));
  5659.             if (getPet() != null)
  5660.                 player.sendPacket(new RelationChanged(getPet(), getRelation(player), isAutoAttackable(player)));
  5661.         }
  5662.     }
  5663.  
  5664.     /**
  5665.      * Set the online Flag to True or False and update the characters table of the database with online status and lastAccess (called when login and logout).<BR><BR>
  5666.      */
  5667.     public void setOnlineStatus(boolean isOnline)
  5668.     {
  5669.         if (_isOnline != isOnline)
  5670.             _isOnline = isOnline;            
  5671.  
  5672.         // Update the characters table of the database with online status and lastAccess (called when login and logout)
  5673.         updateOnlineStatus();
  5674.     }
  5675.  
  5676.     /**
  5677.      * Update the characters table of the database with online status and lastAccess of this L2PcInstance (called when login and logout).<BR><BR>
  5678.      */
  5679.     public void updateOnlineStatus()
  5680.     {
  5681.         java.sql.Connection con = null;
  5682.         try
  5683.  
  5684.         {
  5685.             con = L2DatabaseFactory.getInstance().getConnection();
  5686.             PreparedStatement statement = con.prepareStatement("UPDATE characters SET online=?, lastAccess=? WHERE obj_Id=?");
  5687.             statement.setInt(1, isOnline());
  5688.             statement.setLong(2, System.currentTimeMillis());
  5689.             statement.setInt(3, getObjectId());
  5690.             statement.execute();
  5691.             statement.close();
  5692.         }
  5693.         catch (Exception e)
  5694.         {
  5695.             _log.warning("could not set char online status:"+e);
  5696.         }
  5697.         finally
  5698.         {
  5699.             try
  5700.             {
  5701.                 con.close();
  5702.             }
  5703.             catch (Exception e) {}
  5704.         }
  5705.     }
  5706.  
  5707.     /**
  5708.      * Create a new player in the characters table of the database.<BR><BR>
  5709.      */
  5710.     private boolean createDb()
  5711.     {
  5712.         java.sql.Connection con = null;
  5713.         try
  5714.         {
  5715.             con = L2DatabaseFactory.getInstance().getConnection();
  5716.             PreparedStatement statement;
  5717.             statement = con.prepareStatement("INSERT INTO characters " +
  5718.                   "(account_name,obj_Id,char_name,level,maxHp,curHp,maxCp,curCp,maxMp,curMp," +
  5719.                   "acc,crit,evasion,mAtk,mDef,mSpd,pAtk,pDef,pSpd,runSpd,walkSpd," +
  5720.                   "str,con,dex,_int,men,wit,face,hairStyle,hairColor,sex," +
  5721.                   "movement_multiplier,attack_speed_multiplier,colRad,colHeight," +
  5722.                   "exp,sp,karma,pvpkills,pkkills,clanid,maxload,race,classid,deletetime," +
  5723.                   "cancraft,title,accesslevel,online,clan_privs,wantspeace," +
  5724.                   "base_class,newbie,nobless,last_recom_date) " +
  5725.                   "values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
  5726.             statement.setString(1, _accountName);
  5727.             statement.setInt(2, getObjectId());
  5728.             statement.setString(3, getName());
  5729.             statement.setInt(4, getLevel());
  5730.             statement.setInt(5, getMaxHp());
  5731.             statement.setDouble(6, getCurrentHp());
  5732.             statement.setInt(7, getMaxCp());
  5733.             statement.setDouble(8, getCurrentCp());
  5734.             statement.setInt(9, getMaxMp());
  5735.             statement.setDouble(10, getCurrentMp());
  5736.             statement.setInt(11, getAccuracy());
  5737.             statement.setInt(12, getCriticalHit(null, null));
  5738.             statement.setInt(13, getEvasionRate(null));
  5739.             statement.setInt(14, getMAtk(null, null));
  5740.             statement.setInt(15, getMDef(null, null));
  5741.             statement.setInt(16, getMAtkSpd());
  5742.             statement.setInt(17, getPAtk(null));
  5743.             statement.setInt(18, getPDef(null));
  5744.             statement.setInt(19, getPAtkSpd());
  5745.             statement.setInt(20, getRunSpeed());
  5746.             statement.setInt(21, getWalkSpeed());
  5747.             statement.setInt(22, getSTR());
  5748.             statement.setInt(23, getCON());
  5749.             statement.setInt(24, getDEX());
  5750.             statement.setInt(25, getINT());
  5751.             statement.setInt(26, getMEN());
  5752.             statement.setInt(27, getWIT());
  5753.             statement.setInt(28, getAppearance().getFace());
  5754.             statement.setInt(29, getAppearance().getHairStyle());
  5755.             statement.setInt(30, getAppearance().getHairColor());
  5756.             statement.setInt(31, getAppearance().getSex() ? 1 : 0);
  5757.             statement.setDouble(32, 1); // speed multiplier
  5758.             statement.setDouble(33, 1); // atk speed multiplier
  5759.             statement.setDouble(34, getCollisionRadius());
  5760.             statement.setDouble(35, getCollisionHeight());
  5761.             statement.setLong(36, getExp());
  5762.             statement.setInt(37, getSp());
  5763.             statement.setInt(38, getKarma());
  5764.             statement.setInt(39, getPvpKills());
  5765.             statement.setInt(40, getPkKills());
  5766.             statement.setInt(41, getClanId());
  5767.             statement.setInt(42, getMaxLoad());
  5768.             statement.setInt(43, getRace().ordinal());
  5769.             statement.setInt(44, getClassId().getId());
  5770.             statement.setLong(45, getDeleteTimer());
  5771.             statement.setInt(46, hasDwarvenCraft() ? 1 : 0);
  5772.             statement.setString(47, getTitle());
  5773.             statement.setInt(48, getAccessLevel());
  5774.             statement.setInt(49, isOnline());
  5775.  
  5776.             statement.setInt(50, getClanPrivileges());
  5777.             statement.setInt(51, getWantsPeace());
  5778.             statement.setInt(52, getBaseClass());
  5779.             statement.setInt(53, getNewbieState());
  5780.  
  5781.             statement.setInt(54, isNoble() ? 1 : 0);
  5782.  
  5783.             statement.setLong(55, System.currentTimeMillis());
  5784.             statement.executeUpdate();
  5785.             statement.close();
  5786.         }
  5787.         catch (Exception e)
  5788.         {
  5789.             _log.warning("Could not insert char data: " + e);
  5790.             return false;
  5791.         }
  5792.         finally
  5793.         {
  5794.             try
  5795.             {
  5796.                 con.close();
  5797.             }
  5798.             catch (Exception e) {}
  5799.         }
  5800.         return true;
  5801.     }
  5802.  
  5803.     /**
  5804.      * Retrieve a L2PcInstance from the characters table of the database and add it in _allObjects of the L2world.<BR><BR>
  5805.      *
  5806.      * <B><U> Actions</U> :</B><BR><BR>
  5807.      * <li>Retrieve the L2PcInstance from the characters table of the database </li>
  5808.      * <li>Add the L2PcInstance object in _allObjects </li>
  5809.      * <li>Set the x,y,z position of the L2PcInstance and make it invisible</li>
  5810.      * <li>Update the overloaded status of the L2PcInstance</li><BR><BR>
  5811.      *
  5812.      * @param objectId Identifier of the object to initialized
  5813.      *
  5814.      * @return The L2PcInstance loaded from the database
  5815.      *
  5816.      */
  5817.     private static L2PcInstance restore(int objectId)
  5818.     {
  5819.         L2PcInstance player = null;
  5820.         java.sql.Connection con = null;
  5821.         try
  5822.         {
  5823.             // Retrieve the L2PcInstance from the characters table of the database
  5824.             con = L2DatabaseFactory.getInstance().getConnection();
  5825.  
  5826.             PreparedStatement statement = con.prepareStatement(RESTORE_CHARACTER);
  5827.             statement.setInt(1, objectId);
  5828.             ResultSet rset = statement.executeQuery();
  5829.  
  5830.             double currentCp = 0;
  5831.             double currentHp = 0;
  5832.             double currentMp = 0;
  5833.  
  5834.  
  5835.             while (rset.next())
  5836.             {
  5837.                 final int activeClassId = rset.getInt("classid");
  5838.                 final boolean female = rset.getInt("sex") != 0;
  5839.                 final L2PcTemplate template = CharTemplateTable.getInstance().getTemplate(activeClassId);
  5840.                 PcAppearance app = new PcAppearance(rset.getByte("face"), rset.getByte("hairColor"), rset.getByte("hairStyle"), female);
  5841.  
  5842.                 player = new L2PcInstance(objectId, template, rset.getString("account_name"), app);
  5843.                 player.setName(rset.getString("char_name"));
  5844.                 player._lastAccess = rset.getLong("lastAccess");
  5845.  
  5846.                 player.getStat().setExp(rset.getLong("exp"));
  5847.                 player.getStat().setLevel(rset.getInt("level"));
  5848.                 player.getStat().setSp(rset.getInt("sp"));
  5849.  
  5850.                 player.setClanPrivileges(rset.getInt("clan_privs"));
  5851.                 player.setWantsPeace(rset.getInt("wantspeace"));
  5852.  
  5853.                 player.setHeading(rset.getInt("heading"));
  5854.  
  5855.                 player.setKarma(rset.getInt("karma"));
  5856.                 player.setPvpKills(rset.getInt("pvpkills"));
  5857.                 player.setPkKills(rset.getInt("pkkills"));
  5858.  
  5859.  
  5860.                 player.setClanJoinExpiryTime(rset.getLong("clan_join_expiry_time"));
  5861.  
  5862.                 if (player.getClanJoinExpiryTime() < System.currentTimeMillis())
  5863.  
  5864.                 {
  5865.  
  5866.                     player.setClanJoinExpiryTime(0);
  5867.  
  5868.                 }
  5869.  
  5870.  
  5871.                 player.setClanCreateExpiryTime(rset.getLong("clan_create_expiry_time"));
  5872.  
  5873.                 if (player.getClanCreateExpiryTime() < System.currentTimeMillis())
  5874.                 {
  5875.                     player.setClanCreateExpiryTime(0);
  5876.                 }
  5877.  
  5878.                 player.setOnlineTime(rset.getLong("onlinetime"));
  5879.  
  5880.                 player.setNewbieState(rset.getInt("newbie"));
  5881.                 player.setNoble(rset.getInt("nobless") == 1 || Config.AUTO_NOBLE_STATUS);
  5882.  
  5883.                 player.setLastRecomUpdate(rset.getLong("last_recom_date"));
  5884.  
  5885.  
  5886.                 player.setClanJoinExpiryTime(rset.getLong("clan_join_expiry_time"));
  5887.  
  5888.                 if (player.getClanJoinExpiryTime() < System.currentTimeMillis())
  5889.  
  5890.                 {
  5891.  
  5892.                     player.setClanJoinExpiryTime(0);
  5893.  
  5894.                 }
  5895.  
  5896.  
  5897.                 player.setClanCreateExpiryTime(rset.getLong("clan_create_expiry_time"));
  5898.  
  5899.                 if (player.getClanCreateExpiryTime() < System.currentTimeMillis())
  5900.  
  5901.                 {
  5902.  
  5903.                     player.setClanCreateExpiryTime(0);
  5904.  
  5905.                 }
  5906.  
  5907.                 int clanId = rset.getInt("clanid");
  5908.                 if (clanId > 0)
  5909.                     player.setClan(ClanTable.getInstance().getClan(clanId));
  5910.  
  5911.                 player.setDeleteTimer(rset.getLong("deletetime"));
  5912.  
  5913.                 player.setTitle(rset.getString("title"));
  5914.                 player.setAccessLevel(rset.getInt("accesslevel"));
  5915.                 player.setFistsWeaponItem(player.findFistsWeaponItem(activeClassId));
  5916.                 player.setUptime(System.currentTimeMillis());
  5917.  
  5918.                 currentHp = rset.getDouble("curHp");
  5919.                 currentCp = rset.getDouble("curCp");
  5920.                 currentMp = rset.getDouble("curMp");
  5921.  
  5922.                 //Check recs
  5923.                 player.checkRecom(rset.getInt("rec_have"),rset.getInt("rec_left"));
  5924.  
  5925.  
  5926.                 player._classIndex = 0;
  5927.  
  5928.                 try
  5929.                 {
  5930.                     player.setBaseClass(rset.getInt("base_class"));
  5931.                 }
  5932.  
  5933.                 catch (Exception e)
  5934.                 {
  5935.                     player.setBaseClass(activeClassId);
  5936.                 }
  5937.  
  5938.  
  5939.                 // Restore Subclass Data (cannot be done earlier in function)
  5940.  
  5941.                 if (restoreSubClassData(player))
  5942.  
  5943.                 {
  5944.  
  5945.                     if (activeClassId != player.getBaseClass())
  5946.  
  5947.                     {
  5948.  
  5949.                         for (SubClass subClass : player.getSubClasses().values())
  5950.                         {
  5951.  
  5952.                             if (subClass.getClassId() == activeClassId)
  5953.  
  5954.                                 player._classIndex = subClass.getClassIndex();
  5955.                         }
  5956.  
  5957.                     }
  5958.  
  5959.                 }                
  5960.  
  5961.  
  5962.  
  5963.                 if (player.getClassIndex() == 0 && activeClassId != player.getBaseClass())
  5964.  
  5965.                 {
  5966.  
  5967.                     // Subclass in use but doesn't exist in DB -
  5968.  
  5969.                     // a possible restart-while-modifysubclass cheat has been attempted.
  5970.  
  5971.                     // Switching to use base class
  5972.  
  5973.                     player.setClassId(player.getBaseClass());
  5974.  
  5975.                     _log.warning("Player "+player.getName()+" reverted to base class. Possibly has tried a relogin exploit while subclassing.");
  5976.  
  5977.                 }
  5978.  
  5979.                 else
  5980.                     player._activeClass = activeClassId;
  5981.  
  5982.  
  5983.                 player.setInJail(rset.getInt("in_jail") == 1);
  5984.  
  5985.                 if (player.isInJail())
  5986.  
  5987.                     player.setJailTimer(rset.getLong("jail_timer"));
  5988.  
  5989.                 else
  5990.  
  5991.                     player.setJailTimer(0);
  5992.  
  5993.  
  5994.  
  5995.                 player.setAllianceWithVarkaKetra(rset.getInt("varka_ketra_ally"));
  5996.  
  5997.                 // Set the x,y,z position of the L2PcInstance and make it invisible
  5998.                 player.setXYZInvisible(rset.getInt("x"), rset.getInt("y"), rset.getInt("z"));
  5999.  
  6000.                 // Retrieve the name and ID of the other characters assigned to this account.
  6001.                 PreparedStatement stmt = con.prepareStatement("SELECT obj_Id, char_name FROM characters WHERE account_name=? AND obj_Id<>?");
  6002.                 stmt.setString(1, player._accountName);
  6003.                 stmt.setInt(2, objectId);
  6004.                 ResultSet chars = stmt.executeQuery();
  6005.  
  6006.                 while (chars.next())
  6007.                 {
  6008.                     Integer charId = chars.getInt("obj_Id");
  6009.                     String charName = chars.getString("char_name");
  6010.                     player._chars.put(charId, charName);
  6011.                 }
  6012.  
  6013.                 chars.close();
  6014.                 stmt.close();
  6015.                 break;
  6016.             }
  6017.    
  6018.             rset.close();
  6019.             statement.close();
  6020.  
  6021.             // Retrieve from the database all secondary data of this L2PcInstance
  6022.             // and reward expertise/lucky skills if necessary.
  6023.             player.restoreCharData();
  6024.             player.rewardSkills();
  6025.  
  6026.  
  6027.             if (Config.STORE_SKILL_COOLTIME)
  6028.  
  6029.                 player.restoreEffects();
  6030.  
  6031.             // Restore current Cp, HP and MP values
  6032.             player.setCurrentCp(currentCp);
  6033.             player.setCurrentHp(currentHp);
  6034.             player.setCurrentMp(currentMp);
  6035.  
  6036.  
  6037.             if (currentHp < 0.5)
  6038.  
  6039.             {
  6040.  
  6041.                 player.setIsDead(true);
  6042.  
  6043.                 player.stopHpMpRegeneration();
  6044.  
  6045.             }
  6046.  
  6047.             // Restore pet if exists in the world
  6048.             player.setPet(L2World.getInstance().getPet(player.getObjectId()));
  6049.  
  6050.             if (player.getPet() != null)
  6051.                 player.getPet().setOwner(player);
  6052.  
  6053.             // Update the overloaded status of the L2PcInstance
  6054.             player.refreshOverloaded();
  6055.         }
  6056.         catch (Exception e)
  6057.         {
  6058.             _log.warning("Could not restore char data: " + e);
  6059.         }
  6060.         finally
  6061.         {
  6062.             try
  6063.             {
  6064.                 con.close();
  6065.             }
  6066.             catch (Exception e) {}
  6067.         }
  6068.  
  6069.  
  6070.         return player;
  6071.     }
  6072.  
  6073.     /**
  6074.      * @return
  6075.      */
  6076.     public Forum getMail()
  6077.     {
  6078.         if (_forumMail == null)
  6079.         {
  6080.             setMail(ForumsBBSManager.getInstance().getForumByName("MailRoot").GetChildByName(getName()));
  6081.  
  6082.             if (_forumMail == null)
  6083.             {
  6084.                 ForumsBBSManager.getInstance().CreateNewForum(getName(),ForumsBBSManager.getInstance().getForumByName("MailRoot"),Forum.MAIL,Forum.OWNERONLY,getObjectId());
  6085.                 setMail(ForumsBBSManager.getInstance().getForumByName("MailRoot").GetChildByName(getName()));
  6086.             }
  6087.         }
  6088.  
  6089.  
  6090.         return _forumMail;
  6091.     }
  6092.  
  6093.     /**
  6094.      * @param forum
  6095.      */
  6096.     public void setMail(Forum forum)
  6097.     {
  6098.         _forumMail = forum;
  6099.     }
  6100.  
  6101.     /**
  6102.      * @return
  6103.      */
  6104.     public Forum getMemo()
  6105.     {
  6106.         if (_forumMemo == null)
  6107.         {
  6108.             setMemo(ForumsBBSManager.getInstance().getForumByName("MemoRoot").GetChildByName(_accountName));
  6109.  
  6110.  
  6111.             if (_forumMemo == null)
  6112.  
  6113.             {
  6114.                 ForumsBBSManager.getInstance().CreateNewForum(_accountName,ForumsBBSManager.getInstance().getForumByName("MemoRoot"),Forum.MEMO,Forum.OWNERONLY,getObjectId());
  6115.  
  6116.                 setMemo(ForumsBBSManager.getInstance().getForumByName("MemoRoot").GetChildByName(_accountName));
  6117.             }
  6118.         }
  6119.  
  6120.  
  6121.         return _forumMemo;
  6122.     }
  6123.  
  6124.     /**
  6125.      * @param forum
  6126.      */
  6127.     public void setMemo(Forum forum)
  6128.     {
  6129.         _forumMemo = forum;
  6130.     }
  6131.  
  6132.     /**
  6133.      * Restores sub-class data for the L2PcInstance, used to check the current
  6134.      * class index for the character.
  6135.      */
  6136.     private static boolean restoreSubClassData(L2PcInstance player)
  6137.     {
  6138.         java.sql.Connection con = null;
  6139.  
  6140.         try
  6141.         {
  6142.             con = L2DatabaseFactory.getInstance().getConnection();
  6143.             PreparedStatement statement = con.prepareStatement(RESTORE_CHAR_SUBCLASSES);
  6144.             statement.setInt(1, player.getObjectId());
  6145.  
  6146.  
  6147.             ResultSet rset = statement.executeQuery();
  6148.  
  6149.  
  6150.             while (rset.next())
  6151.             {
  6152.                 SubClass subClass = new SubClass();
  6153.                 subClass.setClassId(rset.getInt("class_id"));
  6154.                 subClass.setLevel(rset.getInt("level"));
  6155.                 subClass.setExp(rset.getLong("exp"));
  6156.                 subClass.setSp(rset.getInt("sp"));
  6157.                 subClass.setClassIndex(rset.getInt("class_index"));
  6158.  
  6159.  
  6160.                 // Enforce the correct indexing of _subClasses against their class indexes.
  6161.                 player.getSubClasses().put(subClass.getClassIndex(), subClass);
  6162.             }
  6163.  
  6164.  
  6165.             statement.close();
  6166.         }
  6167.         catch (Exception e)
  6168.         {
  6169.             _log.warning("Could not restore classes for " + player.getName() + ": " + e);
  6170.             e.printStackTrace();
  6171.         }
  6172.         finally
  6173.         {
  6174.             try
  6175.             {
  6176.                 con.close();
  6177.             }
  6178.             catch (Exception e) {}
  6179.         }
  6180.  
  6181.  
  6182.         return true;
  6183.     }
  6184.  
  6185.     /**
  6186.      * Restores secondary data for the L2PcInstance, based on the current class index.
  6187.      */
  6188.     private void restoreCharData()
  6189.     {
  6190.         // Retrieve from the database all skills of this L2PcInstance and add them to _skills.
  6191.         restoreSkills();
  6192.  
  6193.         // Retrieve from the database all macroses of this L2PcInstance and add them to _macroses.
  6194.         _macroses.restore();
  6195.  
  6196.         // Retrieve from the database all shortCuts of this L2PcInstance and add them to _shortCuts.
  6197.         _shortCuts.restore();
  6198.  
  6199.         // Retrieve from the database all henna of this L2PcInstance and add them to _henna.
  6200.         restoreHenna();
  6201.  
  6202.  
  6203.         // Retrieve from the database all recom data of this L2PcInstance and add to _recomChars.
  6204.  
  6205.         if (Config.ALT_RECOMMEND)
  6206.             restoreRecom();
  6207.  
  6208.         // Retrieve from the database the recipe book of this L2PcInstance.
  6209.         restoreRecipeBook(isSubClassActive() ? 1 : 2);
  6210.  
  6211.         // Retrieve from the database all friends
  6212.         restoreFriends();
  6213.     }
  6214.  
  6215.     /**
  6216.      * Store dwarven recipe book data for this L2PcInstance, if not on an active sub-class.
  6217.      */
  6218.     private void storeDwarvenRecipeBook()
  6219.     {
  6220.         if (getDwarvenRecipeBook().length == 0)
  6221.             return;
  6222.  
  6223.         java.sql.Connection con = null;
  6224.         try
  6225.         {
  6226.             con = L2DatabaseFactory.getInstance().getConnection();
  6227.             PreparedStatement statement = con.prepareStatement("DELETE FROM character_recipebook WHERE char_id=? AND type=1");
  6228.             statement.setInt(1, getObjectId());
  6229.             statement.execute();
  6230.             statement.close();
  6231.  
  6232.             L2RecipeList[] recipes = getDwarvenRecipeBook();
  6233.             for (int count = 0; count < recipes.length; count++)
  6234.             {
  6235.                 statement = con.prepareStatement("INSERT INTO character_recipebook (char_id, id, type) values(?,?,1)");
  6236.                 statement.setInt(1, getObjectId());
  6237.                 statement.setInt(2, recipes[count].getId());
  6238.                 statement.execute();
  6239.                 statement.close();
  6240.             }
  6241.         }
  6242.         catch (Exception e)
  6243.         {
  6244.             _log.warning("Could not store dwarven recipe book data: " + e);
  6245.         }
  6246.         finally
  6247.         {
  6248.             try
  6249.             {
  6250.                 con.close();
  6251.             }
  6252.             catch (Exception e) {}
  6253.         }
  6254.     }
  6255.  
  6256.     /**
  6257.      * Store common recipe book data for this L2PcInstance.
  6258.      */
  6259.     private void storeCommonRecipeBook()
  6260.     {
  6261.         if (getCommonRecipeBook().length == 0)
  6262.             return;
  6263.  
  6264.         java.sql.Connection con = null;
  6265.         try
  6266.         {
  6267.             con = L2DatabaseFactory.getInstance().getConnection();
  6268.             PreparedStatement statement = con.prepareStatement("DELETE FROM character_recipebook WHERE char_id=? AND type=0");
  6269.             statement.setInt(1, getObjectId());
  6270.             statement.execute();
  6271.             statement.close();
  6272.  
  6273.             L2RecipeList[] recipes = getCommonRecipeBook();
  6274.  
  6275.             for (int count = 0; count < recipes.length; count++)
  6276.             {
  6277.                 statement = con.prepareStatement("INSERT INTO character_recipebook (char_id, id, type) values(?,?,0)");
  6278.                 statement.setInt(1, getObjectId());
  6279.                 statement.setInt(2, recipes[count].getId());
  6280.                 statement.execute();
  6281.                 statement.close();
  6282.             }
  6283.         }
  6284.         catch (Exception e)
  6285.         {
  6286.             _log.warning("Could not store common recipe book data: " + e);
  6287.         }
  6288.         finally
  6289.         {
  6290.             try
  6291.             {
  6292.                 con.close();
  6293.             }
  6294.             catch (Exception e) {}
  6295.         }
  6296.     }
  6297.  
  6298.     /**
  6299.      * Restore recipe book data for this L2PcInstance.
  6300.      * recipeType is the type you do not want to restore.
  6301.      */
  6302.     private void restoreRecipeBook(int recipeType)
  6303.     {
  6304.         java.sql.Connection con = null;
  6305.         try
  6306.         {
  6307.             con = L2DatabaseFactory.getInstance().getConnection();
  6308.             PreparedStatement statement = con.prepareStatement("SELECT id, type FROM character_recipebook WHERE char_id=? AND type<>?");
  6309.             statement.setInt(1, getObjectId());
  6310.             statement.setInt(2, recipeType);
  6311.             ResultSet rset = statement.executeQuery();
  6312.  
  6313.             L2RecipeList recipe;
  6314.             while (rset.next())
  6315.             {
  6316.                 recipe = RecipeController.getInstance().getRecipeList(rset.getInt("id") - 1);
  6317.                 if (rset.getInt("type") == 1)
  6318.                     registerDwarvenRecipeList(recipe);
  6319.                 else
  6320.                     registerCommonRecipeList(recipe);
  6321.             }
  6322.  
  6323.             rset.close();
  6324.             statement.close();
  6325.         }
  6326.         catch (Exception e)
  6327.         {
  6328.             _log.warning("Could not restore recipe book data:" + e);
  6329.         }
  6330.         finally
  6331.         {
  6332.             try
  6333.             {
  6334.                 con.close();
  6335.             }
  6336.             catch (Exception e) {}
  6337.         }
  6338.     }
  6339.  
  6340.     /**
  6341.      * Update L2PcInstance stats in the characters table of the database.<BR><BR>
  6342.      */
  6343.     public void store()
  6344.     {
  6345.  
  6346.         storeCharBase();
  6347.         storeCharSub();
  6348.         storeEffect(true);
  6349.         storeDwarvenRecipeBook();
  6350.         storeCommonRecipeBook();
  6351.     }
  6352.  
  6353.     private void storeCharBase()
  6354.     {
  6355.         java.sql.Connection con = null;
  6356.         try
  6357.         {
  6358.             // Get the exp, level, and sp of base class to store in base table
  6359.             int currentClassIndex = getClassIndex();
  6360.             _classIndex = 0;
  6361.             long exp = getStat().getExp();
  6362.             int level = getStat().getLevel();
  6363.             int sp = getStat().getSp();
  6364.             _classIndex = currentClassIndex;
  6365.  
  6366.             con = L2DatabaseFactory.getInstance().getConnection();
  6367.             PreparedStatement statement;
  6368.  
  6369.             // Update base class
  6370.  
  6371.             statement = con.prepareStatement(UPDATE_CHARACTER);
  6372.             statement.setInt(1, level);
  6373.             statement.setInt(2, getMaxHp());
  6374.             statement.setDouble(3, getCurrentHp());
  6375.             statement.setInt(4, getMaxCp());
  6376.             statement.setDouble(5, getCurrentCp());
  6377.             statement.setInt(6, getMaxMp());
  6378.             statement.setDouble(7, getCurrentMp());
  6379.             statement.setInt(8, getSTR());
  6380.             statement.setInt(9, getCON());
  6381.             statement.setInt(10, getDEX());
  6382.             statement.setInt(11, getINT());
  6383.             statement.setInt(12, getMEN());
  6384.             statement.setInt(13, getWIT());
  6385.             statement.setInt(14, getAppearance().getFace());
  6386.             statement.setInt(15, getAppearance().getHairStyle());
  6387.             statement.setInt(16, getAppearance().getHairColor());
  6388.             statement.setInt(17, getAppearance().getSex() ? 1 : 0);
  6389.             statement.setInt(18, getHeading());
  6390.             statement.setInt(19, _observerMode ? _obsX : getX());
  6391.             statement.setInt(20, _observerMode ? _obsY : getY());
  6392.             statement.setInt(21, _observerMode ? _obsZ : getZ());
  6393.             statement.setLong(22, exp);
  6394.             statement.setInt(23, sp);
  6395.             statement.setInt(24, getKarma());
  6396.             statement.setInt(25, getPvpKills());
  6397.             statement.setInt(26, getPkKills());
  6398.             statement.setInt(27, getRecomHave());
  6399.             statement.setInt(28, getRecomLeft());
  6400.             statement.setInt(29, getClanId());
  6401.             statement.setInt(30, getMaxLoad());
  6402.             statement.setInt(31, getRace().ordinal());
  6403.             statement.setInt(32, getClassId().getId());
  6404.             statement.setLong(33, getDeleteTimer());
  6405.             statement.setString(34, getTitle());
  6406.             statement.setInt(35, getAccessLevel());
  6407.             statement.setInt(36, isOnline());
  6408.  
  6409.             statement.setInt(37, getClanPrivileges());
  6410.             statement.setInt(38, getWantsPeace());
  6411.             statement.setLong(39, getClanJoinExpiryTime());
  6412.  
  6413.             statement.setLong(40, getClanCreateExpiryTime());
  6414.             statement.setInt(41, getBaseClass());
  6415.  
  6416.  
  6417.             long totalOnlineTime = _onlineTime;
  6418.  
  6419.             if (_onlineBeginTime > 0)
  6420.                 totalOnlineTime += (System.currentTimeMillis()-_onlineBeginTime)/1000;
  6421.  
  6422.  
  6423.  
  6424.             statement.setLong(42, totalOnlineTime);
  6425.  
  6426.             statement.setInt(43, isInJail() ? 1 : 0);
  6427.  
  6428.             statement.setLong(44, getJailTimer());
  6429.             statement.setInt(45, getNewbieState());
  6430.  
  6431.             statement.setInt(46, isNoble() ? 1 : 0);
  6432.  
  6433.             statement.setLong(47, getLastRecomUpdate());
  6434.  
  6435.             statement.setInt(48, getAllianceWithVarkaKetra());
  6436.  
  6437.             statement.setString(49, getName());
  6438.  
  6439.             statement.setInt(50, getObjectId());
  6440.             statement.execute();
  6441.             statement.close();
  6442.         }
  6443.         catch (Exception e)
  6444.         {
  6445.             _log.warning("Could not store char base data: "+ e);
  6446.         }
  6447.         finally
  6448.         {
  6449.             try
  6450.             {
  6451.                 con.close();
  6452.             }
  6453.             catch (Exception e) {}
  6454.         }
  6455.     }
  6456.  
  6457.     private void storeCharSub()
  6458.     {
  6459.         java.sql.Connection con = null;
  6460.  
  6461.         try
  6462.         {
  6463.             con = L2DatabaseFactory.getInstance().getConnection();
  6464.             PreparedStatement statement;
  6465.  
  6466.             if (getTotalSubClasses() > 0)
  6467.             {
  6468.                 for (SubClass subClass : getSubClasses().values())
  6469.                 {
  6470.  
  6471.                     statement = con.prepareStatement(UPDATE_CHAR_SUBCLASS);
  6472.                     statement.setLong(1, subClass.getExp());
  6473.                     statement.setInt(2, subClass.getSp());
  6474.                     statement.setInt(3, subClass.getLevel());
  6475.                     statement.setInt(4, subClass.getClassId());
  6476.                     statement.setInt(5, getObjectId());
  6477.                     statement.setInt(6, subClass.getClassIndex());
  6478.  
  6479.  
  6480.                     statement.execute();
  6481.                     statement.close();
  6482.                 }
  6483.             }
  6484.         }
  6485.         catch (Exception e)
  6486.         {
  6487.             _log.warning("Could not store sub class data for " + getName() + ": "+ e);
  6488.         }
  6489.         finally
  6490.         {
  6491.             try
  6492.             {
  6493.                 con.close();
  6494.             }
  6495.             catch (Exception e) {}
  6496.         }
  6497.     }
  6498.  
  6499.     private void storeEffect(boolean storeEffects)
  6500.     {
  6501.         if (!Config.STORE_SKILL_COOLTIME)
  6502.  
  6503.             return;
  6504.  
  6505.         java.sql.Connection con = null;
  6506.         try
  6507.         {
  6508.             con = L2DatabaseFactory.getInstance().getConnection();
  6509.             PreparedStatement statement;
  6510.  
  6511.             // Delete all current stored effects for char to avoid dupe
  6512.             statement = con.prepareStatement(DELETE_SKILL_SAVE);
  6513.             statement.setInt(1, getObjectId());
  6514.             statement.setInt(2, getClassIndex());
  6515.             statement.execute();
  6516.             statement.close();
  6517.  
  6518.  
  6519.             int buff_index = 0;
  6520.  
  6521.             // Store all effect data along with calulated remaining
  6522.  
  6523.             // reuse delays for matching skills. 'restore_type'= 0.
  6524.  
  6525.             statement = con.prepareStatement(ADD_SKILL_SAVE);
  6526.  
  6527.  
  6528.             List<Integer> storedSkills = new FastList<>();
  6529.  
  6530.             if (storeEffects)
  6531.             {
  6532.                 for (L2Effect effect : getAllEffects())
  6533.                 {
  6534.  
  6535.                     if (effect == null)
  6536.                         continue;
  6537.  
  6538.                     L2Skill skill = effect.getSkill();
  6539.  
  6540.                     int skillId = skill.getId();
  6541.  
  6542.  
  6543.                     if (storedSkills.contains(skillId))
  6544.  
  6545.                         continue;
  6546.  
  6547.  
  6548.                     storedSkills.add(skillId);
  6549.  
  6550.  
  6551.                     if (effect != null && effect.getInUse() && !skill.isToggle())
  6552.                     {
  6553.  
  6554.                         buff_index++;
  6555.  
  6556.  
  6557.                         statement.setInt(1, getObjectId());
  6558.                         statement.setInt(2, skillId);
  6559.                         statement.setInt(3, skill.getLevel());
  6560.                         statement.setInt(4, effect.getCount());
  6561.                         statement.setInt(5, effect.getTime());
  6562.  
  6563.                         if (_reuseTimeStamps.containsKey(skillId))
  6564.  
  6565.                         {
  6566.  
  6567.                             TimeStamp t = _reuseTimeStamps.get(skillId);
  6568.  
  6569.                             statement.setLong(6, t.hasNotPassed() ? t.getReuse() : 0);
  6570.  
  6571.                             statement.setDouble(7, t.hasNotPassed() ? t.getStamp() : 0);
  6572.  
  6573.                         }
  6574.  
  6575.                         else
  6576.  
  6577.                         {
  6578.  
  6579.                             statement.setLong(6, 0);
  6580.  
  6581.                             statement.setDouble(7, 0);
  6582.  
  6583.                         }
  6584.  
  6585.  
  6586.                         statement.setInt(8, 0);
  6587.  
  6588.                         statement.setInt(9, getClassIndex());
  6589.  
  6590.                         statement.setInt(10, buff_index);
  6591.                         statement.execute();
  6592.  
  6593.                     }
  6594.                 }
  6595.             }
  6596.  
  6597.  
  6598.             // Store the reuse delays of remaining skills which
  6599.  
  6600.             // lost effect but still under reuse delay. 'restore_type' 1.
  6601.  
  6602.             for (TimeStamp t : _reuseTimeStamps.values())
  6603.  
  6604.             {
  6605.  
  6606.                 if (t.hasNotPassed())
  6607.  
  6608.                 {
  6609.  
  6610.                     int skillId = t.getSkillId();
  6611.  
  6612.  
  6613.                     if (storedSkills.contains(skillId))
  6614.  
  6615.                         continue;
  6616.  
  6617.  
  6618.                     storedSkills.add(skillId);
  6619.  
  6620.  
  6621.                     buff_index++;
  6622.  
  6623.  
  6624.                     statement.setInt(1, getObjectId());
  6625.  
  6626.                     statement.setInt(2, skillId);
  6627.  
  6628.                     statement.setInt(3, -1);
  6629.  
  6630.                     statement.setInt(4, -1);
  6631.  
  6632.                     statement.setInt(5, -1);
  6633.  
  6634.                     statement.setLong(6, t.getReuse());
  6635.  
  6636.                     statement.setDouble(7, t.getStamp());
  6637.  
  6638.                     statement.setInt(8, 1);
  6639.  
  6640.                     statement.setInt(9, getClassIndex());
  6641.  
  6642.                     statement.setInt(10, buff_index);
  6643.  
  6644.                     statement.execute();
  6645.  
  6646.                 }
  6647.  
  6648.             }
  6649.  
  6650.             statement.close();
  6651.  
  6652.         }
  6653.         catch (Exception e)
  6654.  
  6655.         {
  6656.  
  6657.             _log.warning("Could not store char effect data: "+ e);
  6658.  
  6659.         }
  6660.         finally
  6661.  
  6662.         {
  6663.  
  6664.             try
  6665.  
  6666.             {
  6667.  
  6668.                 con.close();
  6669.  
  6670.             }
  6671.  
  6672.             catch (Exception e) {}
  6673.  
  6674.         }
  6675.     }
  6676.  
  6677.     private void restoreFriends()
  6678.     {
  6679.         java.sql.Connection con = null;
  6680.  
  6681.         try
  6682.  
  6683.         {
  6684.             con = L2DatabaseFactory.getInstance().getConnection();
  6685.             PreparedStatement statement;
  6686.             statement = con.prepareStatement("SELECT character_friends.friend_id, characters.char_name, characters.online FROM character_friends, characters WHERE character_friends.char_id=? AND character_friends.friend_id = characters.obj_Id ORDER BY characters.char_name ASC");
  6687.             statement.setInt(1, getObjectId());
  6688.             ResultSet rset = statement.executeQuery();
  6689.  
  6690.  
  6691.             while (rset.next())
  6692.             {
  6693.                 int friendId = rset.getInt("friend_id");
  6694.                 String friendName = rset.getString("char_name");
  6695.                 int online = rset.getInt("online");
  6696.  
  6697.                 Friend friend = new Friend(friendId, friendName);
  6698.                 friend.setOnline(online);
  6699.  
  6700.                 getFriendList().add(friend);
  6701.             }
  6702.  
  6703.             rset.close();
  6704.             statement.close();
  6705.         }
  6706.         catch (Exception e)
  6707.         {
  6708.             _log.warning("could not restore friend data:"+e);
  6709.         }
  6710.         finally
  6711.         {
  6712.             try
  6713.             {
  6714.                 con.close();
  6715.             }
  6716.             catch (Exception e) {}
  6717.         }
  6718.     }
  6719.  
  6720.     private void notifyFriends()
  6721.     {
  6722.         SystemMessage sm = new SystemMessage(SystemMessage.FRIEND_S1_HAS_LOGGED_IN);
  6723.         sm.addString(getName());
  6724.  
  6725.         for (Friend friend : getFriendList())
  6726.         {
  6727.             if (friend == null)
  6728.                 continue;
  6729.  
  6730.             // notify online friends
  6731.             if (friend.isOnline() == 1)
  6732.             {
  6733.                 L2PcInstance friendChar = L2World.getInstance().getPlayer(friend.getName());
  6734.                 if (friendChar == null)
  6735.                     return;
  6736.  
  6737.                 friendChar.sendPacket(new FriendList(this));
  6738.                 // friend logged in
  6739.                 if (isOnline() == 1)
  6740.                     friendChar.sendPacket(sm);
  6741.             }
  6742.         }
  6743.         sm = null;
  6744.     }
  6745.  
  6746.     /**
  6747.      * Return True if the L2PcInstance is on line.<BR><BR>
  6748.      */
  6749.     public int isOnline()
  6750.     {
  6751.         return (_isOnline ? 1 : 0);
  6752.     }
  6753.  
  6754.  
  6755.     /**
  6756.      * Add a skill to the L2PcInstance _skills and its Func objects to the calculator set of the L2PcInstance and save update in the character_skills table of the database.<BR><BR>
  6757.      *
  6758.      * <B><U> Concept</U> :</B><BR><BR>
  6759.      * All skills own by a L2PcInstance are identified in <B>_skills</B><BR><BR>
  6760.      *
  6761.      * <B><U> Actions</U> :</B><BR><BR>
  6762.      * <li>Replace oldSkill by newSkill or Add the newSkill </li>
  6763.      * <li>If an old skill has been replaced, remove all its Func objects of L2Character calculator set</li>
  6764.      * <li>Add Func objects of newSkill to the calculator set of the L2Character </li><BR><BR>
  6765.      *
  6766.      * @param newSkill The L2Skill to add to the L2Character
  6767.      *
  6768.      * @return The L2Skill replaced or null if just added a new L2Skill
  6769.      *
  6770.      */
  6771.     public L2Skill addSkill(L2Skill newSkill, boolean store)
  6772.     {
  6773.         // Add a skill to the L2PcInstance _skills and its Func objects to the calculator set of the L2PcInstance
  6774.         L2Skill oldSkill = super.addSkill(newSkill);
  6775.  
  6776.         // Add or update a L2PcInstance skill in the character_skills table of the database
  6777.         if (store)
  6778.             storeSkill(newSkill, oldSkill, -1);
  6779.  
  6780.         return oldSkill;
  6781.     }
  6782.  
  6783.     /**
  6784.      * Remove a skill from the L2Character and its Func objects from calculator set of the L2Character and save update in the character_skills table of the database.<BR><BR>
  6785.      *
  6786.      * <B><U> Concept</U> :</B><BR><BR>
  6787.      * All skills own by a L2Character are identified in <B>_skills</B><BR><BR>
  6788.      *
  6789.      * <B><U> Actions</U> :</B><BR><BR>
  6790.      * <li>Remove the skill from the L2Character _skills </li>
  6791.      * <li>Remove all its Func objects from the L2Character calculator set</li><BR><BR>
  6792.      *
  6793.      * <B><U> Overriden in </U> :</B><BR><BR>
  6794.      * <li> L2PcInstance : Save update in the character_skills table of the database</li><BR><BR>
  6795.      *
  6796.      * @param skill The L2Skill to remove from the L2Character
  6797.      *
  6798.      * @return The L2Skill removed
  6799.      *
  6800.      */
  6801.     public L2Skill removeSkill(L2Skill skill)
  6802.     {
  6803.         // Remove a skill from the L2Character and its Func objects from calculator set of the L2Character
  6804.         L2Skill oldSkill = super.removeSkill(skill);
  6805.  
  6806.         java.sql.Connection con = null;
  6807.         try
  6808.         {
  6809.             // Remove or update a L2PcInstance skill from the character_skills table of the database
  6810.             con = L2DatabaseFactory.getInstance().getConnection();
  6811.             PreparedStatement statement;
  6812.  
  6813.             if (oldSkill != null)
  6814.             {
  6815.                 statement = con.prepareStatement(DELETE_SKILL_FROM_CHAR);
  6816.                 statement.setInt(1, oldSkill.getId());
  6817.                 statement.setInt(2, getObjectId());
  6818.                 statement.setInt(3, getClassIndex());
  6819.                 statement.execute();
  6820.                 statement.close();
  6821.             }
  6822.         }
  6823.         catch (Exception e)
  6824.         {
  6825.             _log.warning("Error could not delete skill: " + e);
  6826.         }
  6827.         finally
  6828.         {
  6829.             try
  6830.             {
  6831.                 con.close();
  6832.             }
  6833.             catch (Exception e) {}
  6834.         }
  6835.  
  6836.         for (L2ShortCut sc : getAllShortCuts())
  6837.         {
  6838.             if (sc == null)
  6839.                 continue;
  6840.  
  6841.             if (skill != null && sc.getId() == skill.getId() && sc.getType() == L2ShortCut.TYPE_SKILL)
  6842.                 deleteShortCut(sc.getSlot(), sc.getPage());
  6843.         }
  6844.  
  6845.         return oldSkill;
  6846.     }
  6847.  
  6848.     /**
  6849.      * Add or update a L2PcInstance skill in the character_skills table of the database.
  6850.      * <BR><BR>
  6851.      * If newClassIndex > -1, the skill will be stored with that class index, not the current one.
  6852.      */
  6853.     private void storeSkill(L2Skill newSkill, L2Skill oldSkill, int newClassIndex)
  6854.     {
  6855.         int classIndex = _classIndex;
  6856.  
  6857.         if (newClassIndex > -1)
  6858.             classIndex = newClassIndex;
  6859.  
  6860.         java.sql.Connection con = null;
  6861.         try
  6862.         {
  6863.             con = L2DatabaseFactory.getInstance().getConnection();
  6864.             PreparedStatement statement;
  6865.  
  6866.             if (oldSkill != null && newSkill != null)
  6867.             {
  6868.                 if (Config.KEEP_SUBCLASS_SKILLS)
  6869.                 {
  6870.                     statement = con.prepareStatement("UPDATE character_skills SET skill_level=? WHERE skill_id=? AND char_obj_id=?");
  6871.                     statement.setInt(1, newSkill.getLevel());
  6872.                     statement.setInt(2, oldSkill.getId());
  6873.                     statement.setInt(3, getObjectId());
  6874.                 }
  6875.                 else
  6876.                 {
  6877.                     statement = con.prepareStatement(UPDATE_CHARACTER_SKILL_LEVEL);
  6878.                     statement.setInt(1, newSkill.getLevel());
  6879.                     statement.setInt(2, oldSkill.getId());
  6880.                     statement.setInt(3, getObjectId());
  6881.                     statement.setInt(4, classIndex);
  6882.                 }
  6883.                 statement.execute();
  6884.                 statement.close();
  6885.             }
  6886.             else if (newSkill != null)
  6887.             {
  6888.                 statement = con.prepareStatement(ADD_NEW_SKILL);
  6889.                 statement.setInt(1, getObjectId());
  6890.                 statement.setInt(2, newSkill.getId());
  6891.                 statement.setInt(3, newSkill.getLevel());
  6892.                 statement.setString(4, newSkill.getName());
  6893.                 statement.setInt(5, classIndex);
  6894.                 statement.execute();
  6895.                 statement.close();
  6896.             }
  6897.             else
  6898.                 _log.warning("could not store new skill. its NULL");
  6899.         }
  6900.         catch (Exception e)
  6901.         {
  6902.             _log.warning("Error could not store char skills: " + e);
  6903.         }
  6904.         finally
  6905.         {
  6906.             try
  6907.             {
  6908.                 con.close();
  6909.             }
  6910.             catch (Exception e) {}
  6911.         }
  6912.     }
  6913.  
  6914.     /**
  6915.      * Retrieve from the database all skills of this L2PcInstance and add them to _skills.<BR><BR>
  6916.      */
  6917.     private void restoreSkills()
  6918.     {
  6919.         java.sql.Connection con = null;
  6920.         try
  6921.         {
  6922.             if (Config.KEEP_SUBCLASS_SKILLS)
  6923.             {
  6924.                 // Retrieve all skills of this L2PcInstance from the database
  6925.                 con = L2DatabaseFactory.getInstance().getConnection();
  6926.                 PreparedStatement statement = con.prepareStatement(RESTORE_SKILLS_FOR_CHAR_ALT_SUBCLASS);
  6927.                 statement.setInt(1, getObjectId());
  6928.                 ResultSet rset = statement.executeQuery();
  6929.  
  6930.                 // Go though the recordset of this SQL query
  6931.                 while (rset.next())
  6932.                 {
  6933.                     int id = rset.getInt("skill_id");
  6934.                     int level = rset.getInt("skill_level");
  6935.  
  6936.                     if (id > 9000)
  6937.                         continue; // fake skills for base stats
  6938.  
  6939.                     // Create a L2Skill object for each record
  6940.                     L2Skill skill = SkillTable.getInstance().getInfo(id, level);
  6941.  
  6942.                     // Add the L2Skill object to the L2Character _skills and its Func objects to the calculator set of the L2Character
  6943.                     super.addSkill(skill);
  6944.                 }
  6945.  
  6946.                 rset.close();
  6947.                 statement.close();
  6948.             }
  6949.             else
  6950.             {
  6951.                 // Retrieve all skills of this L2PcInstance from the database
  6952.                 con = L2DatabaseFactory.getInstance().getConnection();
  6953.                 PreparedStatement statement = con.prepareStatement(RESTORE_SKILLS_FOR_CHAR);
  6954.                 statement.setInt(1, getObjectId());
  6955.                 statement.setInt(2, getClassIndex());
  6956.                 ResultSet rset = statement.executeQuery();
  6957.  
  6958.                 // Go though the recordset of this SQL query
  6959.                 while (rset.next())
  6960.                 {
  6961.                     int id = rset.getInt("skill_id");
  6962.                     int level = rset.getInt("skill_level");
  6963.  
  6964.                     if (id > 9000)
  6965.                         continue; // fake skills for base stats
  6966.  
  6967.                     // Create a L2Skill object for each record
  6968.                     L2Skill skill = SkillTable.getInstance().getInfo(id, level);
  6969.  
  6970.                     // Add the L2Skill object to the L2Character _skills and its Func objects to the calculator set of the L2Character
  6971.                     super.addSkill(skill);
  6972.  
  6973.                     if (Config.SKILL_CHECK_ENABLE && !isGM())
  6974.                     {
  6975.                         if (!SkillTreeTable.getInstance().isSkillAllowed(this, skill))
  6976.                         {
  6977.                             removeSkill(skill);
  6978.                             _log.warning("Removed invalid skill " + skill.getName() + " ("+skill.getId() + "/" + skill.getLevel() + ") from player " + getName() + " with class:" + getTemplate().className);
  6979.                         }
  6980.                     }
  6981.                 }
  6982.  
  6983.                 rset.close();
  6984.                 statement.close();
  6985.             }
  6986.         }
  6987.         catch (Exception e)
  6988.         {
  6989.             _log.warning("Could not restore character skills: " + e);
  6990.         }
  6991.         finally
  6992.         {
  6993.             try
  6994.             {
  6995.                 con.close();
  6996.             }
  6997.             catch (Exception e) {}
  6998.         }
  6999.     }
  7000.  
  7001.  
  7002.     /**
  7003.      * Retrieve from the database all skill effects of this L2PcInstance and add them to the player.<BR><BR>
  7004.      */
  7005.     public void restoreEffects()
  7006.     {
  7007.         java.sql.Connection con = null;
  7008.         try
  7009.         {
  7010.             con = L2DatabaseFactory.getInstance().getConnection();
  7011.             PreparedStatement statement;
  7012.             ResultSet rset;
  7013.  
  7014.  
  7015.             /**
  7016.  
  7017.              *  Restore Type 0
  7018.  
  7019.              *  These skill were still in effect on the character
  7020.  
  7021.              *  upon logout. Some of which were self casted and
  7022.  
  7023.              *  might still have had a long reuse delay which also
  7024.  
  7025.              *  is restored.
  7026.  
  7027.              */
  7028.             statement = con.prepareStatement(RESTORE_SKILL_SAVE);
  7029.             statement.setInt(1, getObjectId());
  7030.             statement.setInt(2, getClassIndex());
  7031.  
  7032.             statement.setInt(3, 0);
  7033.  
  7034.             rset = statement.executeQuery();
  7035.  
  7036.             while (rset.next())
  7037.             {
  7038.                 int skillId = rset.getInt("skill_id");
  7039.                 int skillLvl = rset.getInt("skill_level");
  7040.                 int effectCount = rset.getInt("effect_count");
  7041.                 int effectCurTime = rset.getInt("effect_cur_time");
  7042.  
  7043.                 double reuseDelay = rset.getInt("reuse_delay");
  7044.  
  7045.                 double systime = rset.getDouble("systime");
  7046.  
  7047.  
  7048.                 double remainingTime = systime - System.currentTimeMillis();
  7049.  
  7050.  
  7051.                 // Just incase the admin minipulated this table incorrectly :x
  7052.  
  7053.                 if (skillId == -1 || effectCount == -1 || effectCurTime == -1 || reuseDelay < 0)
  7054.                     continue;
  7055.  
  7056.                 L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);
  7057.  
  7058.  
  7059.  
  7060.                 if (remainingTime > 10)
  7061.  
  7062.                 {
  7063.  
  7064.                     disableSkill(skillId, (long)reuseDelay);
  7065.  
  7066.                     addTimeStamp(new TimeStamp(skillId, (long)remainingTime, (long)systime));
  7067.  
  7068.                 }
  7069.  
  7070.                 for (L2Effect effect : skill.getEffects(this, this, false))
  7071.  
  7072.                 {
  7073.  
  7074.                     effect.setCount(effectCount);
  7075.  
  7076.                     effect.setFirstTime(effectCurTime);
  7077.  
  7078.                 }
  7079.             }
  7080.  
  7081.             rset.close();
  7082.  
  7083.             statement.close();
  7084.  
  7085.  
  7086.             /**
  7087.  
  7088.              * Restore Type 1
  7089.  
  7090.              * The remaning skills lost effect upon logout but
  7091.  
  7092.              * were still under a high reuse delay.
  7093.  
  7094.              */
  7095.             if (Config.KEEP_SUBCLASS_SKILLS)
  7096.             {
  7097.                 statement = con.prepareStatement(RESTORE_SKILL_SAVE_ALT_SUBCLASS);
  7098.  
  7099.                 statement.setInt(1, getObjectId());
  7100.  
  7101.                 statement.setInt(2, 1);
  7102.             }
  7103.             else
  7104.             {
  7105.  
  7106.                 statement = con.prepareStatement(RESTORE_SKILL_SAVE);
  7107.  
  7108.                 statement.setInt(1, getObjectId());
  7109.  
  7110.                 statement.setInt(2, getClassIndex());
  7111.  
  7112.                 statement.setInt(3, 1);
  7113.             }
  7114.  
  7115.             rset = statement.executeQuery();
  7116.  
  7117.  
  7118.             while (rset.next())
  7119.  
  7120.             {
  7121.  
  7122.                 int skillId = rset.getInt("skill_id");
  7123.  
  7124.                 double reuseDelay = rset.getDouble("reuse_delay");
  7125.  
  7126.                 double systime = rset.getDouble("systime");
  7127.  
  7128.  
  7129.                 double remainingTime = systime - System.currentTimeMillis();
  7130.  
  7131.  
  7132.                 if (remainingTime < 10)
  7133.  
  7134.                     continue;
  7135.  
  7136.  
  7137.                 disableSkill(skillId, (long)remainingTime);
  7138.  
  7139.                 addTimeStamp(new TimeStamp(skillId, (long)reuseDelay, (long)systime));
  7140.  
  7141.             }
  7142.  
  7143.             rset.close();
  7144.  
  7145.             statement.close();
  7146.  
  7147.             statement = con.prepareStatement(DELETE_SKILL_SAVE);
  7148.             statement.setInt(1, getObjectId());
  7149.             statement.setInt(2, getClassIndex());
  7150.             statement.executeUpdate();
  7151.  
  7152.             statement.close();
  7153.         }
  7154.         catch (Exception e)
  7155.         {
  7156.             _log.warning("Could not restore active effect data: " + e);
  7157.         }
  7158.         finally
  7159.  
  7160.         {
  7161.             try
  7162.             {
  7163.                 con.close();
  7164.             }
  7165.             catch (Exception e) {}
  7166.         }
  7167.     }
  7168.  
  7169.     /**
  7170.      * Retrieve from the database all Henna of this L2PcInstance, add them to _henna and calculate stats of the L2PcInstance.<BR><BR>
  7171.      */
  7172.     private void restoreHenna()
  7173.     {
  7174.         java.sql.Connection con = null;
  7175.         try
  7176.         {
  7177.             con = L2DatabaseFactory.getInstance().getConnection();
  7178.             PreparedStatement statement = con.prepareStatement(RESTORE_CHAR_HENNAS);
  7179.             statement.setInt(1, getObjectId());
  7180.             statement.setInt(2, getClassIndex());
  7181.             ResultSet rset = statement.executeQuery();
  7182.  
  7183.             for (int i=0;i<3;i++)
  7184.                 _henna[i]=null;
  7185.  
  7186.             while (rset.next())
  7187.             {
  7188.                 int slot = rset.getInt("slot");
  7189.                 if (slot<1 || slot>3)
  7190.  
  7191.                     continue;
  7192.  
  7193.                 int symbol_id = rset.getInt("symbol_id");
  7194.  
  7195.                 L2HennaInstance sym = null;
  7196.  
  7197.                 if (symbol_id != 0)
  7198.                 {
  7199.                     L2Henna tpl = HennaTable.getInstance().getTemplate(symbol_id);
  7200.  
  7201.                     if (tpl != null)
  7202.                     {
  7203.                         sym = new L2HennaInstance(tpl);
  7204.                         _henna[slot-1] = sym;
  7205.                     }
  7206.                 }
  7207.             }
  7208.  
  7209.             rset.close();
  7210.             statement.close();
  7211.         }
  7212.         catch (Exception e)
  7213.         {
  7214.             _log.warning("could not restore henna: "+e);
  7215.         }
  7216.         finally
  7217.         {
  7218.             try
  7219.             {
  7220.                 con.close();
  7221.             }
  7222.             catch (Exception e) {}
  7223.         }
  7224.  
  7225.         // Calculate Henna modifiers of this L2PcInstance
  7226.         recalcHennaStats();
  7227.     }
  7228.  
  7229.     /**
  7230.      * Retrieve from the database all Recommendation data of this L2PcInstance, add to _recomChars and calculate stats of the L2PcInstance.<BR><BR>
  7231.      */
  7232.     private void restoreRecom()
  7233.     {
  7234.         java.sql.Connection con = null;
  7235.         try
  7236.         {
  7237.             con = L2DatabaseFactory.getInstance().getConnection();
  7238.             PreparedStatement statement = con.prepareStatement(RESTORE_CHAR_RECOMS);
  7239.             statement.setInt(1, getObjectId());
  7240.             ResultSet rset = statement.executeQuery();
  7241.             while (rset.next())
  7242.             {
  7243.                 _recomChars.add(rset.getInt("target_id"));
  7244.             }
  7245.  
  7246.             rset.close();
  7247.             statement.close();
  7248.         }
  7249.         catch (Exception e)
  7250.         {
  7251.             _log.warning("could not restore recommendations: "+e);
  7252.         }
  7253.         finally
  7254.         {
  7255.             try
  7256.             {
  7257.                 con.close();
  7258.             }
  7259.             catch (Exception e) {}
  7260.         }
  7261.     }
  7262.  
  7263.     /**
  7264.      * Return the number of Henna empty slot of the L2PcInstance.<BR><BR>
  7265.      */
  7266.     public int getHennaEmptySlots()
  7267.     {
  7268.         int totalSlots = 1 + getClassId().level();
  7269.  
  7270.         for (int i = 0; i < 3; i++)
  7271.         {
  7272.             if (_henna[i] != null)
  7273.  
  7274.                 totalSlots--;
  7275.         }
  7276.  
  7277.         if (totalSlots <= 0)
  7278.  
  7279.             return 0;
  7280.  
  7281.         return totalSlots;
  7282.     }
  7283.  
  7284.     /**
  7285.      * Remove a Henna of the L2PcInstance, save update in the character_hennas table of the database and send Server->Client HennaInfo/UserInfo packet to this L2PcInstance.<BR><BR>
  7286.      */
  7287.     public boolean removeHenna(int slot)
  7288.     {
  7289.         if (slot < 1 || slot > 3)
  7290.             return false;
  7291.  
  7292.         slot--;
  7293.  
  7294.         if (_henna[slot]==null)
  7295.             return false;
  7296.  
  7297.         L2HennaInstance henna = _henna[slot];
  7298.         _henna[slot] = null;
  7299.  
  7300.         java.sql.Connection con = null;
  7301.  
  7302.         try
  7303.         {
  7304.             con = L2DatabaseFactory.getInstance().getConnection();
  7305.             PreparedStatement statement = con.prepareStatement(DELETE_CHAR_HENNA);
  7306.             statement.setInt(1, getObjectId());
  7307.             statement.setInt(2, slot+1);
  7308.             statement.setInt(3, getClassIndex());
  7309.             statement.execute();
  7310.             statement.close();
  7311.         }
  7312.         catch (Exception e)
  7313.         {
  7314.             _log.warning("could not remove char henna: "+e);
  7315.         }
  7316.         finally
  7317.         {
  7318.             try
  7319.             {
  7320.                 con.close();
  7321.             }
  7322.             catch (Exception e) {}
  7323.         }
  7324.  
  7325.         // Calculate Henna modifiers of this L2PcInstance
  7326.         recalcHennaStats();
  7327.  
  7328.         // Send Server->Client HennaInfo packet to this L2PcInstance
  7329.         sendPacket(new HennaInfo(this));
  7330.  
  7331.         // Send Server->Client UserInfo packet to this L2PcInstance
  7332.         sendPacket(new UserInfo(this));
  7333.  
  7334.         // Add the recovered dyes to the player's inventory and notify them.
  7335.         getInventory().addItem("Henna", henna.getItemIdDye(), henna.getAmountDyeRequire() / 2, this, null);
  7336.  
  7337.  
  7338.         SystemMessage sm = new SystemMessage(SystemMessage.EARNED_S2_S1_s);
  7339.  
  7340.         sm.addItemName(henna.getItemIdDye());
  7341.  
  7342.         sm.addNumber(henna.getAmountDyeRequire() / 2);
  7343.         sendPacket(sm);
  7344.  
  7345.         return true;
  7346.     }
  7347.  
  7348.     /**
  7349.      * Add a Henna to the L2PcInstance, save update in the character_hennas table of the database and send Server->Client HennaInfo/UserInfo packet to this L2PcInstance.<BR><BR>
  7350.      */
  7351.     public boolean addHenna(L2HennaInstance henna)
  7352.     {
  7353.         if (getHennaEmptySlots() == 0)
  7354.         {
  7355.             sendMessage("You may not have more than three equipped symbols at a time.");
  7356.             return false;
  7357.         }
  7358.  
  7359.  
  7360.         for (int i=0;i<3;i++)
  7361.         {
  7362.             if (_henna[i]==null)
  7363.             {
  7364.                 _henna[i]=henna;
  7365.  
  7366.                 // Calculate Henna modifiers of this L2PcInstance
  7367.                 recalcHennaStats();
  7368.  
  7369.                 java.sql.Connection con = null;
  7370.                 try
  7371.                 {
  7372.                     con = L2DatabaseFactory.getInstance().getConnection();
  7373.                     PreparedStatement statement = con.prepareStatement(ADD_CHAR_HENNA);
  7374.                     statement.setInt(1, getObjectId());
  7375.                     statement.setInt(2, henna.getSymbolId());
  7376.                     statement.setInt(3, i+1);
  7377.                     statement.setInt(4, getClassIndex());
  7378.                     statement.execute();
  7379.                     statement.close();
  7380.                 }
  7381.                 catch (Exception e)
  7382.                 {
  7383.                     _log.warning("could not save char henna: "+e);
  7384.                 }
  7385.                 finally
  7386.                 {
  7387.                     try
  7388.                     {
  7389.                         con.close();
  7390.                     }
  7391.                     catch (Exception e) {}
  7392.                 }
  7393.  
  7394.                 // Send Server->Client HennaInfo packet to this L2PcInstance
  7395.                 HennaInfo hi = new HennaInfo(this);
  7396.                 sendPacket(hi);
  7397.  
  7398.                 // Send Server->Client UserInfo packet to this L2PcInstance
  7399.                 UserInfo ui = new UserInfo(this);
  7400.                 sendPacket(ui);
  7401.  
  7402.                 return true;
  7403.             }
  7404.         }
  7405.  
  7406.         return false;
  7407.     }
  7408.  
  7409.     /**
  7410.      * Calculate Henna modifiers of this L2PcInstance.<BR><BR>
  7411.      */
  7412.     private void recalcHennaStats()
  7413.     {
  7414.         _hennaINT = 0;
  7415.         _hennaSTR = 0;
  7416.         _hennaCON = 0;
  7417.         _hennaMEN = 0;
  7418.         _hennaWIT = 0;
  7419.         _hennaDEX = 0;
  7420.  
  7421.         for (int i=0;i<3;i++)
  7422.         {
  7423.             if (_henna[i]==null)
  7424.                 continue;
  7425.  
  7426.             _hennaINT += _henna[i].getStatINT();
  7427.             _hennaSTR += _henna[i].getStatSTR();
  7428.             _hennaMEN += _henna[i].getStatMEN();
  7429.             _hennaCON += _henna[i].getStatCON();
  7430.             _hennaWIT += _henna[i].getStatWIT();
  7431.             _hennaDEX += _henna[i].getStatDEX();
  7432.         }
  7433.  
  7434.         if (_hennaINT > 5)
  7435.             _hennaINT=5;
  7436.         if (_hennaSTR > 5)
  7437.             _hennaSTR=5;
  7438.         if (_hennaMEN > 5)
  7439.             _hennaMEN=5;
  7440.         if (_hennaCON > 5)
  7441.             _hennaCON=5;
  7442.         if (_hennaWIT > 5)
  7443.             _hennaWIT=5;
  7444.         if (_hennaDEX > 5)
  7445.             _hennaDEX=5;
  7446.     }
  7447.  
  7448.     /**
  7449.      * Return the Henna of this L2PcInstance corresponding to the selected slot.<BR><BR>
  7450.      */
  7451.     public L2HennaInstance getHenna(int slot)
  7452.     {
  7453.         if (slot < 1 || slot > 3)
  7454.             return null;
  7455.  
  7456.  
  7457.         return _henna[slot - 1];
  7458.     }
  7459.  
  7460.     /**
  7461.      * Return the INT Henna modifier of this L2PcInstance.<BR><BR>
  7462.      */
  7463.     public int getHennaStatINT()
  7464.     {
  7465.         return _hennaINT;
  7466.     }
  7467.  
  7468.     /**
  7469.      * Return the STR Henna modifier of this L2PcInstance.<BR><BR>
  7470.      */
  7471.     public int getHennaStatSTR()
  7472.     {
  7473.         return _hennaSTR;
  7474.     }
  7475.  
  7476.     /**
  7477.      * Return the CON Henna modifier of this L2PcInstance.<BR><BR>
  7478.      */
  7479.     public int getHennaStatCON()
  7480.     {
  7481.         return _hennaCON;
  7482.     }
  7483.  
  7484.     /**
  7485.      * Return the MEN Henna modifier of this L2PcInstance.<BR><BR>
  7486.      */
  7487.     public int getHennaStatMEN()
  7488.     {
  7489.         return _hennaMEN;
  7490.     }
  7491.  
  7492.     /**
  7493.      * Return the WIT Henna modifier of this L2PcInstance.<BR><BR>
  7494.      */
  7495.     public int getHennaStatWIT()
  7496.     {
  7497.         return _hennaWIT;
  7498.     }
  7499.  
  7500.     /**
  7501.      * Return the DEX Henna modifier of this L2PcInstance.<BR><BR>
  7502.      */
  7503.     public int getHennaStatDEX()
  7504.     {
  7505.         return _hennaDEX;
  7506.     }
  7507.  
  7508.     /**
  7509.      * Return True if the L2PcInstance is autoAttackable.<BR><BR>
  7510.      *
  7511.      * <B><U> Actions</U> :</B><BR><BR>
  7512.      * <li>Check if the attacker isn't the L2PcInstance Pet </li>
  7513.      * <li>Check if the attacker is L2MonsterInstance</li>
  7514.      * <li>If the attacker is a L2PcInstance, check if it is not in the same party </li>
  7515.      * <li>Check if the L2PcInstance has Karma </li>
  7516.      * <li>If the attacker is a L2PcInstance, check if it is not in the same siege clan (Attacker, Defender) </li><BR><BR>
  7517.      *
  7518.      */
  7519.     public boolean isAutoAttackable(L2Character attacker)
  7520.     {
  7521.         // Check if the attacker isn't the L2PcInstance Pet
  7522.         if (attacker == this || attacker == getPet())
  7523.             return false;
  7524.  
  7525.         // TODO: check for friendly mobs
  7526.         // Check if the attacker is a L2MonsterInstance
  7527.         if (attacker instanceof L2MonsterInstance)
  7528.             return true;
  7529.  
  7530.         // Check if the attacker is not in the same party
  7531.         if (getParty() != null)
  7532.         {
  7533.             if (getParty().getPartyMembers().contains(attacker))
  7534.                 return false;
  7535.  
  7536.             if (attacker.getParty() != null)
  7537.             {
  7538.                 if (getParty().getCommandChannel() != null && attacker.getParty().getCommandChannel() != null)
  7539.                 {
  7540.                     if (getParty().getCommandChannel() == attacker.getParty().getCommandChannel())
  7541.                         return false;
  7542.                 }
  7543.             }
  7544.         }
  7545.  
  7546.         // Check if the attacker is in event, olympiad, and olympiad start
  7547.         if (attacker instanceof L2PcInstance)
  7548.         {
  7549.             if (((L2PcInstance)attacker).getEventTeam() > 0 && getEventTeam() > 0)
  7550.             {
  7551.                 if (((L2PcInstance)attacker).getEventTeam() == getEventTeam())
  7552.                     return false;
  7553.                 else
  7554.                     return true;
  7555.             }
  7556.  
  7557.             if (((L2PcInstance)attacker).isInOlympiadMode())
  7558.             {
  7559.                 if (isInOlympiadMode() && isOlympiadStart() && ((L2PcInstance)attacker).getOlympiadGameId() == getOlympiadGameId())
  7560.                     return true;
  7561.                 else
  7562.                     return false;
  7563.             }
  7564.         }
  7565.  
  7566.         // Check if the attacker is not in the same clan
  7567.         if (getClan() != null && attacker != null && getClan().isMember(attacker.getObjectId()))
  7568.             return false;
  7569.  
  7570.  
  7571.         if (attacker instanceof L2PlayableInstance && isInsideZone(ZONE_PEACE))
  7572.  
  7573.             return false;
  7574.  
  7575.         // Check if the L2PcInstance has Karma
  7576.         if (getKarma() > 0 || getPvpFlag() > 0)
  7577.             return true;
  7578.  
  7579.         L2PcInstance player = null;
  7580.         if (attacker instanceof L2PcInstance)
  7581.             player = (L2PcInstance)attacker;
  7582.         else if (attacker instanceof L2Summon)
  7583.             player = ((L2Summon)attacker).getOwner();
  7584.  
  7585.         // Check if the attacker is a L2PcInstance
  7586.         if (player != null)
  7587.         {
  7588.  
  7589.             // Check if the L2PcInstance is in an arena or a siege area
  7590.             if (isInsideZone(ZONE_PVP) && player.isInsideZone(ZONE_PVP))
  7591.  
  7592.                 return true;
  7593.  
  7594.             if (getClan() != null)
  7595.             {
  7596.                 Siege siege = SiegeManager.getInstance().getSiege(this);
  7597.                 if (siege != null)
  7598.                 {
  7599.                     // Check if a siege is in progress and if attacker and the L2PcInstance aren't in the Defender clan
  7600.                     if (siege.checkIsDefender(player.getClan())
  7601.                      && siege.checkIsDefender(getClan()))
  7602.                         return false;
  7603.  
  7604.                     // Check if a siege is in progress and if attacker and the L2PcInstance aren't in the Attacker clan
  7605.                     if (siege.checkIsAttacker(player.getClan())
  7606.                      && siege.checkIsAttacker(getClan()))
  7607.                         return false;
  7608.                 }
  7609.  
  7610.                 // Check if clan is at war
  7611.                 if (getClan() != null
  7612.                  && player.getClan() != null
  7613.                  && (getClan().isAtWarWith(player.getClanId())
  7614.                  && player.getClan().isAtWarWith(getClanId())
  7615.                  && getWantsPeace() == 0
  7616.                  && player.getWantsPeace() == 0))
  7617.                     return true;
  7618.             }
  7619.         }
  7620.         else if (attacker instanceof L2SiegeGuardInstance)
  7621.         {
  7622.             if (getClan() != null)
  7623.             {
  7624.                 Siege siege = SiegeManager.getInstance().getSiege(this);
  7625.                 return (siege != null && siege.checkIsAttacker(this.getClan()));
  7626.             }
  7627.         }
  7628.  
  7629.         return false;
  7630.     }
  7631.  
  7632.     /**
  7633.      * Check if the active L2Skill can be casted.<BR><BR>
  7634.      *
  7635.      * <B><U> Actions</U> :</B><BR><BR>
  7636.      * <li>Check if the skill isn't toggle and is offensive </li>
  7637.      * <li>Check if the target is in the skill cast range </li>
  7638.      * <li>Check if the skill is Spoil type and if the target isn't already spoiled </li>
  7639.      * <li>Check if the caster owns enought consummed Item, enough HP and MP to cast the skill </li>
  7640.      * <li>Check if the caster isn't sitting </li>
  7641.      * <li>Check if all skills are enabled and this skill is enabled </li><BR><BR>
  7642.      * <li>Check if the caster own the weapon needed </li><BR><BR>
  7643.      * <li>Check if the skill is active </li><BR><BR>
  7644.      * <li>Check if all casting conditions are completed</li><BR><BR>
  7645.      * <li>Notify the AI with AI_INTENTION_CAST and target</li><BR><BR>
  7646.      *
  7647.      * @param skill The L2Skill to use
  7648.      * @param forceUse used to force ATTACK on players
  7649.      * @param dontMove used to prevent movement, if not in range
  7650.      *
  7651.      */
  7652.     public void useMagic(L2Skill skill, boolean forceUse, boolean dontMove)
  7653.     {
  7654.         // Check if the skill is active
  7655.         if (skill.isPassive())
  7656.         {
  7657.             // just ignore the passive skill request. why does the client send it anyway ??
  7658.             // Send a Server->Client packet ActionFailed to the L2PcInstance
  7659.             sendPacket(new ActionFailed());
  7660.             return;
  7661.         }
  7662.  
  7663.         if (isDead())
  7664.         {
  7665.  
  7666.             sendPacket(new ActionFailed());
  7667.             abortCast();
  7668.             return;
  7669.         }
  7670.  
  7671.  
  7672.         if (isWearingFormalWear())
  7673.         {
  7674.             sendPacket(new SystemMessage(SystemMessage.CANNOT_USE_ITEMS_SKILLS_WITH_FORMALWEAR));
  7675.  
  7676.             sendPacket(new ActionFailed());
  7677.             abortCast();
  7678.             return;
  7679.         }
  7680.  
  7681.         if (inObserverMode())
  7682.         {
  7683.             sendPacket(new SystemMessage(SystemMessage.OBSERVERS_CANNOT_PARTICIPATE));
  7684.             sendPacket(new ActionFailed());
  7685.             abortCast();
  7686.  
  7687.             return;
  7688.         }
  7689.  
  7690.         // Check if the caster is sitting
  7691.         if (isSitting())
  7692.         {
  7693.             // Send a System Message to the caster
  7694.             sendPacket(new SystemMessage(SystemMessage.CANT_MOVE_SITTING));
  7695.  
  7696.  
  7697.             // Send a Server->Client packet ActionFailed to the L2PcInstance
  7698.             sendPacket(new ActionFailed());
  7699.             return;
  7700.         }
  7701.  
  7702.  
  7703.         // Check if the skill type is TOGGLE
  7704.         if (skill.isToggle())
  7705.         {
  7706.             // Get effects of the skill
  7707.  
  7708.             L2Effect effect = getEffect(skill);
  7709.             if (effect != null)
  7710.             {
  7711.                 SystemMessage sm = new SystemMessage(SystemMessage.S1_IS_ABORTED);
  7712.                 sm.addString(skill.getName());
  7713.                 sendPacket(sm);
  7714.  
  7715.                 effect.exit(); 
  7716.                 // Send a Server->Client packet ActionFailed to the L2PcInstance
  7717.                 sendPacket(new ActionFailed());
  7718.                 return;
  7719.             }
  7720.         }
  7721.  
  7722.  
  7723.         // Check if the player uses "Fake Death" skill
  7724.         if (isFakeDeath())
  7725.         {
  7726.             // Send a Server->Client packet ActionFailed to the L2PcInstance
  7727.             sendPacket(new ActionFailed());
  7728.             return;
  7729.         }
  7730.  
  7731.  
  7732.         //************************************* Check Casting in Progress *******************************************
  7733.  
  7734.  
  7735.         // If a skill is currently being used, queue this one if this is not the same
  7736.         // Note that this check is currently imperfect: getCurrentSkill() isn't always null when a skill has
  7737.         // failed to cast, or the casting is not yet in progress when this is rechecked
  7738.         if (getCurrentSkill() != null && isCastingNow())
  7739.         {
  7740.             // Check if new skill different from current skill in progress
  7741.             if (skill.getId() == getCurrentSkill().getSkillId())
  7742.             {
  7743.                 sendPacket(new ActionFailed());
  7744.                 return;
  7745.             }
  7746.  
  7747.  
  7748.             if (Config.DEBUG && getQueuedSkill() != null)
  7749.                 _log.info(getQueuedSkill().getSkill().getName() + " is already queued for " + getName() + ".");
  7750.  
  7751.  
  7752.  
  7753.             // Create a new SkillDat object and queue it in the player _queuedSkill
  7754.             if (isCastingNow())
  7755.                 setQueuedSkill(skill, forceUse, dontMove);
  7756.             sendPacket(new ActionFailed());
  7757.             return;
  7758.         }
  7759.  
  7760.  
  7761.         if (getQueuedSkill() != null) // wiping out previous values, after casting has been aborted
  7762.             setQueuedSkill(null, false, false);
  7763.  
  7764.  
  7765.         //************************************* Check Target *******************************************
  7766.  
  7767.  
  7768.         // Create and set a L2Object containing the target of the skill
  7769.         L2Object target = null;
  7770.  
  7771.         SkillTargetType sklTargetType = skill.getTargetType();
  7772.         SkillType sklType = skill.getSkillType();
  7773.  
  7774.  
  7775.         switch (sklTargetType)
  7776.         {
  7777.             // Target the player if skill type is AURA, PARTY, CLAN or SELF
  7778.             case TARGET_AURA:
  7779.             case TARGET_AURA_UNDEAD:
  7780.             case TARGET_PARTY:
  7781.             case TARGET_ALLY:
  7782.             case TARGET_CLAN:
  7783.             case TARGET_SELF:
  7784.                 target = this;
  7785.                 break;
  7786.             default:
  7787.                 target = skill.getFirstOfTargetList(this);
  7788.                 break;
  7789.         }
  7790.  
  7791.  
  7792.         // Check the validity of the target
  7793.         if (target == null)
  7794.         {
  7795.  
  7796.             sendPacket(new ActionFailed());
  7797.             return;
  7798.         }
  7799.  
  7800.  
  7801.         //************************************* Check skill availability *******************************************
  7802.  
  7803.         // Check if a skill is disabled while attacking
  7804.         if (isSkillDisabled(skill.getId()) && (isAttackingNow() || skill.getCastRange() < 0))
  7805.         {
  7806.             SystemMessage sm = new SystemMessage(SystemMessage.S1_PREPARED_FOR_REUSE);
  7807.             sm.addSkillName(skill.getId(),skill.getLevel());
  7808.             sendPacket(sm);
  7809.             return;
  7810.         }
  7811.  
  7812.         // Check if all skills are disabled
  7813.         if (isAllSkillsDisabled())
  7814.         {
  7815.             // Send a Server->Client packet ActionFailed to the L2PcInstance
  7816.             sendPacket(new ActionFailed());
  7817.             return;
  7818.         }
  7819.  
  7820.  
  7821.         //************************************* Check Consumables *******************************************
  7822.  
  7823.  
  7824.         // Check if the caster has enough MP
  7825.         if (getCurrentMp() < getStat().getMpConsume(skill) + getStat().getMpInitialConsume(skill))
  7826.         {
  7827.             // Send a System Message to the caster
  7828.             sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_MP));
  7829.  
  7830.  
  7831.             // Send a Server->Client packet ActionFailed to the L2PcInstance
  7832.             sendPacket(new ActionFailed());
  7833.             return;
  7834.         }
  7835.  
  7836.  
  7837.         // Check if the caster has enough HP
  7838.         if (getCurrentHp() <= skill.getHpConsume())
  7839.         {
  7840.             // Send a System Message to the caster
  7841.             sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_HP));
  7842.  
  7843.  
  7844.             // Send a Server->Client packet ActionFailed to the L2PcInstance
  7845.             sendPacket(new ActionFailed());
  7846.             return;
  7847.         }
  7848.  
  7849.  
  7850.         // Check if the spell consummes an Item
  7851.         if (skill.getItemConsume() > 0)
  7852.         {
  7853.             // Get the L2ItemInstance consummed by the spell
  7854.             L2ItemInstance requiredItems = getInventory().getItemByItemId(skill.getItemConsumeId());
  7855.  
  7856.  
  7857.             // Check if the caster owns enought consumed Item to cast
  7858.             if (requiredItems == null || requiredItems.getCount() < skill.getItemConsume())
  7859.             {
  7860.                 // Checked: when a summon skill failed, server show required consume item count
  7861.                 if (sklType == L2Skill.SkillType.SUMMON)
  7862.                 {
  7863.                     SystemMessage sm = new SystemMessage(SystemMessage.SUMMONING_SERVITOR_COSTS_S2_S1);
  7864.                     sm.addItemName(skill.getItemConsumeId());
  7865.                     sm.addNumber(skill.getItemConsume());
  7866.                     sendPacket(sm);
  7867.                     return;
  7868.  
  7869.                 }
  7870.                 else
  7871.                 {
  7872.                     // Send a System Message to the caster
  7873.                     sendPacket(new SystemMessage(SystemMessage.NOT_ENOUGH_ITEMS));
  7874.                     return;
  7875.                 }
  7876.             }
  7877.         }
  7878.  
  7879.  
  7880.         //************************************* Check Casting Conditions *******************************************
  7881.  
  7882.  
  7883.         // Check if the caster own the weapon needed
  7884.         if (!skill.getWeaponDependancy(this))
  7885.         {
  7886.             // Send a Server->Client packet ActionFailed to the L2PcInstance
  7887.             sendPacket(new ActionFailed());
  7888.             return;
  7889.         }
  7890.  
  7891.  
  7892.         // Check if all casting conditions are completed
  7893.         if (!skill.checkCondition(this, false))
  7894.         {
  7895.             // Send a Server->Client packet ActionFailed to the L2PcInstance
  7896.             sendPacket(new ActionFailed());
  7897.             return;
  7898.         }
  7899.  
  7900.  
  7901.         //************************************* Check Player State *******************************************
  7902.  
  7903.  
  7904.         // Abnormal effects(ex : Stun, Sleep...) are checked in L2Character useMagic()
  7905.  
  7906.  
  7907.         if (isFishing() && (sklType != SkillType.PUMPING && sklType != SkillType.REELING && sklType != SkillType.FISHING))
  7908.         {
  7909.             //Only fishing skills are available
  7910.             sendPacket(new SystemMessage(SystemMessage.ONLY_FISHING_SKILLS_NOW));
  7911.             return;
  7912.         }
  7913.  
  7914.  
  7915.         //************************************* Check Skill Type *******************************************
  7916.  
  7917.         // Check if this is offensive magic skill
  7918.         if (skill.isOffensive())
  7919.         {
  7920.             if ((isInsidePeaceZone(this, target)) && (getAccessLevel() < Config.GM_PEACEATTACK))
  7921.             {
  7922.                 // If L2Character or target is in a peace zone, send a system message TARGET_IN_PEACEZONE a Server->Client packet ActionFailed
  7923.                 sendPacket(new SystemMessage(SystemMessage.TARGET_IN_PEACEZONE));
  7924.                 sendPacket(new ActionFailed());
  7925.                 return;
  7926.             }
  7927.  
  7928.  
  7929.  
  7930.             if (isInOlympiadMode() && !isOlympiadStart())
  7931.             {
  7932.                 // if L2PcInstance is in Olympiad and the match isn't already start, send a Server->Client packet ActionFailed
  7933.                 sendPacket(new ActionFailed());
  7934.                 return;
  7935.             }
  7936.  
  7937.             // Check if the target is attackable
  7938.             if (!target.isAttackable() && (getAccessLevel() < Config.GM_PEACEATTACK))
  7939.             {
  7940.                 // If target is not attackable, send a Server->Client packet ActionFailed
  7941.                 sendPacket(new ActionFailed());
  7942.                 return;
  7943.             }
  7944.  
  7945.             // Check if a Forced ATTACK is in progress on non-attackable target
  7946.             if (!target.isAutoAttackable(this) && !forceUse &&
  7947.                   sklTargetType != SkillTargetType.TARGET_AURA &&
  7948.                   sklTargetType != SkillTargetType.TARGET_AURA_UNDEAD &&
  7949.                   sklTargetType != SkillTargetType.TARGET_CLAN &&
  7950.                   sklTargetType != SkillTargetType.TARGET_ALLY &&
  7951.                   sklTargetType != SkillTargetType.TARGET_PARTY &&
  7952.                   sklTargetType != SkillTargetType.TARGET_SELF)
  7953.             {
  7954.                 // Send a Server->Client packet ActionFailed to the L2PcInstance
  7955.                 sendPacket(new ActionFailed());
  7956.                 return;
  7957.             }
  7958.  
  7959.             // Check if the target is in the skill cast range
  7960.             if (dontMove)
  7961.             {
  7962.                 // Calculate the distance between the L2PcInstance and the target
  7963.  
  7964.                 if (skill.getCastRange() > 0 && !isInsideRadius(target, skill.getCastRange()+(int)getTemplate().collisionRadius, false, false))
  7965.                 {
  7966.                     // Send a System Message to the caster
  7967.                     sendPacket(new SystemMessage(SystemMessage.TARGET_TOO_FAR));
  7968.  
  7969.                     // Send a Server->Client packet ActionFailed to the L2PcInstance
  7970.                     sendPacket(new ActionFailed());
  7971.                     return;
  7972.                 }
  7973.             }
  7974.         }
  7975.  
  7976.         // Check if the skill is defensive
  7977.         if (!skill.isOffensive())
  7978.         {
  7979.             // check if the target is a monster and if force attack is set.. if not then we don't want to cast.
  7980.             if ((target instanceof L2MonsterInstance) && !forceUse
  7981.  
  7982.                     && (sklTargetType != SkillTargetType.TARGET_PET)
  7983.                     && (sklTargetType != SkillTargetType.TARGET_AURA)
  7984.                     && (sklTargetType != SkillTargetType.TARGET_AURA_UNDEAD)
  7985.                     && (sklTargetType != SkillTargetType.TARGET_CLAN)
  7986.                     && (sklTargetType != SkillTargetType.TARGET_SELF)
  7987.                     && (sklTargetType != SkillTargetType.TARGET_PARTY)
  7988.                     && (sklTargetType != SkillTargetType.TARGET_ALLY)
  7989.                     && (sklTargetType != SkillTargetType.TARGET_CORPSE_MOB)
  7990.                     && (sklTargetType != SkillTargetType.TARGET_AREA_CORPSE_MOB)
  7991.                     && (sklType != SkillType.BEAST_FEED)
  7992.                     && (sklType != SkillType.DELUXE_KEY_UNLOCK))
  7993.             {
  7994.                 // send the action failed so that the skill doesn't go off.
  7995.                 sendPacket(new ActionFailed());
  7996.                 return;
  7997.             }
  7998.         }
  7999.  
  8000.         // Check if the skill is Spoil type and if the target isn't already spoiled
  8001.         if (sklType == SkillType.SPOIL)
  8002.         {
  8003.             if (!(target instanceof L2MonsterInstance))
  8004.             {
  8005.                 // Send a System Message to the L2PcInstance
  8006.                 sendPacket(new SystemMessage(SystemMessage.TARGET_IS_INCORRECT));
  8007.  
  8008.                 // Send a Server->Client packet ActionFailed to the L2PcInstance
  8009.                 sendPacket(new ActionFailed());
  8010.                 return;
  8011.             }
  8012.         }
  8013.  
  8014.  
  8015.         // Check if the skill is Sweep type and if conditions not apply
  8016.         if (sklType == SkillType.SWEEP && target instanceof L2Attackable)
  8017.         {
  8018.             int spoilerId = ((L2Attackable)target).getIsSpoiledBy();
  8019.  
  8020.             if (((L2Attackable)target).isDead())
  8021.             {
  8022.                 if (!((L2Attackable)target).isSpoil())
  8023.                 {
  8024.                     // Send a System Message to the L2PcInstance
  8025.                     sendPacket(new SystemMessage(SystemMessage.SWEEPER_FAILED_TARGET_NOT_SPOILED));
  8026.  
  8027.  
  8028.                     // Send a Server->Client packet ActionFailed to the L2PcInstance
  8029.                     sendPacket(new ActionFailed());
  8030.                     return;
  8031.                 }
  8032.  
  8033.                 if (getObjectId() != spoilerId && !isInLooterParty(spoilerId))
  8034.                 {
  8035.                     // Send a System Message to the L2PcInstance
  8036.                     sendPacket(new SystemMessage(SystemMessage.SWEEP_NOT_ALLOWED));
  8037.  
  8038.                     // Send a Server->Client packet ActionFailed to the L2PcInstance
  8039.                     sendPacket(new ActionFailed());
  8040.                     return;
  8041.                 }
  8042.             }
  8043.         }
  8044.  
  8045.         // Check if the skill is Drain Soul (Soul Crystals) and if the target is a MOB
  8046.         if (sklType == SkillType.DRAIN_SOUL)
  8047.         {
  8048.             if (!(target instanceof L2MonsterInstance))
  8049.             {
  8050.                 // Send a System Message to the L2PcInstance
  8051.                 sendPacket(new SystemMessage(SystemMessage.TARGET_IS_INCORRECT));
  8052.  
  8053.                 // Send a Server->Client packet ActionFailed to the L2PcInstance
  8054.                 sendPacket(new ActionFailed());
  8055.                 return;
  8056.             }
  8057.         }
  8058.  
  8059.  
  8060.         // Check if this is a Pvp skill and target isn't a non-flagged/non-karma player
  8061.         switch (sklTargetType)
  8062.         {
  8063.             case TARGET_PARTY:
  8064.             case TARGET_ALLY:   // For such skills, checkPvpSkill() is called from L2Skill.getTargetList()
  8065.             case TARGET_CLAN:   // For such skills, checkPvpSkill() is called from L2Skill.getTargetList()
  8066.             case TARGET_AURA:
  8067.             case TARGET_AURA_UNDEAD:
  8068.             case TARGET_SELF:
  8069.                 break;
  8070.             default:
  8071.                 if (!checkPvpSkill(target, skill) && (getAccessLevel() < Config.GM_PEACEATTACK))
  8072.                 {
  8073.                     // Send a System Message to the L2PcInstance
  8074.                     sendPacket(new SystemMessage(SystemMessage.TARGET_IS_INCORRECT));
  8075.  
  8076.                     // Send a Server->Client packet ActionFailed to the L2PcInstance
  8077.                     sendPacket(new ActionFailed());
  8078.                     return;
  8079.                 }
  8080.  
  8081.         }
  8082.  
  8083.         if (sklType == SkillType.STRSIEGEASSAULT && !SiegeManager.getInstance().checkIfOkToSummon(this, false))
  8084.         {
  8085.             sendPacket(new ActionFailed());
  8086.             abortCast();
  8087.             return;
  8088.         }
  8089.  
  8090.         // GeoData Los Check here
  8091.         if (skill.getCastRange() > 0 && !GeoData.getInstance().canSeeTarget(this, target))
  8092.         {
  8093.             sendPacket(new SystemMessage(SystemMessage.CANT_SEE_TARGET));
  8094.             sendPacket(new ActionFailed());
  8095.             return;
  8096.         }
  8097.  
  8098.         // If all conditions are checked, create a new SkillDat object and set the player _currentSkill
  8099.         setCurrentSkill(skill, forceUse, dontMove);
  8100.  
  8101.         // Notify the AI with AI_INTENTION_CAST and target
  8102.         getAI().setIntention(CtrlIntention.AI_INTENTION_CAST, skill, target);
  8103.  
  8104.     }
  8105.  
  8106.     public boolean isInLooterParty(int looterId)
  8107.     {
  8108.  
  8109.         if (isInParty())
  8110.         {
  8111.             for (L2PcInstance member : getParty().getPartyMembers())
  8112.             {
  8113.                 if (member == null)
  8114.                     continue;
  8115.  
  8116.                 if (member.getObjectId() == looterId)
  8117.                     return true;
  8118.             }
  8119.         }
  8120.  
  8121.  
  8122.         return false;
  8123.     }
  8124.  
  8125.     /**
  8126.      * Check if the requested casting is a Pc->Pc skill cast and if it's a valid pvp condition
  8127.      * @param target L2Object instance containing the target
  8128.      * @param skill L2Skill instance with the skill being casted
  8129.      * @return False if the skill is a pvpSkill and target is not a valid pvp target
  8130.      */
  8131.     public boolean checkPvpSkill(L2Object target, L2Skill skill)
  8132.     {
  8133.         return checkPvpSkill(target, skill, false);
  8134.     }
  8135.  
  8136.     public boolean checkPvpSkill(L2Object target, L2Skill skill, boolean srcIsSummon)
  8137.     {
  8138.         L2PcInstance targetPlayer = null;
  8139.         if (target instanceof L2PcInstance)
  8140.             targetPlayer = (L2PcInstance)target;
  8141.         else if (target instanceof L2Summon)
  8142.             targetPlayer = ((L2Summon)target).getOwner();
  8143.  
  8144.         // check for PC->PC Pvp status
  8145.         if (targetPlayer != null && targetPlayer != this &&         // target not null and not self and
  8146.  
  8147.                !isInsideZone(ZONE_PVP) &&                       // Pc is not in PvP zone
  8148.                !targetPlayer.isInsideZone(ZONE_PVP))  // target is not in PvP zone
  8149.         {
  8150.  
  8151.             if (skill.isPvpSkill()) // pvp skill
  8152.  
  8153.             {
  8154.  
  8155.                 if (getClan() != null && targetPlayer.getClan() != null)
  8156.  
  8157.                 {
  8158.  
  8159.                     if (getClan().isAtWarWith(targetPlayer.getClan().getClanId())
  8160.  
  8161.                            && targetPlayer.getClan().isAtWarWith(getClan().getClanId()))
  8162.  
  8163.                         return true; // in clan war player can attack whites even with sleep etc.
  8164.  
  8165.  
  8166.                     if (getClan().getClanId() == targetPlayer.getClan().getClanId())
  8167.                         return false;
  8168.                 }
  8169.  
  8170.  
  8171.                 if (targetPlayer.getPvpFlag() == 0 &&        //   target's pvp flag is not set and
  8172.  
  8173.                        targetPlayer.getKarma() == 0)         //   target has no karma
  8174.  
  8175.                     return false;
  8176.  
  8177.             }
  8178.  
  8179.             else if ((getCurrentSkill() != null && !getCurrentSkill().isCtrlPressed() && skill.isOffensive() && !srcIsSummon)
  8180.                     || (getCurrentPetSkill() != null && !getCurrentPetSkill().isCtrlPressed() && skill.isOffensive() && srcIsSummon))
  8181.  
  8182.             {
  8183.                 if (getClan() != null && targetPlayer.getClan() != null)
  8184.                 {
  8185.                     if (getClan().isAtWarWith(targetPlayer.getClan().getClanId()) && targetPlayer.getClan().isAtWarWith(getClan().getClanId()))
  8186.                         return true;
  8187.                 }
  8188.  
  8189.  
  8190.                 if (targetPlayer.getPvpFlag() == 0 &&        //   target's pvp flag is not set and
  8191.  
  8192.                        targetPlayer.getKarma() == 0)            //   target has no karma
  8193.  
  8194.                     return false;
  8195.  
  8196.             }
  8197.  
  8198.         }
  8199.  
  8200.         return true;
  8201.     }
  8202.  
  8203.     /**
  8204.      * Reduce Item quantity of the L2PcInstance Inventory and send it a Server->Client packet InventoryUpdate.<BR><BR>
  8205.      */
  8206.     public void consumeItem(int itemConsumeId, int itemCount)
  8207.     {
  8208.         if (itemConsumeId != 0 && itemCount != 0)
  8209.             destroyItemByItemId("Consume", itemConsumeId, itemCount, null, false);
  8210.     }
  8211.  
  8212.     /**
  8213.      * Return True if the L2PcInstance is a Mage.<BR><BR>
  8214.      */
  8215.     public boolean isMageClass()
  8216.     {
  8217.         return getClassId().isMage();
  8218.     }
  8219.  
  8220.     public boolean isMounted()
  8221.     {
  8222.         return _mountType > 0;
  8223.     }
  8224.  
  8225.     /**
  8226.      * Set the type of Pet mounted (0 : none, 1 : Stridder, 2 : Wyvern) and send a Server->Client packet InventoryUpdate to the L2PcInstance.<BR><BR>
  8227.      */
  8228.     public boolean checkLandingState()
  8229.     {
  8230.         // Check if char is in a no landing zone
  8231.         if (isInsideZone(ZONE_NOLANDING))
  8232.             return true;
  8233.  
  8234.  
  8235.         return false;
  8236.     }
  8237.  
  8238.     /**
  8239.      * Return the type of Pet mounted (0 : none, 1 : Stridder, 2 : Wyvern).<BR><BR>
  8240.      */
  8241.     public int getMountType()
  8242.     {
  8243.         return _mountType;
  8244.     }
  8245.  
  8246.     public boolean setMount(int npcId, int npcLevel, int mountType)
  8247.     {
  8248.         switch(mountType)
  8249.         {
  8250.             case 0:
  8251.                 setIsFlying(false);
  8252.                 setIsRiding(false);
  8253.                 break; //Dismounted
  8254.             case 1:
  8255.                 setIsRiding(true);
  8256.                 break;
  8257.             case 2:
  8258.                 setIsFlying(true);
  8259.                 break; //Flying Wyvern
  8260.         }
  8261.  
  8262.         _mountType = mountType;
  8263.         _mountNpcId = npcId;
  8264.         _mountLevel = npcLevel;
  8265.  
  8266.         return true;
  8267.     }
  8268.  
  8269.     public boolean mount(L2Summon pet)
  8270.     {
  8271.         if (!disarmWeapons())
  8272.             return false;
  8273.  
  8274.         for (L2Effect e : getAllEffects())
  8275.         {
  8276.             if (e != null && e.getSkill().isToggle())
  8277.                 e.exit();
  8278.         }
  8279.  
  8280.         Ride mount = new Ride(getObjectId(), true, pet.getTemplate().npcId);
  8281.         setMount(pet.getNpcId(), pet.getLevel(), mount.getMountType());
  8282.         setMountObjectID(pet.getControlItemId());
  8283.         clearPetData();
  8284.         startFeed(pet.getNpcId());
  8285.         broadcastPacket(mount);
  8286.  
  8287.         broadcastUserInfo();
  8288.  
  8289.         pet.unSummon(this);
  8290.  
  8291.         return true;
  8292.     }
  8293.  
  8294.     public boolean mount(int npcId, int controlItemObjId, boolean useFood)
  8295.     {
  8296.         if (!disarmWeapons())
  8297.             return false;
  8298.  
  8299.         for (L2Effect e : getAllEffects())
  8300.         {
  8301.             if (e != null && e.getSkill().isToggle())
  8302.                 e.exit();
  8303.         }
  8304.  
  8305.         Ride mount = new Ride(getObjectId(), true, npcId);
  8306.         if (setMount(npcId, getLevel(), mount.getMountType()))
  8307.         {
  8308.             clearPetData();
  8309.             setMountObjectID(controlItemObjId);
  8310.             broadcastPacket(mount);
  8311.             broadcastUserInfo();
  8312.             if (useFood)
  8313.                 startFeed(npcId);
  8314.             return true;
  8315.         }
  8316.         return false;
  8317.     }
  8318.  
  8319.     public boolean dismount()
  8320.     {
  8321.         boolean wasFlying = isFlying();
  8322.         sendPacket(new SetupGauge(3, 0, 0));
  8323.         int petId = _mountNpcId;
  8324.  
  8325.         if (setMount(0, 0, 0))
  8326.         {
  8327.             stopFeed();
  8328.             clearPetData();
  8329.             if (wasFlying)
  8330.                 removeSkill(SkillTable.getInstance().getInfo(4289, 1));
  8331.             Ride dismount = new Ride(getObjectId(), false, 0);
  8332.             broadcastPacket(dismount);
  8333.             setMountObjectID(0);
  8334.             storePetFood(petId);
  8335.             broadcastUserInfo();
  8336.  
  8337.             return true;
  8338.         }
  8339.         return false;
  8340.     }
  8341.  
  8342.     public boolean mountPlayer(L2Summon pet)
  8343.     {
  8344.         if (pet != null && pet.isMountable() && !isMounted())
  8345.         {
  8346.             if (isDead())
  8347.             {
  8348.                 // A strider cannot be ridden when dead
  8349.                 sendPacket(new SystemMessage(SystemMessage.STRIDER_CANT_BE_RIDDEN_WHILE_DEAD));
  8350.                 sendPacket(new ActionFailed());
  8351.                 return false;
  8352.             }
  8353.             else if (pet.isDead())
  8354.             {
  8355.                 // A dead strider cannot be ridden.
  8356.                 sendPacket(new SystemMessage(SystemMessage.DEAD_STRIDER_CANT_BE_RIDDEN));
  8357.  
  8358.                 sendPacket(new ActionFailed());
  8359.                 return false;
  8360.             }
  8361.             else if (pet.isInCombat() || pet.isMovementDisabled())
  8362.             {
  8363.                 // A strider in battle cannot be ridden
  8364.                 sendPacket(new SystemMessage(SystemMessage.STRIDER_IN_BATLLE_CANT_BE_RIDDEN));
  8365.  
  8366.                 sendPacket(new ActionFailed());
  8367.                 return false;  
  8368.             }
  8369.             else if (isInCombat())
  8370.             {
  8371.                 // A strider cannot be ridden while in battle
  8372.                 sendPacket(new SystemMessage(SystemMessage.STRIDER_CANT_BE_RIDDEN_WHILE_IN_BATTLE));
  8373.  
  8374.                 sendPacket(new ActionFailed());
  8375.                 return false;
  8376.             }
  8377.             else if (isSitting())
  8378.             {
  8379.                 // A strider can be ridden only when standing
  8380.                 sendPacket(new SystemMessage(SystemMessage.STRIDER_CAN_BE_RIDDEN_ONLY_WHILE_STANDING));
  8381.  
  8382.                 sendPacket(new ActionFailed());
  8383.                 return false;
  8384.             }
  8385.             else if (isFishing())
  8386.             {
  8387.                 // You can't mount, dismount, break and drop items while fishing
  8388.  
  8389.                 sendPacket(new SystemMessage(SystemMessage.CANNOT_DO_WHILE_FISHING_2));
  8390.  
  8391.                 sendPacket(new ActionFailed());
  8392.                 return false;
  8393.             }
  8394.  
  8395.             else if (pet.isHungry())
  8396.             {
  8397.                 sendPacket(new SystemMessage(SystemMessage.HUNGRY_STRIDER_NOT_MOUNT));
  8398.                 sendPacket(new ActionFailed());
  8399.                 return false;
  8400.             }
  8401.             else if (getEventTeam() > 0)
  8402.             {
  8403.                 sendMessage("Cannot mount while in TvT Event.");
  8404.                 return false;
  8405.             }
  8406.             else if (!Util.checkIfInRange(100, this, pet, true))
  8407.             {
  8408.                 sendMessage("Your pet is too far to ride it.");
  8409.  
  8410.                 sendPacket(new ActionFailed());
  8411.                 return false;              
  8412.             }
  8413.             else if (!pet.isDead() && !isMounted())
  8414.                 mount(pet);
  8415.         }
  8416.         else if (isRentedPet())
  8417.             stopRentPet();
  8418.         else if (isMounted())
  8419.         {
  8420.             if (isInCombat())
  8421.             {
  8422.                 sendPacket(new ActionFailed());
  8423.                 return false;
  8424.             }
  8425.             else if (getMountType() == 2 && isInsideZone(ZONE_NOLANDING))
  8426.             {
  8427.                 sendPacket(new SystemMessage(SystemMessage.NO_DISMOUNT_HERE));
  8428.                 sendPacket(new ActionFailed());
  8429.                 return false;
  8430.             }
  8431.             else if (isHungry())
  8432.             {
  8433.                 sendPacket(new SystemMessage(SystemMessage.HUNGRY_STRIDER_NOT_MOUNT));
  8434.                 sendPacket(new ActionFailed());
  8435.                 return false;
  8436.             }
  8437.             else
  8438.                 dismount();
  8439.         }
  8440.         return true;
  8441.     }
  8442.  
  8443.     /**
  8444.      * Send a Server->Client packet UserInfo to this L2PcInstance and CharInfo to all L2PcInstance in its _KnownPlayers.<BR><BR>
  8445.      *
  8446.      * <B><U> Concept</U> :</B><BR><BR>
  8447.      * Others L2PcInstance in the detection area of the L2PcInstance are identified in <B>_knownPlayers</B>.
  8448.      * In order to inform other players of this L2PcInstance state modifications, server just need to go through _knownPlayers to send Server->Client Packet<BR><BR>
  8449.      *
  8450.      * <B><U> Actions</U> :</B><BR><BR>
  8451.      * <li>Send a Server->Client packet UserInfo to this L2PcInstance (Public and Private Data)</li>
  8452.      * <li>Send a Server->Client packet CharInfo to all L2PcInstance in _KnownPlayers of the L2PcInstance (Public data only)</li><BR><BR>
  8453.      *
  8454.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : DON'T SEND UserInfo packet to other players instead of CharInfo packet.
  8455.      * Indeed, UserInfo packet contains PRIVATE DATA as MaxHP, STR, DEX...</B></FONT><BR><BR>
  8456.      *
  8457.      */
  8458.     public void updateAbnormalEffect()
  8459.     {
  8460.         broadcastUserInfo();
  8461.     }
  8462.  
  8463.     /**
  8464.      * Disable the Inventory and create a new task to enable it after 1.5s.<BR><BR>
  8465.      */
  8466.     public void tempInventoryDisable()
  8467.     {
  8468.         _inventoryDisable  = true;
  8469.         ThreadPoolManager.getInstance().scheduleGeneral(new InventoryEnable(), 1500);
  8470.     }
  8471.  
  8472.     /**
  8473.      * Return True if the Inventory is disabled.<BR><BR>
  8474.      */
  8475.     public boolean isInventoryDisabled()
  8476.     {
  8477.         return _inventoryDisable;
  8478.     }
  8479.  
  8480.     class InventoryEnable implements Runnable
  8481.     {
  8482.         public void run()
  8483.         {
  8484.             _inventoryDisable = false;
  8485.         }
  8486.     }
  8487.  
  8488.     public Map<Integer, L2CubicInstance> getCubics()
  8489.     {
  8490.         return _cubics;
  8491.     }
  8492.  
  8493.     /**
  8494.      * Add a L2CubicInstance to the L2PcInstance _cubics.<BR><BR>
  8495.      */
  8496.     public void addCubic(int id, int level, boolean givenByOther)
  8497.     {
  8498.         L2CubicInstance cubic = new L2CubicInstance(this, id, level, givenByOther);
  8499.         _cubics.put(id, cubic);
  8500.     }
  8501.  
  8502.     /**
  8503.      * Remove a L2CubicInstance from the L2PcInstance _cubics.<BR><BR>
  8504.      */
  8505.     public void delCubic(int id)
  8506.     {
  8507.         _cubics.remove(id);
  8508.     }
  8509.  
  8510.     /**
  8511.      * Return the L2CubicInstance corresponding to the Identifier of the L2PcInstance _cubics.<BR><BR>
  8512.      */
  8513.     public L2CubicInstance getCubic(int id)
  8514.     {
  8515.         return _cubics.get(id);
  8516.     }
  8517.  
  8518.     public String toString()
  8519.     {
  8520.         return "player "+getName();
  8521.     }
  8522.  
  8523.     /**
  8524.      * Return the modifier corresponding to the Enchant Effect of the Active Weapon (Min : 127).<BR><BR>
  8525.      */
  8526.     public int getEnchantEffect()
  8527.     {
  8528.         L2ItemInstance wpn = getActiveWeaponInstance();
  8529.         if (wpn == null)
  8530.             return 0;
  8531.  
  8532.         return Math.min(127, wpn.getEnchantLevel());
  8533.     }
  8534.  
  8535.     /**
  8536.      * Set the _lastFolkNpc of the L2PcInstance corresponding to the last Folk wich one the player talked.<BR><BR>
  8537.      */
  8538.     public void setLastFolkNPC(L2FolkInstance folkNpc)
  8539.     {
  8540.         _lastFolkNpc = folkNpc;
  8541.     }
  8542.  
  8543.     /**
  8544.      * Return the _lastFolkNpc of the L2PcInstance corresponding to the last Folk wich one the player talked.<BR><BR>
  8545.      */
  8546.     public L2FolkInstance getLastFolkNPC()
  8547.     {
  8548.         return _lastFolkNpc;
  8549.     }
  8550.  
  8551.     /**
  8552.      * Return True if L2PcInstance is a participant in the Festival of Darkness.<BR><BR>
  8553.      */
  8554.     public boolean isFestivalParticipant()
  8555.     {
  8556.         return SevenSignsFestival.getInstance().isParticipant(this);
  8557.     }
  8558.  
  8559.     public void addAutoSoulShot(int itemId)
  8560.     {
  8561.         _activeSoulShots.add(itemId);
  8562.     }
  8563.  
  8564.     public void removeAutoSoulShot(int itemId)
  8565.     {
  8566.         _activeSoulShots.remove(itemId);
  8567.     }
  8568.  
  8569.     public Set<Integer> getAutoSoulShot()
  8570.     {
  8571.         return _activeSoulShots;
  8572.     }
  8573.  
  8574.     public void rechargeAutoSoulShot(boolean physical, boolean magic, boolean summon)
  8575.     {
  8576.         L2ItemInstance item;
  8577.         IItemHandler handler;
  8578.  
  8579.         if (_activeSoulShots == null || _activeSoulShots.size() == 0)
  8580.             return;
  8581.  
  8582.         for (int itemId : _activeSoulShots)
  8583.         {
  8584.             item = getInventory().getItemByItemId(itemId);
  8585.             if (item != null)
  8586.             {
  8587.                 if (magic)
  8588.                 {
  8589.                     if (!summon)
  8590.                     {
  8591.                         if (itemId == 2509 || itemId == 2510 || itemId == 2511 ||
  8592.                                 itemId == 2512 || itemId == 2513 || itemId == 2514 ||
  8593.                                 itemId == 3947 || itemId == 3948 || itemId == 3949 ||
  8594.                                 itemId == 3950 || itemId == 3951 || itemId == 3952 ||
  8595.                                 itemId == 5790)
  8596.                         {
  8597.                             handler = ItemHandler.getInstance().getItemHandler(itemId);
  8598.                             if (handler != null)
  8599.                                 handler.useItem(this, item);
  8600.                         }
  8601.                     }
  8602.                     else
  8603.                     {
  8604.                         if (itemId == 6646 || itemId == 6647)
  8605.                         {
  8606.                             handler = ItemHandler.getInstance().getItemHandler(itemId);
  8607.                             if (handler != null)
  8608.                                 handler.useItem(this, item);
  8609.                         }
  8610.                     }
  8611.                 }
  8612.  
  8613.  
  8614.                 if (physical)
  8615.                 {
  8616.                     if (!summon)
  8617.                     {
  8618.                         if (itemId == 1463 || itemId == 1464 || itemId == 1465 ||
  8619.                                 itemId == 1466 || itemId == 1467 || itemId == 1835 ||
  8620.                                 itemId == 5789)
  8621.                         {
  8622.                             handler = ItemHandler.getInstance().getItemHandler(itemId);
  8623.  
  8624.                             if (handler != null)
  8625.                                 handler.useItem(this, item);
  8626.                         }
  8627.                     }
  8628.                     else
  8629.                     {
  8630.                         if (itemId == 6645)
  8631.                         {
  8632.                             handler = ItemHandler.getInstance().getItemHandler(itemId);
  8633.  
  8634.  
  8635.                             if (handler != null)
  8636.                                 handler.useItem(this, item);
  8637.                         }
  8638.                     }
  8639.                 }
  8640.             }
  8641.             else
  8642.  
  8643.                 removeAutoSoulShot(itemId);
  8644.  
  8645.         }
  8646.     }
  8647.  
  8648.     public void disableAutoShotByCrystalType(int crystalType)
  8649.     {
  8650.         for (int itemId : _activeSoulShots)
  8651.         {
  8652.             if (ItemTable.getInstance().getTemplate(itemId).getCrystalType() == crystalType)
  8653.                 disableAutoShot(itemId);
  8654.         }
  8655.     }
  8656.  
  8657.     public boolean disableAutoShot(int itemId)
  8658.     {
  8659.         if (_activeSoulShots.contains(itemId))
  8660.         {
  8661.             removeAutoSoulShot(itemId);
  8662.             sendPacket(new ExAutoSoulShot(itemId, 0));
  8663.  
  8664.             SystemMessage sm = new SystemMessage(SystemMessage.AUTO_USE_OF_S1_CANCELLED);
  8665.             sm.addString(ItemTable.getInstance().getTemplate(itemId).getName());
  8666.             sendPacket(sm);
  8667.             return true;
  8668.         }
  8669.         return false;
  8670.     }
  8671.  
  8672.     public void disableAutoShotsAll()
  8673.     {
  8674.         for (int itemId : _activeSoulShots)
  8675.         {
  8676.             sendPacket(new ExAutoSoulShot(itemId, 0));
  8677.             SystemMessage sm = new SystemMessage(SystemMessage.AUTO_USE_OF_S1_CANCELLED);
  8678.             sm.addString(ItemTable.getInstance().getTemplate(itemId).getName());
  8679.             sendPacket(sm);
  8680.         }
  8681.         _activeSoulShots.clear();
  8682.     }
  8683.  
  8684.     private ScheduledFuture _taskWarnUserTakeBreak;
  8685.  
  8686.     class WarnUserTakeBreak implements Runnable
  8687.     {
  8688.         public void run()
  8689.         {
  8690.             if (L2PcInstance.this.isOnline() == 1)
  8691.             {
  8692.                 SystemMessage msg = new SystemMessage(764);
  8693.                 L2PcInstance.this.sendPacket(msg);
  8694.             }
  8695.             else
  8696.                 stopWarnUserTakeBreak();
  8697.         }
  8698.     }
  8699.  
  8700.     class RentPetTask implements Runnable
  8701.     {
  8702.         public void run()
  8703.         {
  8704.             stopRentPet();
  8705.         }
  8706.     }
  8707.  
  8708.  
  8709.     public ScheduledFuture _taskforfish;
  8710.  
  8711.     class WaterTask implements Runnable
  8712.     {
  8713.         public void run()
  8714.         {
  8715.             double reduceHp = getMaxHp()/100;
  8716.             if (reduceHp < 1)
  8717.                 reduceHp = 1;
  8718.  
  8719.  
  8720.             reduceCurrentHp(reduceHp,L2PcInstance.this,false);
  8721.             //reduced hp, because of not resting
  8722.             SystemMessage sm = new SystemMessage(297);
  8723.             sm.addNumber((int)reduceHp);
  8724.             sendPacket(sm);
  8725.         }
  8726.     }
  8727.  
  8728.     class LookingForFishTask implements Runnable
  8729.     {
  8730.         boolean _isNoob;
  8731.         int _fishType, _fishGutsCheck, _gutsCheckTime;
  8732.         long _endTaskTime;
  8733.  
  8734.         protected LookingForFishTask(int fishWaitTime, int fishGutsCheck, int fishType, boolean isNoob)
  8735.         {
  8736.             _fishGutsCheck = fishGutsCheck;
  8737.             _endTaskTime = System.currentTimeMillis() + fishWaitTime + 10000;
  8738.             _fishType = fishType;
  8739.             _isNoob = isNoob;
  8740.  
  8741.         }
  8742.  
  8743.         public void run()
  8744.         {
  8745.             if (System.currentTimeMillis() >= _endTaskTime)
  8746.             {
  8747.                 endFishing(false);
  8748.                 return;
  8749.             }
  8750.  
  8751.             if (_fishType == -1)
  8752.                 return;
  8753.  
  8754.  
  8755.             if (_fishGutsCheck > Rnd.get(1000))
  8756.             {
  8757.                 stopLookingForFishTask();
  8758.                 startFishCombat(_isNoob);
  8759.  
  8760.             }
  8761.  
  8762.         }
  8763.     }
  8764.  
  8765.     public int getClanPrivileges()
  8766.  
  8767.     {
  8768.         return _clanPrivileges;
  8769.     }
  8770.  
  8771.     public void setClanPrivileges(int n)
  8772.  
  8773.     {
  8774.         _clanPrivileges = n;
  8775.     }
  8776.  
  8777.     public void sendMessage(String message)
  8778.     {
  8779.         sendPacket(SystemMessage.sendString(message));
  8780.     }
  8781.  
  8782.     public void enterObserverMode(int x, int y, int z)
  8783.     {
  8784.         abortCast();
  8785.  
  8786.         if (getPet() != null)
  8787.  
  8788.             getPet().unSummon(this);
  8789.  
  8790.         if (getParty() != null)
  8791.             getParty().removePartyMember(this, true);
  8792.  
  8793.         _obsX = getX();
  8794.         _obsY = getY();
  8795.         _obsZ = getZ();
  8796.  
  8797.  
  8798.         setTarget(null);
  8799.         stopMove(null);
  8800.         setIsParalyzed(true);
  8801.  
  8802.         setIsInvul(true);
  8803.         getAppearance().setInvisible();
  8804.         sendPacket(new ObservationMode(x, y, z));
  8805.         getKnownList().removeAllKnownObjects();
  8806.         setXYZ(x, y, z);
  8807.  
  8808.         _observerMode = true;
  8809.         broadcastPacket(new CharInfo(this));
  8810.     }
  8811.  
  8812.     public void enterOlympiadObserverMode(int x, int y, int z, int id, boolean storeCoords)
  8813.  
  8814.     {
  8815.  
  8816.         _olympiadGameId = id;
  8817.  
  8818.  
  8819.         if (getPet() != null)
  8820.  
  8821.             getPet().unSummon(this);
  8822.  
  8823.         if (getCubics().size() > 0)
  8824.         {
  8825.             for (L2CubicInstance cubic : getCubics().values())
  8826.             {
  8827.                 cubic.stopAction();
  8828.                 cubic.cancelDisappear();
  8829.             }
  8830.             getCubics().clear();
  8831.         }
  8832.  
  8833.         if (getParty() != null)
  8834.             getParty().removePartyMember(this, true);
  8835.  
  8836.  
  8837.         if (isSitting())
  8838.  
  8839.             standUp();
  8840.  
  8841.         if (storeCoords)
  8842.         {
  8843.  
  8844.             _obsX = getX();
  8845.  
  8846.             _obsY = getY();
  8847.  
  8848.             _obsZ = getZ();
  8849.         }
  8850.  
  8851.  
  8852.         setTarget(null);
  8853.  
  8854.         setIsInvul(true);
  8855.  
  8856.         getAppearance().setInvisible();
  8857.  
  8858.         teleToLocation(x, y, z, false);
  8859.  
  8860.         sendPacket(new ExOlympiadMode(3));
  8861.         _observerMode = true;
  8862.  
  8863.     }
  8864.  
  8865.     public void leaveObserverMode()
  8866.     {
  8867.         setTarget(null);
  8868.         getKnownList().removeAllKnownObjects();
  8869.         setXYZ(_obsX, _obsY, _obsZ);
  8870.         setIsParalyzed(false);
  8871.         getAppearance().setVisible();
  8872.  
  8873.         setIsInvul(false);
  8874.  
  8875.  
  8876.         if (getAI() != null)
  8877.             getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  8878.  
  8879.         setFalling();
  8880.  
  8881.         _observerMode = false;
  8882.         sendPacket(new ObservationReturn(this));
  8883.         broadcastPacket(new CharInfo(this));
  8884.     }
  8885.  
  8886.     public void leaveOlympiadObserverMode()
  8887.     {
  8888.  
  8889.         setTarget(null);
  8890.         sendPacket(new ExOlympiadMatchEnd());
  8891.         sendPacket(new ExOlympiadMode(0));
  8892.  
  8893.         teleToLocation(_obsX, _obsY, _obsZ, true);
  8894.  
  8895.         getAppearance().setVisible();
  8896.  
  8897.         setIsInvul(false);
  8898.  
  8899.  
  8900.         if (getAI() != null)
  8901.  
  8902.             getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  8903.  
  8904.  
  8905.         _olympiadGameId = -1;
  8906.         _observerMode = false;
  8907.  
  8908.         broadcastPacket(new CharInfo(this));
  8909.  
  8910.     }
  8911.  
  8912.     public void setOlympiadSide(int i)
  8913.     {
  8914.  
  8915.         _olympiadSide = i;
  8916.  
  8917.     }
  8918.  
  8919.     public int getOlympiadSide()
  8920.     {
  8921.         return _olympiadSide;
  8922.  
  8923.     }
  8924.  
  8925.     public void setOlympiadGameId(int id)
  8926.     {
  8927.         _olympiadGameId = id;
  8928.     }
  8929.  
  8930.     public int getOlympiadGameId()
  8931.     {
  8932.         return _olympiadGameId;
  8933.     }
  8934.  
  8935.     public int getObsX()
  8936.     {
  8937.         return _obsX;
  8938.     }
  8939.  
  8940.     public int getObsY()
  8941.     {
  8942.         return _obsY;
  8943.     }
  8944.  
  8945.     public int getObsZ()
  8946.     {
  8947.         return _obsZ;
  8948.     }
  8949.  
  8950.     public boolean inObserverMode()
  8951.     {
  8952.         return _observerMode;
  8953.     }
  8954.  
  8955.     public int getTeleMode()
  8956.     {
  8957.         return _telemode;
  8958.     }
  8959.  
  8960.     public void setTeleMode(int mode)
  8961.     {
  8962.         _telemode = mode;
  8963.     }
  8964.  
  8965.     public void setLoto(int i, int val)
  8966.     {
  8967.         _loto[i] = val;
  8968.     }
  8969.  
  8970.     public int getLoto(int i)
  8971.     {
  8972.         return _loto[i];
  8973.     }
  8974.  
  8975.     public void setRace(int i, int val)
  8976.     {
  8977.         _race[i] = val;
  8978.     }
  8979.  
  8980.     public int getRace(int i)
  8981.     {
  8982.         return _race[i];
  8983.     }
  8984.  
  8985.     public void setChatBanned(boolean isBanned)
  8986.     {
  8987.         _chatBanned = isBanned;
  8988.  
  8989.         if (isChatBanned())
  8990.             sendMessage("You have been chat-banned for inappropriate language.");
  8991.         else
  8992.  
  8993.         {
  8994.             sendMessage("Your chat ban has been lifted.");
  8995.  
  8996.             if (_chatUnbanTask != null)
  8997.  
  8998.                 _chatUnbanTask.cancel(false);
  8999.  
  9000.             _chatUnbanTask = null;
  9001.         }
  9002.     }
  9003.  
  9004.     public boolean isChatBanned()
  9005.     {
  9006.         return _chatBanned;
  9007.     }
  9008.  
  9009.  
  9010.     public void setChatUnbanTask(ScheduledFuture task)
  9011.  
  9012.     {
  9013.  
  9014.         _chatUnbanTask = task;
  9015.  
  9016.     }
  9017.  
  9018.  
  9019.     public ScheduledFuture getChatUnbanTask()
  9020.     {
  9021.  
  9022.         return _chatUnbanTask;
  9023.  
  9024.     }
  9025.  
  9026.     public boolean getMessageRefusal()
  9027.     {
  9028.         return _messageRefusal;
  9029.     }
  9030.  
  9031.     public void setMessageRefusal(boolean mode)
  9032.     {
  9033.         _messageRefusal = mode;
  9034.  
  9035.         sendPacket(new EtcStatusUpdate(this));
  9036.     }
  9037.  
  9038.     public void setDietMode(boolean mode)
  9039.     {
  9040.         _dietMode = mode;
  9041.     }
  9042.  
  9043.     public boolean getDietMode()
  9044.     {
  9045.         return _dietMode;
  9046.     }
  9047.  
  9048.     public void setTradeRefusal(boolean mode)
  9049.     {
  9050.         _tradeRefusal = mode;
  9051.     }
  9052.  
  9053.     public boolean getTradeRefusal()
  9054.     {
  9055.         return _tradeRefusal;
  9056.     }
  9057.  
  9058.     public void setExchangeRefusal(boolean mode)
  9059.     {
  9060.         _exchangeRefusal = mode;
  9061.     }
  9062.  
  9063.     public boolean getExchangeRefusal()
  9064.     {
  9065.         return _exchangeRefusal;
  9066.     }
  9067.  
  9068.     public BlockList getBlockList()
  9069.     {
  9070.         return _blockList;
  9071.     }
  9072.  
  9073.     public void setConnected(boolean connected)
  9074.     {
  9075.         _isConnected = connected;
  9076.     }
  9077.  
  9078.     public boolean isConnected()
  9079.     {
  9080.         return _isConnected;
  9081.     }
  9082.  
  9083.     public void setHero(boolean hero)
  9084.     {
  9085.         _hero = hero;
  9086.     }
  9087.  
  9088.     public void setIsInOlympiadMode(boolean b)
  9089.  
  9090.     {
  9091.         _inOlympiadMode = b;
  9092.  
  9093.     }
  9094.  
  9095.     public void setIsOlympiadStart(boolean b)
  9096.     {
  9097.         _OlympiadStart = b;
  9098.     }
  9099.  
  9100.     public boolean isHero()
  9101.     {
  9102.         return _hero;
  9103.     }
  9104.  
  9105.     public boolean isInOlympiadMode()
  9106.     {
  9107.         return _inOlympiadMode;
  9108.     }
  9109.  
  9110.     public boolean isOlympiadStart()
  9111.     {
  9112.         return _OlympiadStart;
  9113.     }
  9114.  
  9115.     public boolean isNoble()
  9116.     {
  9117.  
  9118.         return _noble;
  9119.     }
  9120.  
  9121.     public void setNoble(boolean val)
  9122.     {
  9123.         if (val)
  9124.  
  9125.         {
  9126.  
  9127.             for (L2Skill s : NobleSkillTable.getInstance().GetNobleSkills())
  9128.  
  9129.                 addSkill(s, false);
  9130.  
  9131.         }
  9132.  
  9133.         else
  9134.  
  9135.         {
  9136.  
  9137.             for (L2Skill s : NobleSkillTable.getInstance().GetNobleSkills())
  9138.  
  9139.                 removeSkill(s);
  9140.  
  9141.         }
  9142.         _noble = val;
  9143.     }
  9144.  
  9145.     public void setEventTeam(int team)
  9146.     {
  9147.         _team = team;
  9148.     }
  9149.  
  9150.     public int getEventTeam()
  9151.     {
  9152.         return _team;
  9153.     }
  9154.  
  9155.     public void setWantsPeace(int wantsPeace)
  9156.     {
  9157.         _wantsPeace = wantsPeace;
  9158.     }
  9159.  
  9160.     public int getWantsPeace()
  9161.     {
  9162.         return _wantsPeace;
  9163.     }
  9164.  
  9165.     public boolean isFishing()
  9166.     {
  9167.         return _fishing;
  9168.     }
  9169.  
  9170.     public void setFishing(boolean fishing)
  9171.     {
  9172.         _fishing = fishing;
  9173.     }
  9174.  
  9175.     public void setAllianceWithVarkaKetra(int sideAndLvlOfAlliance)
  9176.     {
  9177.         // [-5,-1] varka, 0 neutral, [1,5] ketra
  9178.         _alliedVarkaKetra = sideAndLvlOfAlliance;
  9179.     }
  9180.  
  9181.     public int getAllianceWithVarkaKetra()
  9182.     {
  9183.         return _alliedVarkaKetra;
  9184.     }
  9185.  
  9186.     public boolean isAlliedWithVarka()
  9187.     {
  9188.         return (_alliedVarkaKetra < 0);
  9189.     }
  9190.  
  9191.     public boolean isAlliedWithKetra()
  9192.     {
  9193.         return (_alliedVarkaKetra > 0);
  9194.     }
  9195.  
  9196.     /**
  9197.      * 1. Add the specified class ID as a subclass (up to the maximum number of <b>three</b>)
  9198.      * for this character.<BR>
  9199.      * 2. This method no longer changes the active _classIndex of the player. This is only
  9200.      * done by the calling of setActiveClass() method as that should be the only way to do so.
  9201.      *
  9202.      * @param int classId
  9203.      * @param int classIndex
  9204.      * @return boolean subclassAdded
  9205.      */
  9206.     public boolean addSubClass(int classId, int classIndex)
  9207.     {
  9208.         if (!_classLock.tryLock())
  9209.             return false;
  9210.  
  9211.         try
  9212.         {
  9213.             if (getTotalSubClasses() == Config.ALT_MAX_SUBCLASS || classIndex == 0)
  9214.                 return false;
  9215.  
  9216.             if (getSubClasses().containsKey(classIndex))
  9217.                 return false;
  9218.  
  9219.             // Note: Never change _classIndex in any method other than setActiveClass().
  9220.  
  9221.             SubClass newClass = new SubClass();
  9222.             newClass.setClassId(classId);
  9223.             newClass.setClassIndex(classIndex);
  9224.  
  9225.             java.sql.Connection con = null;
  9226.             try
  9227.             {
  9228.                 // Store the basic info about this new sub-class.
  9229.                 con = L2DatabaseFactory.getInstance().getConnection();
  9230.                 PreparedStatement statement = con.prepareStatement(ADD_CHAR_SUBCLASS);
  9231.                 statement.setInt(1, getObjectId());
  9232.                 statement.setInt(2, newClass.getClassId());
  9233.                 statement.setLong(3, newClass.getExp());
  9234.                 statement.setInt(4, newClass.getSp());
  9235.                 statement.setInt(5, newClass.getLevel());
  9236.                 statement.setInt(6, newClass.getClassIndex()); // <-- Added
  9237.                 statement.execute();
  9238.                 statement.close();
  9239.  
  9240.             }
  9241.             catch (Exception e)
  9242.             {
  9243.                 _log.warning("WARNING: Could not add character sub class for " + getName() + ": " + e);
  9244.                 return false;
  9245.             }
  9246.             finally
  9247.             {
  9248.  
  9249.                 try
  9250.                 {
  9251.                     con.close();
  9252.                 }
  9253.                 catch (Exception e) {}
  9254.             }
  9255.  
  9256.  
  9257.             // Commit after database INSERT incase exception is thrown.
  9258.             getSubClasses().put(newClass.getClassIndex(), newClass);
  9259.  
  9260.             if (Config.DEBUG)
  9261.                 _log.info(getName() + " added class ID " + classId + " as a sub class at index " + classIndex + ".");
  9262.  
  9263.  
  9264.             ClassId subTemplate = ClassId.values()[classId];
  9265.             Collection<L2SkillLearn> skillTree = SkillTreeTable.getInstance().getAllowedSkills(subTemplate);
  9266.  
  9267.             if (skillTree == null)
  9268.                 return true;
  9269.  
  9270.  
  9271.             Map<Integer, L2Skill> prevSkillList = new FastMap<>();
  9272.  
  9273.             for (L2SkillLearn skillInfo : skillTree)
  9274.             {
  9275.                 if (skillInfo.getMinLevel() <= 40)
  9276.                 {  
  9277.                     L2Skill prevSkill = prevSkillList.get(skillInfo.getId());
  9278.                     L2Skill newSkill = SkillTable.getInstance().getInfo(skillInfo.getId(), skillInfo.getLevel());
  9279.  
  9280.                     if (prevSkill != null && (prevSkill.getLevel() > newSkill.getLevel()))
  9281.                         continue;
  9282.  
  9283.                     prevSkillList.put(newSkill.getId(), newSkill);
  9284.                     storeSkill(newSkill, prevSkill, classIndex);
  9285.                 }
  9286.             }
  9287.  
  9288.             if (Config.DEBUG)
  9289.                 _log.info(getName() + " was given " + getAllSkills().length + " skills for their new sub class.");
  9290.  
  9291.  
  9292.             return true;
  9293.         }
  9294.         finally
  9295.         {
  9296.             _classLock.unlock();
  9297.         }
  9298.  
  9299.     }
  9300.  
  9301.     /**
  9302.      * 1. Completely erase all existance of the subClass linked to the classIndex.<BR>
  9303.      * 2. Send over the newClassId to addSubClass()to create a new instance on this classIndex.<BR>
  9304.      * 3. Upon Exception, revert the player to their BaseClass to avoid further problems.<BR>
  9305.      *
  9306.      * @param int classIndex
  9307.      * @param int newClassId
  9308.      * @return boolean subclassAdded
  9309.      */
  9310.     public boolean modifySubClass(int classIndex, int newClassId)
  9311.     {
  9312.         if (!_classLock.tryLock())
  9313.             return false;
  9314.  
  9315.         try
  9316.         {
  9317.             int oldClassId = getSubClasses().get(classIndex).getClassId();
  9318.  
  9319.             if (Config.DEBUG)
  9320.                 _log.info(getName() + " has requested to modify sub class index " + classIndex + " from class ID " + oldClassId + " to " + newClassId + ".");
  9321.  
  9322.  
  9323.             java.sql.Connection con = null;
  9324.  
  9325.             try
  9326.             {
  9327.                 con = L2DatabaseFactory.getInstance().getConnection();
  9328.                 PreparedStatement statement;
  9329.  
  9330.                 // Remove all henna info stored for this sub-class.
  9331.                 statement = con.prepareStatement(DELETE_CHAR_HENNAS);
  9332.                 statement.setInt(1, getObjectId());
  9333.                 statement.setInt(2, classIndex);
  9334.                 statement.execute();
  9335.                 statement.close();
  9336.  
  9337.  
  9338.                 // Remove all shortcuts info stored for this sub-class.
  9339.                 statement = con.prepareStatement(DELETE_CHAR_SHORTCUTS);
  9340.                 statement.setInt(1, getObjectId());
  9341.                 statement.setInt(2, classIndex);
  9342.                 statement.execute();
  9343.                 statement.close();
  9344.  
  9345.                 // Remove all effects info stored for this sub-class.
  9346.                 statement = con.prepareStatement(DELETE_SKILL_SAVE);
  9347.                 statement.setInt(1, getObjectId());
  9348.                 statement.setInt(2, classIndex);
  9349.                 statement.execute();
  9350.                 statement.close();
  9351.  
  9352.  
  9353.                 // Remove all skills info stored for this sub-class.
  9354.                 statement = con.prepareStatement(DELETE_CHAR_SKILLS);
  9355.                 statement.setInt(1, getObjectId());
  9356.                 statement.setInt(2, classIndex);
  9357.                 statement.execute();
  9358.                 statement.close();
  9359.  
  9360.                 // Remove all basic info stored about this sub-class.
  9361.                 statement = con.prepareStatement(DELETE_CHAR_SUBCLASS);
  9362.                 statement.setInt(1, getObjectId());
  9363.                 statement.setInt(2, classIndex);
  9364.                 statement.execute();
  9365.                 statement.close();
  9366.             }
  9367.             catch (Exception e)
  9368.             {
  9369.                 _log.warning("Could not modify sub class for " + getName() + " to class index " + classIndex + ": " + e);
  9370.  
  9371.  
  9372.                 // This must be done in order to maintain data consistency.
  9373.                 getSubClasses().remove(classIndex);
  9374.  
  9375.                 return false;
  9376.             }
  9377.             finally
  9378.             {
  9379.  
  9380.                 try
  9381.                 {
  9382.                     con.close();
  9383.                 }
  9384.                 catch (Exception e) {}
  9385.             }    
  9386.  
  9387.  
  9388.             getSubClasses().remove(classIndex);
  9389.         }
  9390.         finally
  9391.         {
  9392.             _classLock.unlock();
  9393.         }
  9394.  
  9395.         return addSubClass(newClassId, classIndex);
  9396.     }
  9397.  
  9398.     public boolean isSubClassActive()
  9399.     {
  9400.         return _classIndex > 0;
  9401.     }
  9402.  
  9403.     public Map<Integer, SubClass> getSubClasses()
  9404.     {
  9405.         if (_subClasses == null)
  9406.             _subClasses = new FastMap<>();
  9407.  
  9408.  
  9409.         return _subClasses;
  9410.     }
  9411.  
  9412.     public int getTotalSubClasses()
  9413.     {
  9414.         return getSubClasses().size();
  9415.     }
  9416.  
  9417.     public int getBaseClass()
  9418.     {
  9419.         return _baseClass;
  9420.     }
  9421.  
  9422.     public int getActiveClass()
  9423.     {
  9424.         return _activeClass;
  9425.     }
  9426.  
  9427.     public int getClassIndex()
  9428.     {
  9429.         return _classIndex;
  9430.     }
  9431.  
  9432.     private void setClassTemplate(int classId)
  9433.  
  9434.     {
  9435.  
  9436.         _activeClass = classId;
  9437.  
  9438.  
  9439.         L2PcTemplate t = CharTemplateTable.getInstance().getTemplate(classId);
  9440.         if (t == null)
  9441.  
  9442.         {
  9443.  
  9444.             _log.severe("Missing template for classId: "+classId);
  9445.  
  9446.             throw new Error();
  9447.  
  9448.         }
  9449.  
  9450.  
  9451.         // Set the template of the L2PcInstance
  9452.  
  9453.         setTemplate(t);
  9454.  
  9455.     }
  9456.  
  9457.  
  9458.     /**
  9459.  
  9460.      * Changes the character's class based on the given class index.
  9461.  
  9462.      * <BR><BR>
  9463.  
  9464.      * An index of zero specifies the character's original (base) class,
  9465.  
  9466.      * while indexes 1-3 specifies the character's sub-classes respectively.
  9467.  
  9468.      *
  9469.      * @param classIndex
  9470.  
  9471.      */
  9472.  
  9473.     public boolean setActiveClass(int classIndex)
  9474.     {
  9475.         if (!_classLock.tryLock())
  9476.             return false;
  9477.  
  9478.         try
  9479.         {
  9480.  
  9481.             /*
  9482.  
  9483.              * 1. Call store() before modifying _classIndex to avoid skill effects rollover.
  9484.  
  9485.              * 2. Register the correct _classId against applied 'classIndex'.
  9486.  
  9487.              */
  9488.  
  9489.             storeCharBase();
  9490.             storeCharSub();
  9491.  
  9492.             storeEffect(false);
  9493.             storeDwarvenRecipeBook();
  9494.  
  9495.  
  9496.             _reuseTimeStamps.clear();
  9497.  
  9498.  
  9499.             if (classIndex == 0)
  9500.  
  9501.                 setClassTemplate(getBaseClass());
  9502.  
  9503.             else
  9504.             {
  9505.                 try
  9506.                 {
  9507.                     setClassTemplate(getSubClasses().get(classIndex).getClassId());
  9508.                 }
  9509.                 catch (Exception e)
  9510.                 {
  9511.                     _log.info("Could not switch " + getName() + "'s sub class to class index " + classIndex + ": " + e);
  9512.                     return false;
  9513.                 }
  9514.             }
  9515.  
  9516.  
  9517.             _classIndex = classIndex;
  9518.  
  9519.  
  9520.             if (isInParty())
  9521.                 getParty().recalculatePartyLevel();
  9522.  
  9523.             /*
  9524.              * Update the character's change in class status.
  9525.              *
  9526.              * 1. Remove any active cubics from the player.
  9527.  
  9528.              * 2. Renovate the characters table in the database with the new class info, storing also buff/effect data.
  9529.  
  9530.  
  9531.              * 3. Remove all existing skills.
  9532.  
  9533.              * 4. Restore all the learned skills for the current class from the database.
  9534.  
  9535.              * 5. Restore effect/buff data for the new class.
  9536.  
  9537.              * 6. Restore henna data for the class, applying the new stat modifiers while removing existing ones.
  9538.  
  9539.              * 7. Reset HP/MP/CP stats and send Server->Client character status packet to reflect changes.
  9540.  
  9541.              * 8. Restore shortcut data related to this class.
  9542.  
  9543.              * 9. Resend a class change animation effect to broadcast to all nearby players.
  9544.  
  9545.              * 10.Unsummon any active servitor from the player.
  9546.  
  9547.              */
  9548.  
  9549.  
  9550.             if (getPet() != null && getPet() instanceof L2SummonInstance)
  9551.                 getPet().unSummon(this);
  9552.  
  9553.  
  9554.             if (getCubics().size() > 0)
  9555.  
  9556.             {
  9557.  
  9558.                 for (L2CubicInstance cubic : getCubics().values())
  9559.  
  9560.                 {
  9561.                     cubic.stopAction();
  9562.                     cubic.cancelDisappear();
  9563.                 }
  9564.  
  9565.  
  9566.                 getCubics().clear();
  9567.             }
  9568.  
  9569.  
  9570.             for (L2Skill oldSkill : getAllSkills())
  9571.             {
  9572.                 if (oldSkill.getSkillType() == L2Skill.SkillType.ITEM_SA
  9573. )
  9574.                     continue;
  9575.  
  9576.  
  9577.                 super.removeSkill(oldSkill);
  9578.  
  9579.             }
  9580.  
  9581.             stopAllEffects();
  9582.             _charges = 0;
  9583.  
  9584.             if (isSubClassActive())
  9585.                 _dwarvenRecipeBook.clear();
  9586.             else
  9587.  
  9588.                 restoreRecipeBook(0);
  9589.  
  9590.  
  9591.             restoreSkills();
  9592.  
  9593.             rewardSkills();
  9594.             // Prevents some issues when changing between subclasses that share skills
  9595.             if (_disabledSkills != null && !_disabledSkills.isEmpty())
  9596.                 _disabledSkills.clear();
  9597.             restoreEffects();
  9598.  
  9599.             updateEffectIcons();
  9600.             sendPacket(new EtcStatusUpdate(this));
  9601.  
  9602.             if (isNoble())
  9603.                 setNoble(true);
  9604.  
  9605.             if (isClanLeader() && getClan().getLevel() > 3)
  9606.                 SiegeManager.getInstance().addSiegeSkills(this);
  9607.  
  9608.             getSkillList();
  9609.  
  9610.             // If player has quest 422: Repent Your Sins, remove it
  9611.             QuestState st = getQuestState("422_RepentYourSins");
  9612.             if (st != null)
  9613.                 st.exitQuest(true);
  9614.  
  9615.             for (int i = 0; i < 3; i++)
  9616.                 _henna[i] = null;
  9617.  
  9618.             restoreHenna();
  9619.             sendPacket(new HennaInfo(this));
  9620.  
  9621.  
  9622.             if (getCurrentHp() > getMaxHp())
  9623.                 setCurrentHp(getMaxHp());
  9624.             if (getCurrentMp() > getMaxMp())
  9625.                 setCurrentMp(getMaxMp());
  9626.             if (getCurrentCp() > getMaxCp())
  9627.                 setCurrentCp(getMaxCp());
  9628.  
  9629.             refreshOverloaded();
  9630.             refreshExpertisePenalty();
  9631.             broadcastUserInfo();
  9632.  
  9633.  
  9634.             // Clear resurrect xp calculation
  9635.             _expBeforeDeath = 0;
  9636.  
  9637.  
  9638.             _shortCuts.restore();
  9639.             sendPacket(new ShortCutInit(this));
  9640.  
  9641.             sendPacket(new ExStorageMaxCount(this));
  9642.             broadcastPacket(new SocialAction(getObjectId(), 15));
  9643.  
  9644.  
  9645.  
  9646.  
  9647.  
  9648.             return true;
  9649.         }
  9650.         finally
  9651.         {
  9652.             _classLock.unlock();
  9653.         }
  9654.     }
  9655.  
  9656.     public boolean isLocked()
  9657.     {
  9658.         return _classLock.isLocked();
  9659.     }
  9660.  
  9661.     public void stopWarnUserTakeBreak()
  9662.     {
  9663.         if (_taskWarnUserTakeBreak != null)
  9664.         {
  9665.             _taskWarnUserTakeBreak.cancel(false);
  9666.             _taskWarnUserTakeBreak = null;
  9667.         }
  9668.     }
  9669.  
  9670.     public void startWarnUserTakeBreak()
  9671.     {
  9672.         if (_taskWarnUserTakeBreak == null)
  9673.             _taskWarnUserTakeBreak = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new WarnUserTakeBreak(), 7200000, 7200000);
  9674.     }
  9675.  
  9676.     public void stopRentPet()
  9677.     {
  9678.         if (_taskRentPet != null)
  9679.         {
  9680.             // if the rent of a wyvern expires while over a flying zone, tp to town before unmounting
  9681.             if (checkLandingState() && getMountType()==2)
  9682.                 teleToLocation(MapRegionTable.TeleportWhereType.Town);
  9683.  
  9684.             if (dismount())
  9685.             {
  9686.                 _taskRentPet.cancel(true);
  9687.  
  9688.                 _taskRentPet = null;
  9689.  
  9690.             }
  9691.         }
  9692.     }
  9693.  
  9694.     public void startRentPet(int seconds)
  9695.     {
  9696.         if (_taskRentPet == null)
  9697.             _taskRentPet = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new RentPetTask(), seconds * 1000, seconds * 1000);
  9698.     }
  9699.  
  9700.     public boolean isRentedPet()
  9701.     {
  9702.         if (_taskRentPet != null)
  9703.             return true;
  9704.  
  9705.         return false;
  9706.     }
  9707.  
  9708.     public void stopWaterTask()
  9709.     {
  9710.         if (_taskWater != null)
  9711.         {
  9712.             _taskWater.cancel(false);
  9713.             _taskWater = null;
  9714.             sendPacket(new SetupGauge(2, 0));
  9715.         }
  9716.     }
  9717.  
  9718.     public void startWaterTask()
  9719.     {
  9720.         if (!isDead() && _taskWater == null)
  9721.         {
  9722.             int timeinwater = (int)calcStat(Stats.BREATH, 60000, this, null);
  9723.  
  9724.             sendPacket(new SetupGauge(2, timeinwater));
  9725.             _taskWater = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new WaterTask(), timeinwater, 1000);
  9726.         }    
  9727.     }
  9728.  
  9729.     public void checkWaterState()
  9730.     {
  9731.         if (isInsideZone(ZONE_WATER))
  9732.             startWaterTask();
  9733.         else
  9734.             stopWaterTask();
  9735.     }
  9736.  
  9737.     public void onPlayerEnter()
  9738.     {
  9739.         // notify friends about login
  9740.         notifyFriends();
  9741.  
  9742.         // send the list
  9743.         sendPacket(new FriendList(this));
  9744.  
  9745.         startWarnUserTakeBreak();
  9746.  
  9747.  
  9748.         // jail task
  9749.         updateJailState();
  9750.  
  9751.         if (_IsInvul)
  9752.             sendMessage("Entering world in Invulnerable mode.");
  9753.         if (getAppearance().getInvisible())
  9754.  
  9755.             sendMessage("Entering world in Invisible mode.");
  9756.         if (getMessageRefusal())
  9757.             sendMessage("Entering world in Message Refusal mode.");
  9758.  
  9759.         revalidateZone(true);
  9760.     }
  9761.  
  9762.     public long getLastAccess()
  9763.     {
  9764.         return _lastAccess;
  9765.     }
  9766.  
  9767.     private void checkRecom(int recsHave, int recsLeft)
  9768.     {
  9769.         Calendar check = Calendar.getInstance();
  9770.         check.setTimeInMillis(_lastRecomUpdate);
  9771.         check.add(Calendar.DAY_OF_MONTH,1);
  9772.  
  9773.         Calendar min = Calendar.getInstance();
  9774.  
  9775.         _recomHave = recsHave;
  9776.         _recomLeft = recsLeft;
  9777.  
  9778.         if (getStat().getLevel() < 10 || check.after(min))
  9779.             return;
  9780.  
  9781.         restartRecom();
  9782.     }
  9783.  
  9784.     public void restartRecom()
  9785.     {
  9786.  
  9787.         if (Config.ALT_RECOMMEND)
  9788.         {
  9789.             java.sql.Connection con = null;
  9790.             try
  9791.             {
  9792.                 con = L2DatabaseFactory.getInstance().getConnection();
  9793.                 PreparedStatement statement = con.prepareStatement(DELETE_CHAR_RECOMS);
  9794.                 statement.setInt(1, getObjectId());
  9795.                 statement.execute();
  9796.                 statement.close();
  9797.  
  9798.                 _recomChars.clear();
  9799.             }
  9800.             catch (Exception e)
  9801.             {
  9802.                 _log.warning("could not clear char recommendations: "+e);
  9803.             }
  9804.             finally
  9805.             {
  9806.                 try
  9807.                 {
  9808.                     con.close();
  9809.                 }
  9810.                 catch (Exception e) {}
  9811.             }
  9812.         }
  9813.  
  9814.         if (getStat().getLevel() < 20)
  9815.         {
  9816.             _recomLeft = 3;
  9817.             _recomHave--;
  9818.         }
  9819.         else if (getStat().getLevel() < 40)
  9820.  
  9821.         {
  9822.             _recomLeft = 6;
  9823.             _recomHave -= 2;
  9824.         }
  9825.         else
  9826.         {
  9827.             _recomLeft = 9;
  9828.             _recomHave -= 3;
  9829.         }
  9830.  
  9831.         if (_recomHave < 0)
  9832.  
  9833.             _recomHave = 0;
  9834.  
  9835.         // If we have to update last update time, but it's now before 13, we should set it to yesterday
  9836.  
  9837.         Calendar update = Calendar.getInstance();
  9838.  
  9839.         if(update.get(Calendar.HOUR_OF_DAY) < 13)
  9840.            update.add(Calendar.DAY_OF_MONTH,-1);
  9841.  
  9842.  
  9843.         update.set(Calendar.HOUR_OF_DAY,13);
  9844.  
  9845.         _lastRecomUpdate = update.getTimeInMillis();
  9846.     }
  9847.  
  9848.     public int getBoatId()
  9849.     {
  9850.         return _boatId;
  9851.     }
  9852.  
  9853.     public void setBoatId(int boatId)
  9854.     {
  9855.         _boatId = boatId;
  9856.     }
  9857.  
  9858.     public void doRevive()
  9859.     {
  9860.         super.doRevive();
  9861.  
  9862.         updateEffectIcons();
  9863.  
  9864.         sendPacket(new EtcStatusUpdate(this));
  9865.  
  9866.         _ReviveRequested = 0;
  9867.  
  9868.         _RevivePower = 0;
  9869.  
  9870.         if (isInParty() && getParty().isInDimensionalRift())
  9871.             getParty().getDimensionalRift().memberRessurected(this);
  9872.  
  9873.         if (isMounted())
  9874.             startFeed(_mountNpcId);
  9875.     }
  9876.  
  9877.     public void doRevive(double revivePower)
  9878.     {
  9879.         // Restore the player's lost experience,
  9880.         // depending on the % return of the skill used (based on its power).
  9881.         restoreExp(revivePower);
  9882.         doRevive();
  9883.     }
  9884.  
  9885.     public void ReviveRequest(L2PcInstance Reviver, L2Skill skill, boolean Pet)
  9886.     {
  9887.         if (getEventTeam() > 0)
  9888.             return;
  9889.  
  9890.  
  9891.         if (_ReviveRequested == 1)
  9892.         {
  9893.  
  9894.             if (_RevivePet == Pet)
  9895.                 Reviver.sendPacket(new SystemMessage(1513)); // Resurrection is already been proposed.
  9896.             else
  9897.             {
  9898.                 if (Pet)
  9899.  
  9900.                     Reviver.sendPacket(new SystemMessage(1515)); // A pet cannot be resurrected while it's owner is in the process of resurrecting.
  9901.                 else
  9902.                     Reviver.sendPacket(new SystemMessage(1511)); // While a pet is attempting to resurrect, it cannot help in resurrecting its master.
  9903.             }
  9904.             return;
  9905.         }
  9906.  
  9907.         if ((Pet && getPet() != null && getPet().isDead()) || (!Pet && isDead()))
  9908.         {
  9909.             _ReviveRequested = 1;
  9910.             _RevivePower = Formulas.getInstance().calculateSkillResurrectRestorePercent(skill.getPower(), Reviver);
  9911.             _RevivePet = Pet;
  9912.             sendPacket(new ConfirmDlg(SystemMessage.RESSURECTION_REQUEST,Reviver.getName()));
  9913.         }
  9914.  
  9915.     }
  9916.  
  9917.     public void ReviveAnswer(int answer)
  9918.     {
  9919.         if (_ReviveRequested != 1 || (!isDead() && !_RevivePet) || (_RevivePet && getPet() != null && !getPet().isDead()))
  9920.             return;
  9921.  
  9922.         if (getEventTeam() > 0)
  9923.             return;
  9924.  
  9925.         if (answer == 1)
  9926.         {
  9927.             if (!_RevivePet)
  9928.             {
  9929.                 if (_RevivePower != 0)
  9930.                     doRevive(_RevivePower);
  9931.                 else
  9932.                     doRevive();
  9933.             }
  9934.             else if (getPet() != null)
  9935.             {
  9936.                 if (_RevivePower != 0)
  9937.                     getPet().doRevive(_RevivePower);
  9938.                 else
  9939.                     getPet().doRevive();
  9940.             }
  9941.         }
  9942.         _ReviveRequested = 0;
  9943.         _RevivePower = 0;
  9944.     }
  9945.  
  9946.     public boolean isReviveRequested()
  9947.     {
  9948.         return (_ReviveRequested == 1);
  9949.     }
  9950.  
  9951.     public boolean isRevivingPet()
  9952.     {
  9953.         return _RevivePet;
  9954.     }
  9955.  
  9956.     public void removeReviving()
  9957.     {
  9958.         _ReviveRequested = 0;
  9959.         _RevivePower = 0;
  9960.     }
  9961.  
  9962.     public void onActionRequest()
  9963.     {
  9964.         setProtection(false);
  9965.     }
  9966.  
  9967.     /**
  9968.      * @param expertiseIndex The expertiseIndex to set.
  9969.      */
  9970.     public void setExpertiseIndex(int expertiseIndex)
  9971.     {
  9972.         _expertiseIndex = expertiseIndex;
  9973.     }
  9974.  
  9975.     /**
  9976.      * @return Returns the expertiseIndex.
  9977.      */
  9978.     public int getExpertiseIndex()
  9979.     {
  9980.         return _expertiseIndex;
  9981.     }
  9982.  
  9983.     @Override
  9984.     public void teleToLocation(int x, int y, int z, boolean allowRandomOffset)
  9985.     {
  9986.         if (isInBoat())
  9987.             setBoat(null);
  9988.  
  9989.         super.teleToLocation(x, y, z, allowRandomOffset);
  9990.     }
  9991.  
  9992.     @Override
  9993.     public final void onTeleported()
  9994.     {
  9995.         super.onTeleported();
  9996.  
  9997.         // Force a revalidation
  9998.         revalidateZone(true);
  9999.  
  10000.  
  10001.         if (Config.PLAYER_SPAWN_PROTECTION > 0 && !isInOlympiadMode())
  10002.  
  10003.             setProtection(true);
  10004.  
  10005.  
  10006.         // Modify the position of the pet if necessary
  10007.         if (getPet() != null)
  10008.  
  10009.         {
  10010.  
  10011.             getPet().setFollowStatus(false);
  10012.  
  10013.             getPet().teleToLocation(getPosition().getX(), getPosition().getY(), getPosition().getZ(), false);
  10014.  
  10015.  
  10016.             if (getPet() == null)
  10017.                 return;
  10018.  
  10019.             ((L2SummonAI)getPet().getAI()).setStartFollowController(true);
  10020.             getPet().setFollowStatus(true);
  10021.             getPet().updateAndBroadcastStatus(0);
  10022.  
  10023.         }
  10024.     }
  10025.  
  10026.     public void setLastPartyPosition(int x, int y, int z)
  10027.     {
  10028.         _lastPartyPosition.setXYZ(x,y,z);
  10029.     }
  10030.  
  10031.     public int getLastPartyPositionDistance(int x, int y, int z)
  10032.     {
  10033.         double dx = (x - _lastPartyPosition.getX());
  10034.         double dy = (y - _lastPartyPosition.getY());
  10035.         double dz = (z - _lastPartyPosition.getZ());
  10036.  
  10037.         return (int)Math.sqrt(dx*dx + dy*dy + dz*dz);
  10038.     }
  10039.  
  10040.     public void setLastServerPosition(int x, int y, int z)
  10041.     {
  10042.         _lastServerPosition.setXYZ(x,y,z);
  10043.     }
  10044.  
  10045.     public Point3D getLastServerPosition()
  10046.     {
  10047.         return _lastServerPosition;
  10048.     }
  10049.  
  10050.     public boolean checkLastServerPosition(int x, int y, int z)
  10051.     {
  10052.         return _lastServerPosition.equals(x,y,z);
  10053.     }
  10054.  
  10055.     public int getLastServerDistance(int x, int y, int z)
  10056.     {
  10057.         double dx = (x - _lastServerPosition.getX());
  10058.         double dy = (y - _lastServerPosition.getY());
  10059.         double dz = (z - _lastServerPosition.getZ());
  10060.  
  10061.  
  10062.         return (int)Math.sqrt(dx*dx + dy*dy + dz*dz);
  10063.     }
  10064.  
  10065.     public void addExpAndSp(long addToExp, int addToSp)
  10066.     {
  10067.         getStat().addExpAndSp(addToExp, addToSp);
  10068.     }
  10069.  
  10070.     public void removeExpAndSp(long removeExp, int removeSp)
  10071.     {
  10072.         getStat().removeExpAndSp(removeExp, removeSp);
  10073.     }
  10074.  
  10075.     public void reduceCurrentHp(double i, L2Character attacker)
  10076.     {
  10077.         getStatus().reduceHp(i, attacker);
  10078.  
  10079.         // notify the tamed beast of attacks
  10080.         if (getTrainedBeast() != null)
  10081.             getTrainedBeast().onOwnerGotAttacked(attacker);
  10082.     }
  10083.  
  10084.     public void reduceCurrentHp(double value, L2Character attacker, boolean awake)
  10085.     {
  10086.         getStatus().reduceHp(value, attacker, awake);
  10087.  
  10088.         // notify the tamed beast of attacks
  10089.         if (getTrainedBeast() != null)
  10090.             getTrainedBeast().onOwnerGotAttacked(attacker);
  10091.     }
  10092.  
  10093.     public void broadcastSnoop(int type, String name, String _text)
  10094.     {
  10095.         if (_SnoopListener.size() > 0)
  10096.         {
  10097.             Snoop sn = new Snoop(getObjectId(),getName(),type,name,_text);
  10098.  
  10099.  
  10100.             for (L2PcInstance pci : _SnoopListener)
  10101.             {
  10102.                 if (pci != null)
  10103.                     pci.sendPacket(sn);
  10104.             }
  10105.         }
  10106.     }
  10107.  
  10108.     public void addSnooper(L2PcInstance pci)
  10109.     {
  10110.         if (!_SnoopListener.contains(pci))
  10111.             _SnoopListener.add(pci);
  10112.     }
  10113.  
  10114.     public void removeSnooper(L2PcInstance pci)
  10115.     {
  10116.         _SnoopListener.remove(pci);
  10117.     }
  10118.  
  10119.     public void addSnooped(L2PcInstance pci)
  10120.     {
  10121.         if (!_SnoopedPlayer.contains(pci))
  10122.             _SnoopedPlayer.add(pci);
  10123.     }
  10124.  
  10125.     public void removeSnooped(L2PcInstance pci)
  10126.     {
  10127.         _SnoopedPlayer.remove(pci);
  10128.     }
  10129.  
  10130.     public synchronized void addBypass(String bypass)
  10131.     {
  10132.  
  10133.         if (bypass == null)
  10134.             return;
  10135.  
  10136.         _validBypass.add(bypass);
  10137.  
  10138.     }
  10139.  
  10140.  
  10141.     public synchronized void addBypass2(String bypass)
  10142.     {
  10143.  
  10144.         if (bypass == null)
  10145.             return;
  10146.  
  10147.         _validBypass2.add(bypass);
  10148.     }
  10149.  
  10150.     public synchronized boolean validateBypass(String cmd)
  10151.     {
  10152.         if (!Config.BYPASS_VALIDATION)
  10153.             return true;
  10154.  
  10155.         for (String bp : _validBypass)
  10156.         {
  10157.  
  10158.             if (bp == null)
  10159.                 continue;
  10160.  
  10161.  
  10162.             if (bp.equals(cmd))
  10163.                 return true;
  10164.         }
  10165.  
  10166.  
  10167.         for (String bp : _validBypass2)
  10168.         {
  10169.  
  10170.             if (bp == null)
  10171.                 continue;
  10172.  
  10173.  
  10174.             if (cmd.startsWith(bp))
  10175.                 return true;
  10176.         }
  10177.  
  10178.         _log.warning("[L2PcInstance] player ["+getName()+"] sent invalid bypass '"+cmd+"', ban this player!");
  10179.         return false;
  10180.     }
  10181.  
  10182.     public boolean validateItemManipulation(int objectId, String action)
  10183.     {
  10184.         L2ItemInstance item = getInventory().getItemByObjectId(objectId);
  10185.  
  10186.         if (item == null || item.getOwnerId() != getObjectId())
  10187.         {
  10188.             _log.finest(getObjectId()+": player tried to " + action + " item he is not owner of");
  10189.             return false;
  10190.         }
  10191.  
  10192.         // Pet is summoned and not the item that summoned the pet AND not the buggle from strider you're mounting
  10193.         if (getPet() != null && getPet().getControlItemId() == objectId || getMountObjectID() == objectId)
  10194.         {
  10195.             if (Config.DEBUG)
  10196.                 _log.finest(getObjectId()+": player tried to " + action + " item controling pet");
  10197.  
  10198.  
  10199.             return false;
  10200.         }
  10201.  
  10202.         if (getActiveEnchantItem() != null && getActiveEnchantItem().getObjectId() == objectId)
  10203.         {
  10204.             if (Config.DEBUG)
  10205.                 _log.finest(getObjectId()+":player tried to " + action + " an enchant scroll he was using");
  10206.  
  10207.  
  10208.             return false;
  10209.         }
  10210.  
  10211.         if (item.isWear())
  10212.             return false;
  10213.  
  10214.         return true;
  10215.     }
  10216.  
  10217.     public synchronized void clearBypass()
  10218.     {
  10219.  
  10220.         _validBypass.clear();
  10221.  
  10222.         _validBypass2.clear();
  10223.  
  10224.     }
  10225.  
  10226.     /**
  10227.      * @return Returns the inBoat.
  10228.      */
  10229.     public boolean isInBoat()
  10230.     {
  10231.         return _boat != null;
  10232.     }
  10233.  
  10234.     /**
  10235.      * @return
  10236.      */
  10237.     public L2BoatInstance getBoat()
  10238.     {      
  10239.         return _boat;
  10240.     }
  10241.  
  10242.     /**
  10243.      * @param boat
  10244.      */
  10245.     public void setBoat(L2BoatInstance boat)
  10246.     {
  10247.         if (boat == null && _boat != null)
  10248.         {
  10249.             _boat.removePassenger(this);
  10250.             setInsideZone(L2PcInstance.ZONE_PEACE, false);
  10251.         }
  10252.         else if (_boat == null && boat != null)
  10253.             setInsideZone(L2PcInstance.ZONE_PEACE, true);
  10254.         _boat = boat;
  10255.     }
  10256.  
  10257.     public void setInCrystallize(boolean inCrystallize)
  10258.     {
  10259.         _inCrystallize = inCrystallize;
  10260.     }
  10261.  
  10262.     public boolean isInCrystallize()
  10263.     {
  10264.         return _inCrystallize;
  10265.     }
  10266.  
  10267.     /**
  10268.      * @return
  10269.      */
  10270.     public Point3D getInBoatPosition()
  10271.     {
  10272.         return _inBoatPosition;
  10273.     }
  10274.  
  10275.     public void setInBoatPosition(Point3D pt)
  10276.     {
  10277.         _inBoatPosition = pt;
  10278.     }
  10279.  
  10280.     /**
  10281.      * Manage the delete task of a L2PcInstance (Leave Party, Unsummon pet, Save its inventory in the database, Remove it from the world...).<BR><BR>
  10282.      *
  10283.      * <B><U> Actions</U> :</B><BR><BR>
  10284.      * <li>If the L2PcInstance is in observer mode, set its position to its position before entering in observer mode </li>
  10285.      * <li>Set the online Flag to True or False and update the characters table of the database with online status and lastAccess </li>
  10286.      * <li>Stop the HP/MP/CP Regeneration task </li>
  10287.      * <li>Cancel Crafting, Attak or Cast </li>
  10288.      * <li>Remove the L2PcInstance from the world </li>
  10289.      * <li>Stop Party and Unsummon Pet </li>
  10290.      * <li>Update database with items in its inventory and remove them from the world </li>
  10291.      * <li>Remove all L2Object from _knownObjects and _knownPlayer of the L2Character then cancel Attak or Cast and notify AI </li>
  10292.      * <li>Close the connection with the client </li><BR><BR>
  10293.      *
  10294.      */
  10295.     public void deleteMe()
  10296.     {
  10297.         try
  10298.         {
  10299.             abortAttack();
  10300.             abortCast();
  10301.             stopMove(null);
  10302.         }
  10303.  
  10304.         catch (Throwable t)
  10305.         {
  10306.             _log.log(Level.SEVERE, "deletedMe()", t);
  10307.         }
  10308.  
  10309.  
  10310.         // Set the online Flag to True or False and update the characters table of the database with online status and lastAccess (called when login and logout)
  10311.         try
  10312.         {
  10313.             setOnlineStatus(false);
  10314.         }
  10315.         catch (Throwable t)
  10316.         {
  10317.             _log.log(Level.SEVERE, "deletedMe()", t);
  10318.         }
  10319.  
  10320.         // Stop the HP/MP/CP Regeneration task (scheduled tasks)
  10321.         try
  10322.         {
  10323.             stopAllTimers();
  10324.         }
  10325.         catch (Throwable t)
  10326.         {
  10327.             _log.log(Level.SEVERE, "deletedMe()", t);
  10328.         }
  10329.  
  10330.         // Stop crafting, if in progress
  10331.         try
  10332.         {
  10333.             RecipeController.getInstance().requestMakeItemAbort(this);
  10334.         }
  10335.         catch (Throwable t)
  10336.         {
  10337.             _log.log(Level.SEVERE, "deletedMe()", t);
  10338.         }
  10339.  
  10340.         // Cancel Attack or Cast
  10341.         try
  10342.         {
  10343.             setTarget(null);
  10344.         }
  10345.         catch (Throwable t)
  10346.         {
  10347.             _log.log(Level.SEVERE, "deletedMe()", t);
  10348.         }
  10349.  
  10350.  
  10351.  
  10352.         // Remove from world regions zones
  10353.         L2WorldRegion oldRegion = getWorldRegion();
  10354.  
  10355.         // Remove the L2PcInstance from the world
  10356.  
  10357.         try
  10358.         {
  10359.             decayMe();
  10360.         }
  10361.         catch (Throwable t)
  10362.         {
  10363.             _log.log(Level.SEVERE, "deletedMe()", t);
  10364.         }
  10365.  
  10366.  
  10367.         if (oldRegion != null)
  10368.             oldRegion.removeFromZones(this);
  10369.  
  10370.         // If a Party is in progress, leave it
  10371.         if (isInParty())
  10372.         {
  10373.             try
  10374.             {
  10375.                 leaveParty();
  10376.             }
  10377.             catch (Throwable t)
  10378.             {
  10379.                 _log.log(Level.SEVERE, "deletedMe()", t);
  10380.             }
  10381.         }
  10382.  
  10383.         try
  10384.         {
  10385.             if (_partyroom != 0)
  10386.             {
  10387.                 PartyMatchRoom room = PartyMatchRoomList.getInstance().getRoom(_partyroom);
  10388.                 if (room != null)
  10389.                     room.deleteMember(this);
  10390.             }
  10391.         }
  10392.         catch (Throwable t)
  10393.         {
  10394.             _log.log(Level.SEVERE, "deletedMe()", t);
  10395.         }
  10396.  
  10397.         try
  10398.         {
  10399.             if (Olympiad.getInstance().isRegisteredInComp(this)) // handle removal from olympiad game
  10400.                 Olympiad.getInstance().removeDisconnectedCompetitor(this);
  10401.         }
  10402.         catch (Throwable t)
  10403.         {
  10404.             _log.log(Level.SEVERE, "deletedMe()", t);
  10405.         }
  10406.  
  10407.         try
  10408.         {
  10409.             if (TvTEvent.isEnabled)
  10410.                 TvTEvent.removePlayer(this);
  10411.         }
  10412.         catch (Throwable t)
  10413.         {
  10414.             _log.log(Level.SEVERE, "deletedMe()", t);
  10415.         }
  10416.  
  10417.         try
  10418.         {
  10419.             Olympiad.clearOfflineObservers(this);
  10420.         }
  10421.         catch (Throwable t)
  10422.         {
  10423.             _log.log(Level.SEVERE, "deletedMe()", t);
  10424.         }
  10425.  
  10426.         // If the L2PcInstance has Pet, unsummon it
  10427.         if (getPet() != null)
  10428.         {
  10429.             try
  10430.             {
  10431.                 getPet().unSummon(this);
  10432.                 // dead pet wasnt unsummoned, broadcast npcinfo changes (pet will be without owner name - means owner offline)
  10433.                 if (getPet() != null)
  10434.                     getPet().broadcastNpcInfo(0);
  10435.             }
  10436.             catch (Throwable t)
  10437.             {
  10438.                 _log.log(Level.SEVERE, "deletedMe()", t);
  10439.             }
  10440.         }
  10441.  
  10442.         if (getClan() != null)
  10443.         {
  10444.             // set the status for pledge member list to OFFLINE
  10445.             try
  10446.             {
  10447.                 L2ClanMember clanMember = getClan().getClanMember(getObjectId());
  10448.                 if (clanMember != null)
  10449.                     clanMember.setPlayerInstance(null);
  10450.             }
  10451.             catch (Throwable t)
  10452.             {
  10453.                 _log.log(Level.SEVERE, "deletedMe()", t);
  10454.             }
  10455.         }
  10456.  
  10457.         if (getActiveRequester() != null)
  10458.         {
  10459.             // deals with sudden exit in the middle of transaction
  10460.             getActiveRequester().setLootInvitation(-1);
  10461.             setActiveRequester(null);
  10462.         }
  10463.  
  10464.         // If the L2PcInstance is a GM, remove it from the GM List
  10465.         if (isGM())
  10466.         {
  10467.             try
  10468.             {
  10469.                 GmListTable.getInstance().deleteGm(this);
  10470.             }
  10471.             catch (Throwable t)
  10472.             {
  10473.                 _log.log(Level.SEVERE, "deletedMe()", t);
  10474.             }
  10475.         }
  10476.  
  10477.         try
  10478.         {
  10479.             // Check if the L2PcInstance is in observer mode to set its position to its position
  10480.             // before entering in observer mode
  10481.             if (inObserverMode())
  10482.  
  10483.                 setXYZInvisible(_obsX, _obsY, _obsZ);
  10484.             else if (isInBoat())
  10485.                 getBoat().oustPlayer(this);
  10486.  
  10487.         }
  10488.         catch (Throwable t)
  10489.         {
  10490.             _log.log(Level.SEVERE, "deletedMe()", t);
  10491.         }
  10492.  
  10493.         // Update database with items in its inventory and remove them from the world
  10494.         try
  10495.         {
  10496.             getInventory().deleteMe();
  10497.         }
  10498.         catch (Throwable t)
  10499.         {
  10500.             _log.log(Level.SEVERE, "deletedMe()", t);
  10501.         }
  10502.  
  10503.         // Update database with items in its warehouse and remove them from the world
  10504.         try
  10505.         {
  10506.             clearWarehouse();
  10507.         }
  10508.         catch (Throwable t)
  10509.         {
  10510.             _log.log(Level.SEVERE, "deletedMe()", t);
  10511.         }
  10512.  
  10513.  
  10514.         if (Config.WAREHOUSE_CACHE)
  10515.  
  10516.             WarehouseCacheManager.getInstance().remCacheTask(this);
  10517.  
  10518.         // Update database with items in its freight and remove them from the world
  10519.         try
  10520.         {
  10521.             getFreight().deleteMe();
  10522.         }
  10523.         catch (Throwable t)
  10524.         {
  10525.             _log.log(Level.SEVERE, "deletedMe()", t);
  10526.         }
  10527.  
  10528.         // Remove all L2Object from _knownObjects and _knownPlayer of the L2Character then cancel Attak or Cast and notify AI
  10529.         try
  10530.         {
  10531.             getKnownList().removeAllKnownObjects();
  10532.         }
  10533.         catch (Throwable t)
  10534.         {
  10535.             _log.log(Level.SEVERE, "deletedMe()", t);
  10536.         }
  10537.  
  10538.         // Close the connection with the client
  10539.         try
  10540.         {
  10541.             setNetConnection(null);
  10542.         }
  10543.         catch (Throwable t)
  10544.         {
  10545.             _log.log(Level.SEVERE, "deletedMe()", t);
  10546.         }
  10547.  
  10548.         // notify friends about disconnect
  10549.         try
  10550.         {
  10551.             notifyFriends();
  10552.             getFriendList().clear();
  10553.         }
  10554.         catch (Throwable t)
  10555.         {
  10556.             _log.log(Level.SEVERE, "deletedMe()", t);
  10557.         }
  10558.  
  10559.         // remove from flood protector
  10560.         FloodProtector.getInstance().removePlayer(getObjectId());
  10561.  
  10562.         if (getClanId() > 0)
  10563.  
  10564.             getClan().broadcastToOtherOnlineMembers(new PledgeShowMemberListUpdate(this), this);
  10565.  
  10566.         for (L2PcInstance player : _SnoopedPlayer)
  10567.             player.removeSnooper(this);
  10568.  
  10569.         for (L2PcInstance player : _SnoopListener)
  10570.             player.removeSnooped(this);
  10571.  
  10572.         // Remove L2Object object from _allObjects of L2World
  10573.         L2World.getInstance().removeObject(this);
  10574.  
  10575.         L2World.getInstance().removeFromAllPlayers(this);
  10576.     }
  10577.  
  10578.  
  10579.     private FishData _fish;
  10580.  
  10581.     public void startFishing(int _x, int _y, int _z)
  10582.     {
  10583.         stopMove(null);
  10584.  
  10585.         changeImmobileLevel(1);
  10586.         _fishing = true;
  10587.         _fishx = _x;
  10588.         _fishy = _y;
  10589.         _fishz = _z;
  10590.         broadcastUserInfo();
  10591.         //Starts fishing
  10592.         int lvl = getRandomFishLvl();
  10593.         int group = getRandomGroup();
  10594.         int type = getRandomFishType(group);
  10595.  
  10596.         List<FishData> fishs = FishTable.getInstance().getfish(lvl, type, group);
  10597.         if (fishs == null || fishs.size() == 0)
  10598.         {
  10599.             sendMessage("Error - Fishes are not defined.");
  10600.             endFishing(false);
  10601.             return;
  10602.         }
  10603.  
  10604.         int check = Rnd.get(fishs.size());
  10605.         _fish = fishs.get(check);
  10606.         fishs.clear();
  10607.         fishs = null;
  10608.         sendPacket(new SystemMessage(SystemMessage.CAST_LINE_AND_START_FISHING));
  10609.         broadcastPacket(new ExFishingStart(this, _fish.getType(), _x, _y, _z));
  10610.         startLookingForFishTask();
  10611.     }
  10612.  
  10613.     public void stopLookingForFishTask()
  10614.     {
  10615.         if (_taskforfish != null)
  10616.         {
  10617.             _taskforfish.cancel(false);
  10618.             _taskforfish = null;
  10619.         }
  10620.     }
  10621.  
  10622.     public void startLookingForFishTask()
  10623.     {
  10624.         if (!isDead() && _taskforfish == null)
  10625.         {
  10626.             int checkDelay = 0;
  10627.  
  10628.             boolean isNoob = false;
  10629.  
  10630.             if (_lure != null)
  10631.             {
  10632.                 int lureid = _lure.getItemId();
  10633.  
  10634.                 isNoob = _fish.getGroup() == 0;
  10635.  
  10636.                 if (lureid == 6519 || lureid == 6522 || lureid == 6525)
  10637.                     checkDelay = Math.round((float)(_fish.getGutsCheckTime() * (1.33)));
  10638.                 else if (lureid == 6520 || lureid == 6523 || lureid == 6526 || (lureid >= 7610 && lureid <= 7613) || (lureid >= 7807 && lureid <= 7809))
  10639.                     checkDelay = Math.round((float)(_fish.getGutsCheckTime() * (1.00)));
  10640.                 else if (lureid == 6521 || lureid == 6524 || lureid == 6527)
  10641.                     checkDelay = Math.round((float)(_fish.getGutsCheckTime() * (0.66)));
  10642.             }      
  10643.             _taskforfish = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new LookingForFishTask(_fish.getWaitTime(), _fish.getFishGuts(), _fish.getType(), isNoob), 10000, checkDelay);
  10644.         }
  10645.     }
  10646.  
  10647.  
  10648.     private int getRandomGroup()
  10649.     {
  10650.         switch (_lure.getItemId())
  10651.  
  10652.         {
  10653.             case 7807: //green for beginners
  10654.             case 7808: //purple for beginners
  10655.             case 7809: //yellow for beginners
  10656.                 return 0;
  10657.             default:
  10658.                 return 1;
  10659.         }
  10660.     }  
  10661.  
  10662.     private int getRandomFishType(int group)
  10663.     {
  10664.         int check = Rnd.get(100);
  10665.         int type = 1;
  10666.         switch (group)
  10667.  
  10668.         {
  10669.             case 0:
  10670.                 switch (_lure.getItemId())
  10671.  
  10672.                 {
  10673.                     case 7807:
  10674.                         if (check <= 54)
  10675.                             type = 5;
  10676.                         else if (check <= 77)
  10677.                             type = 4;
  10678.                         else
  10679.                             type = 6;
  10680.                         break;
  10681.                     case 7808:
  10682.                         if (check <= 54)
  10683.                             type = 4;
  10684.                         else if (check <= 77)
  10685.                             type = 6;
  10686.                         else
  10687.                             type = 5;
  10688.                         break;
  10689.                     case 7809:
  10690.                         if (check <= 54)
  10691.                             type = 6;
  10692.                         else if (check <= 77)
  10693.                             type = 5;
  10694.                         else
  10695.                             type = 4;
  10696.                         break;
  10697.                 }
  10698.                 break;
  10699.             case 1:
  10700.                 switch (_lure.getItemId())
  10701.  
  10702.                 {
  10703.                     case 7610:
  10704.                     case 7611:
  10705.                     case 7612:
  10706.                     case 7613:
  10707.                         type = 3;
  10708.                         break;
  10709.                     case 6519:
  10710.  
  10711.                     case 6520:
  10712.  
  10713.                     case 6521:
  10714.                         if (check <= 54)
  10715.                             type = 1;
  10716.                         else if (check <= 74)
  10717.                             type = 0;
  10718.                         else if (check <= 94)
  10719.                             type = 2;
  10720.                         else
  10721.                             type = 3;
  10722.                         break;
  10723.                     case 6522:
  10724.  
  10725.                     case 6523:
  10726.  
  10727.                     case 6524:
  10728.                         if (check <= 54)
  10729.                             type = 0;
  10730.                         else if (check <= 74)
  10731.                             type = 1;
  10732.                         else if (check <= 94)
  10733.                             type = 2;
  10734.                         else
  10735.                             type = 3;
  10736.                         break;
  10737.                     case 6525:
  10738.  
  10739.                     case 6526:
  10740.  
  10741.                     case 6527:
  10742.                         if (check <= 55)
  10743.                             type = 2;
  10744.                         else if (check <= 74)
  10745.                             type = 1;
  10746.                         else if (check <= 94)
  10747.                             type = 0;
  10748.                         else
  10749.                             type = 3;
  10750.                         break;
  10751.                 }
  10752.         }
  10753.         return type;
  10754.     }
  10755.  
  10756.     private int getRandomFishLvl()
  10757.     {
  10758.         int skilllvl = getSkillLevel(1315);
  10759.         if (skilllvl <= 0)
  10760.             return 1;
  10761.  
  10762.         int randomlvl;
  10763.         int check = Rnd.get(100);
  10764.  
  10765.         if (check <= 50)
  10766.             randomlvl = skilllvl;
  10767.         else if (check <= 85)
  10768.         {
  10769.             randomlvl = skilllvl - 1;
  10770.             if (randomlvl <= 0)
  10771.                 randomlvl = 1;
  10772.         }
  10773.         else
  10774.         {
  10775.  
  10776.             randomlvl = skilllvl + 1;
  10777.             if (randomlvl > 27)
  10778.                 randomlvl = 27;
  10779.         }
  10780.  
  10781.         return randomlvl;
  10782.     }
  10783.  
  10784.     public void startFishCombat(boolean isNoob)
  10785.     {                              
  10786.         _fishCombat = new L2Fishing (this, _fish, isNoob);      
  10787.     }
  10788.  
  10789.     public void endFishing(boolean win)
  10790.     {
  10791.  
  10792.         ExFishingEnd efe = new ExFishingEnd(win, this);
  10793.         broadcastPacket(efe);
  10794.         _fishing = false;
  10795.         _fishx = 0;
  10796.         _fishy = 0;
  10797.         _fishz = 0;
  10798.         broadcastUserInfo();
  10799.         if (_fishCombat == null)
  10800.             sendPacket(new SystemMessage(SystemMessage.BAIT_LOST_FISH_GOT_AWAY));
  10801.         _fishCombat = null;
  10802.         _lure = null;
  10803.         //Ends fishing
  10804.         sendPacket(new SystemMessage(SystemMessage.REEL_LINE_AND_STOP_FISHING));
  10805.         changeImmobileLevel(-1);
  10806.         stopLookingForFishTask();
  10807.     }
  10808.  
  10809.     public L2Fishing getFishCombat()
  10810.     {
  10811.         return _fishCombat;
  10812.     }
  10813.  
  10814.     public int getFishx()
  10815.     {
  10816.         return _fishx;
  10817.     }
  10818.  
  10819.     public int getFishy()
  10820.     {
  10821.         return _fishy;
  10822.     }
  10823.  
  10824.     public int getFishz()
  10825.     {
  10826.         return _fishz;
  10827.     }
  10828.  
  10829.     public void setLure (L2ItemInstance lure)
  10830.     {
  10831.         _lure = lure;
  10832.     }
  10833.  
  10834.     public L2ItemInstance getLure()
  10835.     {
  10836.         return _lure;
  10837.     }
  10838.  
  10839.     public int getInventoryLimit()
  10840.     {
  10841.         int ivlim;
  10842.         if (isGM())
  10843.  
  10844.             ivlim = Config.INVENTORY_MAXIMUM_GM;        
  10845.  
  10846.         else if (getRace() == Race.Dwarf)
  10847.  
  10848.             ivlim = Config.INVENTORY_MAXIMUM_DWARF;
  10849.  
  10850.         else
  10851.  
  10852.             ivlim = Config.INVENTORY_MAXIMUM_NO_DWARF;
  10853.  
  10854.  
  10855.         ivlim += (int)getStat().calcStat(Stats.INV_LIM, 0, null, null);
  10856.  
  10857.  
  10858.         return ivlim;
  10859.  
  10860.     }
  10861.  
  10862.     public int getWareHouseLimit()
  10863.  
  10864.     {
  10865.  
  10866.         int whlim;
  10867.  
  10868.         if (getRace() == Race.Dwarf)
  10869.  
  10870.             whlim = Config.WAREHOUSE_SLOTS_DWARF;
  10871.  
  10872.         else
  10873.  
  10874.             whlim = Config.WAREHOUSE_SLOTS_NO_DWARF;
  10875.  
  10876.  
  10877.         whlim += (int)getStat().calcStat(Stats.WH_LIM, 0, null, null);
  10878.  
  10879.  
  10880.         return whlim;
  10881.     }
  10882.  
  10883.     public int getPrivateSellStoreLimit()
  10884.  
  10885.     {
  10886.  
  10887.         int pslim;
  10888.  
  10889.         if (getRace() == Race.Dwarf)
  10890.  
  10891.             pslim = Config.MAX_PVTSTORE_SLOTS_DWARF;
  10892.  
  10893.         else
  10894.  
  10895.             pslim = Config.MAX_PVTSTORE_SLOTS_OTHER;
  10896.  
  10897.  
  10898.  
  10899.         pslim += (int)getStat().calcStat(Stats.P_SELL_LIM, 0, null, null);
  10900.  
  10901.  
  10902.         return pslim;
  10903.  
  10904.     }
  10905.  
  10906.     public int getPrivateBuyStoreLimit()
  10907.  
  10908.     {
  10909.  
  10910.         int pblim;
  10911.  
  10912.         if (getRace() == Race.Dwarf)
  10913.  
  10914.             pblim = Config.MAX_PVTSTORE_SLOTS_DWARF;
  10915.  
  10916.         else
  10917.  
  10918.             pblim = Config.MAX_PVTSTORE_SLOTS_OTHER;
  10919.  
  10920.  
  10921.         pblim += (int)getStat().calcStat(Stats.P_BUY_LIM, 0, null, null);
  10922.  
  10923.  
  10924.         return pblim;
  10925.  
  10926.     }
  10927.  
  10928.     public int getFreightLimit()
  10929.     {
  10930.         return Config.FREIGHT_SLOTS + (int)getStat().calcStat(Stats.FREIGHT_LIM, 0, null, null);
  10931.     }
  10932.  
  10933.     public int getDwarfRecipeLimit()
  10934.     {
  10935.         int recdlim = Config.DWARF_RECIPE_LIMIT;
  10936.         recdlim += (int)getStat().calcStat(Stats.REC_D_LIM, 0, null, null);
  10937.         return recdlim;
  10938.     }
  10939.  
  10940.     public int getCommonRecipeLimit()
  10941.     {
  10942.         int recclim = Config.COMMON_RECIPE_LIMIT;
  10943.         recclim += (int)getStat().calcStat(Stats.REC_C_LIM, 0, null, null);
  10944.         return recclim;
  10945.     }
  10946.  
  10947.     public int getMountNpcId()
  10948.     {
  10949.         return _mountNpcId;
  10950.     }
  10951.  
  10952.     public int getMountLevel()
  10953.     {
  10954.         return _mountLevel;
  10955.     }
  10956.  
  10957.     public void setMountObjectID(int newID)
  10958.     {
  10959.         _mountObjectID = newID;
  10960.     }
  10961.  
  10962.     public int getMountObjectID()
  10963.     {
  10964.         return _mountObjectID;
  10965.     }
  10966.  
  10967.     private L2ItemInstance _lure = null;
  10968.  
  10969.     /**
  10970.      * Get the current skill in use or return null.<BR><BR>
  10971.      *
  10972.      */
  10973.     public SkillDat getCurrentSkill()
  10974.     {
  10975.         return _currentSkill;
  10976.     }
  10977.  
  10978.  
  10979.     /**
  10980.      * Create a new SkillDat object and set the player _currentSkill.<BR><BR>
  10981.      *
  10982.      */
  10983.     public void setCurrentSkill(L2Skill currentSkill, boolean ctrlPressed, boolean shiftPressed)
  10984.     {
  10985.         if (currentSkill == null)
  10986.         {
  10987.             if (Config.DEBUG)
  10988.                 _log.info("Setting current skill: NULL for " + getName() + ".");
  10989.  
  10990.  
  10991.             _currentSkill = null;
  10992.             return;
  10993.         }
  10994.  
  10995.         if (Config.DEBUG)
  10996.             _log.info("Setting current skill: " + currentSkill.getName() + " (ID: " + currentSkill.getId() + ") for " + getName() + ".");
  10997.  
  10998.  
  10999.         _currentSkill = new SkillDat(currentSkill, ctrlPressed, shiftPressed);
  11000.     }
  11001.  
  11002.     /**
  11003.      * Get the current pet skill in use or return null.<BR><BR>
  11004.      *
  11005.      */
  11006.     public SkillDat getCurrentPetSkill()
  11007.     {
  11008.         return _currentPetSkill;
  11009.     }
  11010.  
  11011.     /**
  11012.      * Create a new SkillDat object and set the player _currentPetSkill.<BR><BR>
  11013.      *
  11014.      */
  11015.     public void setCurrentPetSkill(L2Skill currentPetSkill, boolean ctrlPressed, boolean shiftPressed)
  11016.     {
  11017.         if (currentPetSkill == null)
  11018.         {
  11019.             if (Config.DEBUG)
  11020.                 _log.info("Setting current pet skill: NULL for " + getName() + ".");
  11021.  
  11022.  
  11023.             _currentPetSkill = null;
  11024.             return;
  11025.         }
  11026.  
  11027.         if (Config.DEBUG)
  11028.             _log.info("Setting current pet skill: " + currentPetSkill.getName() + " (ID: " + currentPetSkill.getId() + ") for " + getName() + ".");
  11029.  
  11030.  
  11031.         _currentPetSkill = new SkillDat(currentPetSkill, ctrlPressed, shiftPressed);
  11032.     }
  11033.  
  11034.     public SkillDat getQueuedSkill()
  11035.     {
  11036.         return _queuedSkill;
  11037.     }
  11038.  
  11039.     /**
  11040.      * Create a new SkillDat object and queue it in the player _queuedSkill.<BR><BR>
  11041.      *
  11042.      */
  11043.     public void setQueuedSkill(L2Skill queuedSkill, boolean ctrlPressed, boolean shiftPressed)
  11044.     {
  11045.         if (queuedSkill == null)
  11046.         {
  11047.             if (Config.DEBUG)
  11048.                 _log.info("Setting queued skill: NULL for " + getName() + ".");
  11049.  
  11050.  
  11051.             _queuedSkill = null;
  11052.             return;
  11053.         }
  11054.  
  11055.         if (Config.DEBUG)
  11056.             _log.info("Setting queued skill: " + queuedSkill.getName() + " (ID: " + queuedSkill.getId() + ") for " + getName() + ".");
  11057.  
  11058.  
  11059.         _queuedSkill = new SkillDat(queuedSkill, ctrlPressed, shiftPressed);
  11060.     }
  11061.  
  11062.     public boolean isInJail()
  11063.     {
  11064.         return _inJail;
  11065.     }
  11066.  
  11067.     public void setInJail(boolean state)
  11068.     {
  11069.         _inJail = state;
  11070.     }
  11071.  
  11072.     public void setInJail(boolean state, int delayInMinutes)
  11073.     {
  11074.         _inJail = state;
  11075.         _jailTimer = 0;
  11076.         // Remove the task if any
  11077.         stopJailTask(false);
  11078.  
  11079.  
  11080.         if (_inJail)
  11081.         {
  11082.             if (delayInMinutes > 0)
  11083.             {
  11084.                 _jailTimer = delayInMinutes * 60000; // in millisec
  11085.  
  11086.                 // start the countdown
  11087.                 _jailTask = ThreadPoolManager.getInstance().scheduleGeneral(new JailTask(this), _jailTimer);
  11088.                 sendMessage("You have been jailed for "+delayInMinutes+" minutes.");
  11089.             }
  11090.  
  11091.             if (Olympiad.getInstance().isRegisteredInComp(this))
  11092.                 Olympiad.getInstance().removeDisconnectedCompetitor(this);
  11093.  
  11094.             if (TvTEvent.isEnabled)
  11095.                 TvTEvent.removePlayer(this);
  11096.  
  11097.             // Open a Html message to inform the player
  11098.             NpcHtmlMessage htmlMsg = new NpcHtmlMessage(0);
  11099.             String jailInfos = HtmCache.getInstance().getHtm("data/html/jail_in.htm");
  11100.             if (jailInfos != null)
  11101.                 htmlMsg.setHtml(jailInfos);
  11102.             else
  11103.                 htmlMsg.setHtml("<html><body>You have been put in jail by an admin.</body></html>");
  11104.             sendPacket(htmlMsg);
  11105.  
  11106.             if (inOfflineMode())
  11107.                 closeNetConnection();
  11108.             else
  11109.                 teleToLocation(-114356, -249645, -2984, false);  // Jail
  11110.         }
  11111.         else
  11112.         {
  11113.             // Open a Html message to inform the player
  11114.             NpcHtmlMessage htmlMsg = new NpcHtmlMessage(0);
  11115.             String jailInfos = HtmCache.getInstance().getHtm("data/html/jail_out.htm");
  11116.             if (jailInfos != null)
  11117.                 htmlMsg.setHtml(jailInfos);
  11118.             else
  11119.                 htmlMsg.setHtml("<html><body>You are free for now, respect server rules!</body></html>");
  11120.             sendPacket(htmlMsg);
  11121.  
  11122.  
  11123.             teleToLocation(17836, 170178, -3507, true);  // Floran
  11124.         }
  11125.  
  11126.  
  11127.         // store in database
  11128.         storeCharBase();
  11129.     }
  11130.  
  11131.     public long getJailTimer()
  11132.     {
  11133.         return _jailTimer;
  11134.     }
  11135.  
  11136.     public void setJailTimer(long time)
  11137.     {
  11138.         _jailTimer = time;
  11139.     }
  11140.  
  11141.     private void updateJailState()
  11142.     {
  11143.         if (isInJail())
  11144.         {
  11145.             // If jail time is elapsed, free the player
  11146.             if (_jailTimer > 0)
  11147.             {
  11148.                 // restart the countdown
  11149.                 _jailTask = ThreadPoolManager.getInstance().scheduleGeneral(new JailTask(this), _jailTimer);
  11150.                 sendMessage("You are still in jail for "+Math.round(_jailTimer/60000)+" minutes.");
  11151.             }
  11152.  
  11153.             // If player escaped, put him back in jail
  11154.             if (!isInsideZone(ZONE_JAIL))
  11155.                 teleToLocation(-114356, -249645, -2984, false);
  11156.         }
  11157.     }
  11158.  
  11159.     public void stopJailTask(boolean save)
  11160.     {
  11161.         if (_jailTask != null)
  11162.         {
  11163.             if (save)
  11164.             {
  11165.                 long delay = _jailTask.getDelay(TimeUnit.MILLISECONDS);
  11166.                 if (delay < 0)
  11167.                     delay = 0;
  11168.                 setJailTimer(delay);
  11169.             }
  11170.             _jailTask.cancel(false);
  11171.             _jailTask = null;
  11172.         }
  11173.     }
  11174.  
  11175.     private ScheduledFuture _jailTask;
  11176.     private class JailTask implements Runnable
  11177.     {
  11178.         L2PcInstance _player;
  11179.         protected long _startedAt;
  11180.  
  11181.  
  11182.         protected JailTask(L2PcInstance player)
  11183.         {
  11184.             _player = player;
  11185.             _startedAt = System.currentTimeMillis();
  11186.         }
  11187.  
  11188.         public void run()
  11189.         {
  11190.             _player.setInJail(false, 0);
  11191.         }
  11192.     }
  11193.  
  11194.     private FastMap<Integer, TimeStamp> _reuseTimeStamps = new FastMap<Integer, TimeStamp>().shared();
  11195.  
  11196.     public Collection<TimeStamp> getReuseTimeStamps()
  11197.     {
  11198.         return _reuseTimeStamps.values();
  11199.     }
  11200.  
  11201.     /**
  11202.      * Simple class containing all neccessary information to maintain
  11203.      * valid timestamps and reuse for skills upon relog. Filter this
  11204.      * carefully as it becomes redundant to store reuse for small delays.
  11205.      * @author  Yesod
  11206.      */
  11207.     public class TimeStamp
  11208.     {
  11209.     private int skillId;
  11210.     private long reuse;
  11211.     private long stamp;
  11212.  
  11213.     public TimeStamp(int _skillId, long _reuse)
  11214.     {
  11215.         skillId = _skillId;
  11216.         reuse = _reuse;
  11217.         stamp = System.currentTimeMillis() + reuse;
  11218.     }
  11219.  
  11220.         public TimeStamp(int _skillId, long _reuse, long _systime)
  11221.         {
  11222.             skillId = _skillId;
  11223.             reuse = _reuse;
  11224.             stamp = _systime;
  11225.         }
  11226.  
  11227.         public long getStamp()
  11228.         {
  11229.             return stamp;
  11230.         }
  11231.  
  11232.     public int getSkillId()
  11233.         {
  11234.             return skillId;
  11235.         }
  11236.  
  11237.     public long getReuse()
  11238.         {
  11239.             return reuse;
  11240.         }
  11241.  
  11242.         public long getRemaining()
  11243.         {
  11244.  
  11245.             return Math.max(stamp - System.currentTimeMillis(), 0);
  11246.         }
  11247.  
  11248.     /* Check if the reuse delay has passed and
  11249.      * if it has not then update the stored reuse time
  11250.      * according to what is currently remaining on
  11251.      * the delay.
  11252.          */
  11253.     public boolean hasNotPassed()
  11254.     {
  11255.             if (System.currentTimeMillis() < stamp)
  11256.                 return true;
  11257.  
  11258.  
  11259.         return false;
  11260.     }
  11261.     }
  11262.  
  11263.     /**
  11264.      * Index according to skill id the current
  11265.      * timestamp of use.
  11266.      * @param skillid
  11267.      * @param reuse delay
  11268.      */
  11269.     @Override
  11270.     public void addTimeStamp(int s, int r)
  11271.     {
  11272.     _reuseTimeStamps.put(s, new TimeStamp(s, r));
  11273.     }
  11274.  
  11275.     /**
  11276.      * Index according to skill this TimeStamp
  11277.      * instance for restoration purposes only.
  11278.      * @param TimeStamp
  11279.      */
  11280.     private void addTimeStamp(TimeStamp t)
  11281.     {
  11282.     _reuseTimeStamps.put(t.getSkillId(), t);
  11283.     }
  11284.  
  11285.     /**
  11286.      * Index according to skill id the current
  11287.      * timestamp of use.
  11288.      * @param skillid
  11289.      */
  11290.     @Override
  11291.     public void removeTimeStamp(int s)
  11292.     {
  11293.     _reuseTimeStamps.remove(s);
  11294.     }
  11295.  
  11296.     public int getCharges()
  11297.     {
  11298.         return _charges;
  11299.     }
  11300.  
  11301.     public void addCharge(int number)
  11302.     {
  11303.         _charges += number;
  11304.         sendPacket(new EtcStatusUpdate(this));
  11305.     }
  11306.  
  11307.     public void getSkillList()
  11308.     {
  11309.         SkillList sl = new SkillList();
  11310.         for (L2Skill s : getAllSkills())
  11311.         {
  11312.             if (s == null)
  11313.                 continue;
  11314.             if (s.getId() > 9000)
  11315.                 continue; // Fake skills to change base stats
  11316.             sl.addSkill(s.getId(), s.getLevel(), s.isPassive());
  11317.         }
  11318.         sendPacket(sl);
  11319.  
  11320.     }
  11321.  
  11322.     public boolean isSpawnProtected()
  11323.     {
  11324.         return (_protectEndTime > 0);
  11325.     }
  11326.  
  11327.     public boolean inOfflineMode()
  11328.     {
  11329.         return _inOfflineMode;
  11330.     }
  11331.  
  11332.     public void setInOfflineMode()
  11333.     {
  11334.         _inOfflineMode = true;
  11335.  
  11336.         if (getClan() != null)
  11337.             getClan().broadcastToOtherOnlineMembers(new PledgeShowMemberListUpdate(this), this);
  11338.  
  11339.         leaveParty();
  11340.  
  11341.         if (getPet() != null)
  11342.             getPet().unSummon(this);
  11343.  
  11344.         stopWarnUserTakeBreak();
  11345.     }
  11346.  
  11347.     public long getOfflineStartTime()
  11348.     {
  11349.         return _offlineShopStart;
  11350.     }
  11351.  
  11352.     public void setOfflineStartTime(long time)
  11353.     {
  11354.         _offlineShopStart = time;
  11355.     }
  11356.  
  11357.     public final void sendDamageMessage(L2Character target, int damage, boolean mcrit, boolean pcrit, boolean miss)
  11358.     {
  11359.         // Check if hit is missed
  11360.         if (miss)
  11361.         {
  11362.             sendPacket(new SystemMessage(SystemMessage.MISSED_TARGET));
  11363.             return;
  11364.         }
  11365.  
  11366.         // Check if hit is critical
  11367.         if (pcrit)
  11368.             sendPacket(new SystemMessage(SystemMessage.CRITICAL_HIT));
  11369.         if (mcrit)
  11370.             sendPacket(new SystemMessage(SystemMessage.CRITICAL_HIT_MAGIC));
  11371.  
  11372.         if (isInOlympiadMode() && target instanceof L2PcInstance
  11373.                 && ((L2PcInstance)target).isInOlympiadMode()
  11374.                 && ((L2PcInstance)target).getOlympiadGameId() == getOlympiadGameId())
  11375.             dmgDealt += damage;
  11376.  
  11377.         SystemMessage sm = new SystemMessage(SystemMessage.YOU_DID_S1_DMG);
  11378.         sm.addNumber(damage);
  11379.         sendPacket(sm);
  11380.     }
  11381.  
  11382.     class FeedTask implements Runnable
  11383.     {
  11384.         public void run()
  11385.         {
  11386.             try
  11387.             {
  11388.                 if (!isMounted())
  11389.                 {
  11390.                     stopFeed();
  11391.                     return;
  11392.                 }
  11393.    
  11394.                 if (getCurrentFeed() > getFeedConsume())
  11395.                     setCurrentFeed(getCurrentFeed()-getFeedConsume());
  11396.                 else
  11397.                 {
  11398.                     // go back to pet control item, or simply said, unsummon it
  11399.                     setCurrentFeed(0);
  11400.                     stopFeed();
  11401.                     dismount();
  11402.                     sendPacket(new SystemMessage(SystemMessage.OUT_OF_FEED_MOUNT_CANCELED));
  11403.                 }
  11404.  
  11405.                 int[] foodIds = L2PetDataTable.getFoodItemId(getMountNpcId());
  11406.                 if (foodIds[0] == 0)
  11407.                     return;
  11408.  
  11409.                 L2ItemInstance food = getInventory().getItemByItemId(foodIds[0]);
  11410.  
  11411.                 // use better strider food if exists
  11412.                 if (L2PetDataTable.isStrider(getMountNpcId()))
  11413.                 {
  11414.                     if (getInventory().getItemByItemId(foodIds[1]) != null)
  11415.                         food = getInventory().getItemByItemId(foodIds[1]);
  11416.                 }
  11417.  
  11418.                 if (food != null && isHungry())
  11419.                 {
  11420.                     IItemHandler handler = ItemHandler.getInstance().getItemHandler(food.getItemId());
  11421.                     if (handler != null)
  11422.                     {
  11423.                         handler.useItem(L2PcInstance.this, food);
  11424.                         SystemMessage sm = new SystemMessage(SystemMessage.PET_TOOK_S1_BECAUSE_HE_WAS_HUNGRY);
  11425.                         sm.addItemName(food.getItemId());
  11426.                         sendPacket(sm);
  11427.                     }
  11428.                 }
  11429.             }
  11430.             catch (Exception e)
  11431.             {
  11432.                 _log.log(Level.SEVERE, "Mounted Pet [NpcId: "+getMountNpcId()+"] a feed task error has occurred", e);
  11433.             }
  11434.         }
  11435.     }
  11436.  
  11437.     protected synchronized void startFeed(int npcId)
  11438.     {
  11439.         _canFeed = npcId > 0;
  11440.         if (!isMounted())
  11441.             return;
  11442.  
  11443.         if (getPet() != null)
  11444.         {
  11445.             setCurrentFeed(((L2PetInstance) getPet()).getCurrentFed());
  11446.             _controlItemId = getPet().getControlItemId();
  11447.             sendPacket(new SetupGauge(3, getCurrentFeed()*10000/getFeedConsume(), getMaxFeed()*10000/getFeedConsume()));
  11448.             if (!isDead())
  11449.                 _mountFeedTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new FeedTask(), 10000, 10000);
  11450.         }
  11451.         else if (_canFeed)
  11452.         {
  11453.             setCurrentFeed(getMaxFeed());
  11454.             sendPacket(new SetupGauge(3, getCurrentFeed()*10000/getFeedConsume(), getMaxFeed()*10000/getFeedConsume()));
  11455.             if (!isDead())
  11456.                 _mountFeedTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new FeedTask(), 10000, 10000);
  11457.         }
  11458.     }
  11459.  
  11460.     protected synchronized void stopFeed()
  11461.     {
  11462.         if (_mountFeedTask != null)
  11463.         {
  11464.             _mountFeedTask.cancel(false);
  11465.             _mountFeedTask = null;
  11466.             if (Config.DEBUG)
  11467.                 _log.fine("Pet [#"+_mountNpcId+"] feed task stop");
  11468.         }
  11469.     }
  11470.  
  11471.     protected final void clearPetData()
  11472.     {
  11473.         _data = null;
  11474.     }
  11475.  
  11476.     protected final L2PetData getPetData(int npcId)
  11477.     {
  11478.         if (_data == null && getPet() != null)
  11479.             _data = L2PetDataTable.getInstance().getPetData(getPet().getNpcId(), getPet().getLevel());
  11480.         else if (_data == null && npcId > 0)
  11481.             _data = L2PetDataTable.getInstance().getPetData(npcId, getLevel());
  11482.  
  11483.         return _data;
  11484.     }
  11485.  
  11486.     public int getCurrentFeed()
  11487.     {
  11488.         return _curFeed;
  11489.     }
  11490.  
  11491.     protected int getFeedConsume()
  11492.     {
  11493.         // if pet is attacking
  11494.         if (isAttackingNow())
  11495.             return getPetData(_mountNpcId).getPetFeedBattle();
  11496.         else
  11497.             return getPetData(_mountNpcId).getPetFeedNormal();
  11498.     }
  11499.  
  11500.     public void setCurrentFeed(int num)
  11501.     {
  11502.         _curFeed = num > getMaxFeed() ? getMaxFeed() : num;
  11503.         sendPacket(new SetupGauge(3, getCurrentFeed()*10000/getFeedConsume(), getMaxFeed()*10000/getFeedConsume()));
  11504.     }
  11505.  
  11506.     protected int getMaxFeed()
  11507.     {
  11508.         return getPetData(_mountNpcId).getPetMaxFeed();
  11509.     }
  11510.  
  11511.     protected boolean isHungry()
  11512.     {
  11513.         return _canFeed ? (getCurrentFeed() < (0.55 * getPetData(getMountNpcId()).getPetMaxFeed())):false;
  11514.     }
  11515.  
  11516.     public class dismount implements Runnable
  11517.     {
  11518.         public void run()
  11519.         {
  11520.             try
  11521.             {
  11522.                 L2PcInstance.this.dismount();
  11523.             }
  11524.             catch (Exception e)
  11525.             {
  11526.                 e.printStackTrace();
  11527.             }
  11528.         }
  11529.     }
  11530.  
  11531.     public void enteredNoLanding()
  11532.     {
  11533.         _dismountTask = ThreadPoolManager.getInstance().scheduleGeneral(new L2PcInstance.dismount(), 5000);
  11534.     }
  11535.  
  11536.     public void exitedNoLanding()
  11537.     {
  11538.         if (_dismountTask != null)
  11539.         {
  11540.             _dismountTask.cancel(true);
  11541.             _dismountTask = null;
  11542.         }
  11543.     }
  11544.  
  11545.     public void storePetFood(int petId)
  11546.     {
  11547.         if (_controlItemId != 0 && petId != 0)
  11548.         {
  11549.             String req;
  11550.             req = "UPDATE pets SET fed=? WHERE item_obj_id = ?";
  11551.             java.sql.Connection con = null;
  11552.  
  11553.             try
  11554.             {
  11555.                 con = L2DatabaseFactory.getInstance().getConnection();
  11556.                 PreparedStatement statement = con.prepareStatement(req);
  11557.                 statement.setInt(1, getCurrentFeed());
  11558.                 statement.setInt(2, _controlItemId);
  11559.                 statement.executeUpdate();
  11560.                 statement.close();
  11561.                 _controlItemId = 0;
  11562.             }
  11563.             catch (Exception e)
  11564.             {
  11565.                 _log.log(Level.SEVERE, "Failed to store Pet [NpcId: "+petId+"] data", e);
  11566.             }
  11567.             finally
  11568.             {
  11569.                 try
  11570.                 {
  11571.                     con.close();
  11572.                 }
  11573.                 catch (Exception e) {}
  11574.             }
  11575.         }
  11576.     }
  11577.  
  11578.     /**
  11579.      * Return true if character falling now
  11580.      * On the start of fall return false for correct coord sync !
  11581.      */
  11582.     public final boolean isFalling(int z)
  11583.     {
  11584.         if (isDead() || isFlying() || isInsideZone(ZONE_WATER))
  11585.             return false;
  11586.  
  11587.         if (System.currentTimeMillis() < _fallingTimestamp)
  11588.             return true;
  11589.  
  11590.         final int deltaZ = getZ() - z;
  11591.         if (deltaZ <= getBaseTemplate().getFallHeight())
  11592.             return false;
  11593.  
  11594.         final int damage = (int)Formulas.getInstance().calcFallDam(this, deltaZ);
  11595.         if (damage > 0)
  11596.         {
  11597.             reduceCurrentHp(Math.min(damage, getCurrentHp() - 1), null, false);
  11598.             SystemMessage sm = new SystemMessage(SystemMessage.FALL_DAMAGE_S1);
  11599.             sm.addNumber(damage);
  11600.             sendPacket(sm);
  11601.         }
  11602.         setFalling();
  11603.  
  11604.         return false;
  11605.     }
  11606.  
  11607.     public void gatesRequest(L2DoorInstance door)
  11608.     {
  11609.         _gatesRequest.setTarget(door);
  11610.     }
  11611.  
  11612.     public void gatesAnswer(int answer, int type)
  11613.     {
  11614.         if (_gatesRequest.getDoor() == null)
  11615.             return;
  11616.         if (answer == 1 && getTarget() == _gatesRequest.getDoor() && type == 1)
  11617.             _gatesRequest.getDoor().openMe();
  11618.         else if (answer == 1 && getTarget() == _gatesRequest.getDoor() && type == 0)
  11619.             _gatesRequest.getDoor().closeMe();
  11620.         _gatesRequest.setTarget(null);
  11621.     }
  11622.  
  11623.     public final void setFalling()
  11624.     {
  11625.         _fallingTimestamp = System.currentTimeMillis() + FALLING_VALIDATION_DELAY;
  11626.     }
  11627.  
  11628.     public void setGainXpSp(boolean XpSp)
  11629.     {
  11630.         _getGainXpSp = XpSp;
  11631.     }
  11632.  
  11633.     public boolean getGainXpSp()
  11634.     {
  11635.         return _getGainXpSp;
  11636.     }
  11637.  
  11638.     public boolean isPendingSitting()
  11639.     {
  11640.         return _isPendingSitting;
  11641.     }
  11642.  
  11643.     public void setIsPendingSitting(boolean sit)
  11644.     {
  11645.         _isPendingSitting = sit;
  11646.     }
  11647.  
  11648.     public int getLootInvitation()
  11649.     {
  11650.         return _lootInvitation;
  11651.     }
  11652.  
  11653.     public void setLootInvitation(int loot)
  11654.     {
  11655.         _lootInvitation = loot;
  11656.     }
  11657.  
  11658.     public double getCollisionRadius()
  11659.     {
  11660.         if (getAppearance().getSex())
  11661.             return getBaseTemplate().collisionRadius_female;
  11662.         else
  11663.             return getBaseTemplate().collisionRadius;
  11664.     }
  11665.  
  11666.     public double getCollisionHeight()
  11667.     {
  11668.         if (getAppearance().getSex())
  11669.             return getBaseTemplate().collisionHeight_female;
  11670.         else
  11671.             return getBaseTemplate().collisionHeight;
  11672.     }
  11673.  
  11674.     public static class Friend
  11675.     {
  11676.         private int _objectId;
  11677.         private String _name;
  11678.         private int _online;
  11679.  
  11680.         public Friend(int objectId, String name)
  11681.         {
  11682.             _objectId = objectId;
  11683.             _name = name;
  11684.         }
  11685.  
  11686.         public int getObjectId()
  11687.         {
  11688.             return _objectId;
  11689.         }
  11690.  
  11691.         public String getName()
  11692.         {
  11693.             return _name;
  11694.         }
  11695.  
  11696.         public void setName(String name)
  11697.         {
  11698.             _name = name;
  11699.         }
  11700.  
  11701.         public int isOnline()
  11702.         {
  11703.             return _online;
  11704.         }
  11705.  
  11706.         public void setOnline(int online)
  11707.         {
  11708.             _online = online;
  11709.         }
  11710.     }
  11711.  
  11712.     public List<Friend> getFriendList()
  11713.     {
  11714.         return _friendList;
  11715.     }
  11716.  
  11717.     public Friend getFriend(String name)
  11718.     {
  11719.         for (Friend friend : getFriendList())
  11720.         {
  11721.              if (friend == null)
  11722.                  continue;
  11723.  
  11724.              if (friend.getName().equalsIgnoreCase(name))
  11725.                  return friend;
  11726.         }
  11727.         return null;
  11728.     }
  11729.  
  11730.     /**
  11731.      * Check for Olympiad restrictions
  11732.      */
  11733.     public boolean checkOlympiadConditions()
  11734.     {
  11735.         if (!isNoble())
  11736.         {
  11737.  
  11738.             sendPacket(new SystemMessage(SystemMessage.ONLY_NOBLESS_CAN_PARTICIPATE_IN_THE_OLYMPIAD));
  11739.             return false;
  11740.         }
  11741.  
  11742.         if (getInventoryLimit() * 0.8 <= getInventory().getSize())
  11743.         {
  11744.  
  11745.             sendPacket(new SystemMessage(SystemMessage.SINCE_80_PERCENT_OR_MORE_OF_YOUR_INVENTORY_SLOTS_ARE_FULL_YOU_CANNOT_PARTICIPATE_IN_THE_OLYMPIAD));
  11746.             return false;
  11747.         }
  11748.  
  11749.         if (isFestivalParticipant())
  11750.         {
  11751.             sendMessage("Festival participants cannot register to the Grand Olympiad games.");
  11752.             return false;
  11753.         }
  11754.  
  11755.         if (isDead())
  11756.             return false;
  11757.  
  11758.         if (getBaseClass() != getClassId().getId())
  11759.         {
  11760.             sendPacket(new SystemMessage(SystemMessage.YOU_CANT_JOIN_THE_OLYMPIAD_WITH_A_SUB_JOB_CHARACTER));
  11761.             return false;
  11762.         }
  11763.  
  11764.         if (getEventTeam() > 0 || TvTEvent.isRegistered(this))
  11765.  
  11766.         {
  11767.             sendMessage("TvT Participants cannot register to the Grand Olympiad Games.");
  11768.             return false;
  11769.         }
  11770.  
  11771.         return true;
  11772.     }
  11773. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement