Advertisement
Guest User

Untitled

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