Advertisement
Guest User

Untitled

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