Advertisement
Guest User

Untitled

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