Guest User

Untitled

a guest
Jul 24th, 2016
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 425.26 KB | None | 0 0
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation, either version 3 of the License, or (at your option) any later
  5. * version.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT
  8. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. * details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with
  13. * this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package net.sf.l2j.gameserver.model.actor.instance;
  16.  
  17. import java.sql.Connection;
  18. import java.sql.PreparedStatement;
  19. import java.sql.ResultSet;
  20. import java.sql.SQLException;
  21. import java.util.ArrayList;
  22. import java.util.Arrays;
  23. import java.util.Calendar;
  24. import java.util.Collection;
  25. import java.util.LinkedList;
  26. import java.util.List;
  27. import java.util.Map;
  28. import java.util.concurrent.Future;
  29. import java.util.concurrent.ScheduledFuture;
  30. import java.util.concurrent.TimeUnit;
  31. import java.util.concurrent.atomic.AtomicInteger;
  32. import java.util.concurrent.locks.ReentrantLock;
  33. import java.util.logging.Level;
  34. import java.sql.Statement;
  35.  
  36. import javolution.text.TextBuilder;
  37. import javolution.util.FastList;
  38. import javolution.util.FastMap;
  39. import net.sf.l2j.Config;
  40. import net.sf.l2j.RandomFight;
  41. import net.sf.l2j.achievementEngine.AchievementsManager;
  42. import net.sf.l2j.L2DatabaseFactory;
  43. import net.sf.l2j.gameserver.Announcements;
  44. import net.sf.l2j.gameserver.GameTimeController;
  45. import net.sf.l2j.gameserver.GeoData;
  46. import net.sf.l2j.gameserver.GmListTable;
  47. import net.sf.l2j.gameserver.ItemsAutoDestroy;
  48. import net.sf.l2j.gameserver.LoginServerThread;
  49. import net.sf.l2j.gameserver.RecipeController;
  50. import net.sf.l2j.gameserver.SevenSigns;
  51. import net.sf.l2j.gameserver.SevenSignsFestival;
  52. import net.sf.l2j.gameserver.ThreadPoolManager;
  53. import net.sf.l2j.gameserver.Universe;
  54. import net.sf.l2j.gameserver.ai.CtrlIntention;
  55. import net.sf.l2j.gameserver.ai.L2CharacterAI;
  56. import net.sf.l2j.gameserver.ai.L2PlayerAI;
  57. import net.sf.l2j.gameserver.ai.L2SummonAI;
  58. import net.sf.l2j.gameserver.cache.HtmCache;
  59. import net.sf.l2j.gameserver.cache.WarehouseCacheManager;
  60. import net.sf.l2j.gameserver.communitybbs.BB.Forum;
  61. import net.sf.l2j.gameserver.communitybbs.Manager.ForumsBBSManager;
  62. import net.sf.l2j.gameserver.communitybbs.Manager.RegionBBSManager;
  63. import net.sf.l2j.gameserver.datatables.AccessLevels;
  64. import net.sf.l2j.gameserver.datatables.AdminCommandAccessRights;
  65. import net.sf.l2j.gameserver.datatables.CharTemplateTable;
  66. import net.sf.l2j.gameserver.datatables.ClanTable;
  67. import net.sf.l2j.gameserver.datatables.FishTable;
  68. import net.sf.l2j.gameserver.datatables.HennaTable;
  69. import net.sf.l2j.gameserver.datatables.HeroSkillTable;
  70. import net.sf.l2j.gameserver.datatables.ItemTable;
  71. import net.sf.l2j.gameserver.datatables.MapRegionTable;
  72. import net.sf.l2j.gameserver.datatables.NobleSkillTable;
  73. import net.sf.l2j.gameserver.datatables.NpcTable;
  74. import net.sf.l2j.gameserver.datatables.SkillTable;
  75. import net.sf.l2j.gameserver.datatables.SkillTreeTable;
  76. import net.sf.l2j.gameserver.handler.AdminCommandHandler;
  77. import net.sf.l2j.gameserver.handler.IAdminCommandHandler;
  78. import net.sf.l2j.gameserver.handler.IItemHandler;
  79. import net.sf.l2j.gameserver.handler.ItemHandler;
  80. import net.sf.l2j.gameserver.instancemanager.CastleManager;
  81. import net.sf.l2j.gameserver.instancemanager.CoupleManager;
  82. import net.sf.l2j.gameserver.instancemanager.CursedWeaponsManager;
  83. import net.sf.l2j.gameserver.instancemanager.DimensionalRiftManager;
  84. import net.sf.l2j.gameserver.instancemanager.DuelManager;
  85. import net.sf.l2j.gameserver.instancemanager.FortManager;
  86. import net.sf.l2j.gameserver.instancemanager.FortSiegeManager;
  87. import net.sf.l2j.gameserver.instancemanager.InstanceManager;
  88. import net.sf.l2j.gameserver.instancemanager.ItemsOnGroundManager;
  89. import net.sf.l2j.gameserver.instancemanager.QuestManager;
  90. import net.sf.l2j.gameserver.instancemanager.SiegeManager;
  91. import net.sf.l2j.gameserver.model.BlockList;
  92. import net.sf.l2j.gameserver.model.Elementals;
  93. import net.sf.l2j.gameserver.model.FishData;
  94. import net.sf.l2j.gameserver.model.L2AccessLevel;
  95. import net.sf.l2j.gameserver.model.L2CharPosition;
  96. import net.sf.l2j.gameserver.model.L2Clan;
  97. import net.sf.l2j.gameserver.model.L2ClanMember;
  98. import net.sf.l2j.gameserver.model.L2Effect;
  99. import net.sf.l2j.gameserver.model.L2Fishing;
  100. import net.sf.l2j.gameserver.model.L2HennaInstance;
  101. import net.sf.l2j.gameserver.model.L2ItemInstance;
  102. import net.sf.l2j.gameserver.model.L2Macro;
  103. import net.sf.l2j.gameserver.model.L2ManufactureList;
  104. import net.sf.l2j.gameserver.model.L2Object;
  105. import net.sf.l2j.gameserver.model.L2Party;
  106. import net.sf.l2j.gameserver.model.L2PetData;
  107. import net.sf.l2j.gameserver.model.L2PetDataTable;
  108. import net.sf.l2j.gameserver.model.L2Radar;
  109. import net.sf.l2j.gameserver.model.L2RecipeList;
  110. import net.sf.l2j.gameserver.model.L2Request;
  111. import net.sf.l2j.gameserver.model.L2ShortCut;
  112. import net.sf.l2j.gameserver.model.L2Skill;
  113. import net.sf.l2j.gameserver.model.L2SkillLearn;
  114. import net.sf.l2j.gameserver.model.L2Transformation;
  115. import net.sf.l2j.gameserver.model.L2World;
  116. import net.sf.l2j.gameserver.model.L2WorldRegion;
  117. import net.sf.l2j.gameserver.model.MacroList;
  118. import net.sf.l2j.gameserver.model.ShortCuts;
  119. import net.sf.l2j.gameserver.model.TradeList;
  120. import net.sf.l2j.gameserver.model.L2Skill.SkillTargetType;
  121. import net.sf.l2j.gameserver.model.actor.L2Attackable;
  122. import net.sf.l2j.gameserver.model.actor.L2Character;
  123. import net.sf.l2j.gameserver.model.actor.L2Decoy;
  124. import net.sf.l2j.gameserver.model.actor.L2Npc;
  125. import net.sf.l2j.gameserver.model.actor.L2Playable;
  126. import net.sf.l2j.gameserver.model.actor.L2Summon;
  127. import net.sf.l2j.gameserver.model.actor.L2Trap;
  128. import net.sf.l2j.gameserver.model.actor.appearance.PcAppearance;
  129. import net.sf.l2j.gameserver.model.actor.knownlist.PcKnownList;
  130. import net.sf.l2j.gameserver.model.actor.position.PcPosition;
  131. import net.sf.l2j.gameserver.model.actor.stat.PcStat;
  132. import net.sf.l2j.gameserver.model.actor.status.PcStatus;
  133. import net.sf.l2j.gameserver.model.base.ClassId;
  134. import net.sf.l2j.gameserver.model.base.ClassLevel;
  135. import net.sf.l2j.gameserver.model.base.Experience;
  136. import net.sf.l2j.gameserver.model.base.PlayerClass;
  137. import net.sf.l2j.gameserver.model.base.Race;
  138. import net.sf.l2j.gameserver.model.base.SubClass;
  139. import net.sf.l2j.gameserver.model.entity.Castle;
  140. import net.sf.l2j.gameserver.model.entity.Duel;
  141. import net.sf.l2j.gameserver.model.entity.Fort;
  142. import net.sf.l2j.gameserver.model.entity.Instance;
  143. import net.sf.l2j.gameserver.model.entity.L2Event;
  144. import net.sf.l2j.gameserver.model.entity.Siege;
  145. import net.sf.l2j.gameserver.model.entity.TvTEvent;
  146. import net.sf.l2j.gameserver.model.itemcontainer.Inventory;
  147. import net.sf.l2j.gameserver.model.itemcontainer.ItemContainer;
  148. import net.sf.l2j.gameserver.model.itemcontainer.PcFreight;
  149. import net.sf.l2j.gameserver.model.itemcontainer.PcInventory;
  150. import net.sf.l2j.gameserver.model.itemcontainer.PcWarehouse;
  151. import net.sf.l2j.gameserver.model.itemcontainer.PetInventory;
  152. import net.sf.l2j.gameserver.model.olympiad.Olympiad;
  153. import net.sf.l2j.gameserver.model.quest.Quest;
  154. import net.sf.l2j.gameserver.model.quest.QuestState;
  155. import net.sf.l2j.gameserver.model.quest.State;
  156. import net.sf.l2j.gameserver.network.L2GameClient;
  157. import net.sf.l2j.gameserver.network.SystemMessageId;
  158. import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
  159. import net.sf.l2j.gameserver.network.serverpackets.ChangeWaitType;
  160. import net.sf.l2j.gameserver.network.serverpackets.CharInfo;
  161. import net.sf.l2j.gameserver.network.serverpackets.ConfirmDlg;
  162. import net.sf.l2j.gameserver.network.serverpackets.EnchantResult;
  163. import net.sf.l2j.gameserver.network.serverpackets.EtcStatusUpdate;
  164. import net.sf.l2j.gameserver.network.serverpackets.ExAutoSoulShot;
  165. import net.sf.l2j.gameserver.network.serverpackets.ExBrExtraUserInfo;
  166. import net.sf.l2j.gameserver.network.serverpackets.ExDuelUpdateUserInfo;
  167. import net.sf.l2j.gameserver.network.serverpackets.ExFishingEnd;
  168. import net.sf.l2j.gameserver.network.serverpackets.ExFishingStart;
  169. import net.sf.l2j.gameserver.network.serverpackets.ExGetBookMarkInfoPacket;
  170. import net.sf.l2j.gameserver.network.serverpackets.ExGetOnAirShip;
  171. import net.sf.l2j.gameserver.network.serverpackets.ExOlympiadMode;
  172. import net.sf.l2j.gameserver.network.serverpackets.ExOlympiadUserInfo;
  173. import net.sf.l2j.gameserver.network.serverpackets.ExPrivateStoreSetWholeMsg;
  174. import net.sf.l2j.gameserver.network.serverpackets.ExSetCompassZoneCode;
  175. import net.sf.l2j.gameserver.network.serverpackets.ExShowScreenMessage;
  176. import net.sf.l2j.gameserver.network.serverpackets.ExSpawnEmitter;
  177. import net.sf.l2j.gameserver.network.serverpackets.ExStorageMaxCount;
  178. import net.sf.l2j.gameserver.network.serverpackets.ExVitalityPointInfo;
  179. import net.sf.l2j.gameserver.network.serverpackets.GMHide;
  180. import net.sf.l2j.gameserver.network.serverpackets.GameGuardQuery;
  181. import net.sf.l2j.gameserver.network.serverpackets.GetOnVehicle;
  182. import net.sf.l2j.gameserver.network.serverpackets.HennaInfo;
  183. import net.sf.l2j.gameserver.network.serverpackets.InventoryUpdate;
  184. import net.sf.l2j.gameserver.network.serverpackets.ItemList;
  185. import net.sf.l2j.gameserver.network.serverpackets.L2GameServerPacket;
  186. import net.sf.l2j.gameserver.network.serverpackets.LeaveWorld;
  187. import net.sf.l2j.gameserver.network.serverpackets.MagicSkillUse;
  188. import net.sf.l2j.gameserver.network.serverpackets.MyTargetSelected;
  189. import net.sf.l2j.gameserver.network.serverpackets.NicknameChanged;
  190. import net.sf.l2j.gameserver.network.serverpackets.NpcHtmlMessage;
  191. import net.sf.l2j.gameserver.network.serverpackets.ObservationMode;
  192. import net.sf.l2j.gameserver.network.serverpackets.ObservationReturn;
  193. import net.sf.l2j.gameserver.network.serverpackets.PartySmallWindowUpdate;
  194. import net.sf.l2j.gameserver.network.serverpackets.PetInventoryUpdate;
  195. import net.sf.l2j.gameserver.network.serverpackets.PledgeShowMemberListDelete;
  196. import net.sf.l2j.gameserver.network.serverpackets.PledgeShowMemberListUpdate;
  197. import net.sf.l2j.gameserver.network.serverpackets.PrivateStoreListBuy;
  198. import net.sf.l2j.gameserver.network.serverpackets.PrivateStoreListSell;
  199. import net.sf.l2j.gameserver.network.serverpackets.PrivateStoreManageListBuy;
  200. import net.sf.l2j.gameserver.network.serverpackets.PrivateStoreManageListSell;
  201. import net.sf.l2j.gameserver.network.serverpackets.PrivateStoreMsgBuy;
  202. import net.sf.l2j.gameserver.network.serverpackets.PrivateStoreMsgSell;
  203. import net.sf.l2j.gameserver.network.serverpackets.QuestList;
  204. import net.sf.l2j.gameserver.network.serverpackets.RecipeShopMsg;
  205. import net.sf.l2j.gameserver.network.serverpackets.RecipeShopSellList;
  206. import net.sf.l2j.gameserver.network.serverpackets.RelationChanged;
  207. import net.sf.l2j.gameserver.network.serverpackets.Ride;
  208. import net.sf.l2j.gameserver.network.serverpackets.SetupGauge;
  209. import net.sf.l2j.gameserver.network.serverpackets.ShortBuffStatusUpdate;
  210. import net.sf.l2j.gameserver.network.serverpackets.ShortCutInit;
  211. import net.sf.l2j.gameserver.network.serverpackets.SkillCoolTime;
  212. import net.sf.l2j.gameserver.network.serverpackets.SkillList;
  213. import net.sf.l2j.gameserver.network.serverpackets.Snoop;
  214. import net.sf.l2j.gameserver.network.serverpackets.SocialAction;
  215. import net.sf.l2j.gameserver.network.serverpackets.SpecialCamera;
  216. import net.sf.l2j.gameserver.network.serverpackets.StatusUpdate;
  217. import net.sf.l2j.gameserver.network.serverpackets.StopMove;
  218. import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
  219. import net.sf.l2j.gameserver.network.serverpackets.TargetSelected;
  220. import net.sf.l2j.gameserver.network.serverpackets.TargetUnselected;
  221. import net.sf.l2j.gameserver.network.serverpackets.TradeDone;
  222. import net.sf.l2j.gameserver.network.serverpackets.TradeOtherDone;
  223. import net.sf.l2j.gameserver.network.serverpackets.TradeStart;
  224. import net.sf.l2j.gameserver.network.serverpackets.UserInfo;
  225. import net.sf.l2j.gameserver.network.serverpackets.ValidateLocation;
  226. import net.sf.l2j.gameserver.skills.Formulas;
  227. import net.sf.l2j.gameserver.skills.Stats;
  228. import net.sf.l2j.gameserver.skills.l2skills.L2SkillSiegeFlag;
  229. import net.sf.l2j.gameserver.templates.chars.L2PcTemplate;
  230. import net.sf.l2j.gameserver.templates.item.L2Armor;
  231. import net.sf.l2j.gameserver.templates.item.L2ArmorType;
  232. import net.sf.l2j.gameserver.templates.item.L2EtcItemType;
  233. import net.sf.l2j.gameserver.templates.item.L2Henna;
  234. import net.sf.l2j.gameserver.templates.item.L2Item;
  235. import net.sf.l2j.gameserver.templates.item.L2Weapon;
  236. import net.sf.l2j.gameserver.templates.item.L2WeaponType;
  237. import net.sf.l2j.gameserver.templates.skills.L2EffectType;
  238. import net.sf.l2j.gameserver.templates.skills.L2SkillType;
  239. import net.sf.l2j.gameserver.util.FloodProtectors;
  240. import net.sf.l2j.gameserver.util.Util;
  241. import net.sf.l2j.util.Point3D;
  242. import net.sf.l2j.util.Rnd;
  243.  
  244. /**
  245. * This class represents all player characters in the world.
  246. * There is always a client-thread connected to this (except if a player-store is activated upon logout).<BR><BR>
  247. *
  248. * @version $Revision: 1.66.2.41.2.33 $ $Date: 2005/04/11 10:06:09 $
  249. */
  250. public final class L2PcInstance extends L2Playable
  251. {
  252.  
  253. public boolean inLHE = false;
  254.  
  255. // Character Skill SQL String Definitions:
  256. private static final String RESTORE_SKILLS_FOR_CHAR = "SELECT skill_id,skill_level FROM character_skills WHERE charId=? AND class_index=?";
  257. private static final String ADD_NEW_SKILL = "INSERT INTO character_skills (charId,skill_id,skill_level,class_index) VALUES (?,?,?,?)";
  258. private static final String UPDATE_CHARACTER_SKILL_LEVEL = "UPDATE character_skills SET skill_level=? WHERE skill_id=? AND charId=? AND class_index=?";
  259. private static final String DELETE_SKILL_FROM_CHAR = "DELETE FROM character_skills WHERE skill_id=? AND charId=? AND class_index=?";
  260. private static final String DELETE_CHAR_SKILLS = "DELETE FROM character_skills WHERE charId=? AND class_index=?";
  261.  
  262. // Character Skill Save SQL String Definitions:
  263. private static final String ADD_SKILL_SAVE = "INSERT INTO character_skills_save (charId,skill_id,skill_level,effect_count,effect_cur_time,reuse_delay,systime,restore_type,class_index,buff_index) VALUES (?,?,?,?,?,?,?,?,?,?)";
  264. private static final String RESTORE_SKILL_SAVE = "SELECT skill_id,skill_level,effect_count,effect_cur_time, reuse_delay, systime FROM character_skills_save WHERE charId=? AND class_index=? AND restore_type=? ORDER BY buff_index ASC";
  265. private static final String DELETE_SKILL_SAVE = "DELETE FROM character_skills_save WHERE charId=? AND class_index=?";
  266.  
  267. // Character Character SQL String Definitions:
  268. private static final String INSERT_CHARACTER = "INSERT INTO characters (account_name,charId,char_name,level,maxHp,curHp,maxCp,curCp,maxMp,curMp,face,hairStyle,hairColor,sex,exp,sp,karma,fame,pvpkills,pkkills,clanid,race,classid,deletetime,cancraft,title,accesslevel,online,isin7sdungeon,clan_privs,wantspeace,base_class,newbie,nobless,power_grade,last_recom_date) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
  269. private static final String UPDATE_CHARACTER = "UPDATE characters SET level=?,maxHp=?,curHp=?,maxCp=?,curCp=?,maxMp=?,curMp=?,face=?,hairStyle=?,hairColor=?,sex=?,heading=?,x=?,y=?,z=?,exp=?,expBeforeDeath=?,sp=?,karma=?,fame=?,pvpkills=?,pkkills=?,rec_have=?,rec_left=?,clanid=?,race=?,classid=?,deletetime=?,title=?,accesslevel=?,online=?,isin7sdungeon=?,clan_privs=?,wantspeace=?,base_class=?,onlinetime=?,punish_level=?,punish_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=?,bookmarkslot=?,vitality_points=? WHERE charId=?";
  270. private static final String RESTORE_CHARACTER = "SELECT account_name, charId, char_name, level, maxHp, curHp, maxCp, curCp, maxMp, curMp, face, hairStyle, hairColor, sex, heading, x, y, z, exp, expBeforeDeath, sp, karma, fame, pvpkills, pkkills, clanid, race, classid, deletetime, cancraft, title, rec_have, rec_left, accesslevel, online, char_slot, lastAccess, clan_privs, wantspeace, base_class, onlinetime, isin7sdungeon, punish_level, punish_timer, newbie, nobless, power_grade, subpledge, last_recom_date, lvl_joined_academy, apprentice, sponsor, varka_ketra_ally,clan_join_expiry_time,clan_create_expiry_time,death_penalty_level,bookmarkslot,vitality_points FROM characters WHERE charId=?";
  271.  
  272. // Character Teleport Bookmark:
  273. private static final String INSERT_TP_BOOKMARK = "INSERT INTO character_tpbookmark (charId,Id,x,y,z,icon,tag,name) values (?,?,?,?,?,?,?,?)";
  274. private static final String UPDATE_TP_BOOKMARK = "UPDATE character_tpbookmark SET icon=?,tag=?,name=? where charId=? AND Id=?";
  275. private static final String RESTORE_TP_BOOKMARK = "SELECT Id,x,y,z,icon,tag,name FROM character_tpbookmark WHERE charId=?";
  276. private static final String DELETE_TP_BOOKMARK = "DELETE FROM character_tpbookmark WHERE charId=? AND Id=?";
  277.  
  278.  
  279. // Character Subclass SQL String Definitions:
  280. private static final String RESTORE_CHAR_SUBCLASSES = "SELECT class_id,exp,sp,level,class_index FROM character_subclasses WHERE charId=? ORDER BY class_index ASC";
  281. private static final String ADD_CHAR_SUBCLASS = "INSERT INTO character_subclasses (charId,class_id,exp,sp,level,class_index) VALUES (?,?,?,?,?,?)";
  282. private static final String UPDATE_CHAR_SUBCLASS = "UPDATE character_subclasses SET exp=?,sp=?,level=?,class_id=? WHERE charId=? AND class_index =?";
  283. private static final String DELETE_CHAR_SUBCLASS = "DELETE FROM character_subclasses WHERE charId=? AND class_index=?";
  284.  
  285. // Character Henna SQL String Definitions:
  286. private static final String RESTORE_CHAR_HENNAS = "SELECT slot,symbol_id FROM character_hennas WHERE charId=? AND class_index=?";
  287. private static final String ADD_CHAR_HENNA = "INSERT INTO character_hennas (charId,symbol_id,slot,class_index) VALUES (?,?,?,?)";
  288. private static final String DELETE_CHAR_HENNA = "DELETE FROM character_hennas WHERE charId=? AND slot=? AND class_index=?";
  289. private static final String DELETE_CHAR_HENNAS = "DELETE FROM character_hennas WHERE charId=? AND class_index=?";
  290.  
  291. // Character Shortcut SQL String Definitions:
  292. private static final String DELETE_CHAR_SHORTCUTS = "DELETE FROM character_shortcuts WHERE charId=? AND class_index=?";
  293.  
  294. // Character Recommendation SQL String Definitions:
  295. private static final String RESTORE_CHAR_RECOMS = "SELECT charId,target_id FROM character_recommends WHERE charId=?";
  296. private static final String ADD_CHAR_RECOM = "INSERT INTO character_recommends (charId,target_id) VALUES (?,?)";
  297. private static final String DELETE_CHAR_RECOMS = "DELETE FROM character_recommends WHERE charId=?";
  298.  
  299. // Character Transformation SQL String Definitions:
  300. private static final String SELECT_CHAR_TRANSFORM = "SELECT transform_id FROM characters WHERE charId=?";
  301. private static final String UPDATE_CHAR_TRANSFORM = "UPDATE characters SET transform_id=? WHERE charId=?";
  302.  
  303. public static final int REQUEST_TIMEOUT = 15;
  304. public static final int STORE_PRIVATE_NONE = 0;
  305. public static final int STORE_PRIVATE_SELL = 1;
  306. public static final int STORE_PRIVATE_BUY = 3;
  307. public static final int STORE_PRIVATE_MANUFACTURE = 5;
  308. public static final int STORE_PRIVATE_PACKAGE_SELL = 8;
  309.  
  310. /** The table containing all minimum level needed for each Expertise (None, D, C, B, A, S, S80, S84)*/
  311. private static final int[] EXPERTISE_LEVELS =
  312. {
  313. SkillTreeTable.getInstance().getExpertiseLevel(0), //NONE
  314. SkillTreeTable.getInstance().getExpertiseLevel(1), //D
  315. SkillTreeTable.getInstance().getExpertiseLevel(2), //C
  316. SkillTreeTable.getInstance().getExpertiseLevel(3), //B
  317. SkillTreeTable.getInstance().getExpertiseLevel(4), //A
  318. SkillTreeTable.getInstance().getExpertiseLevel(5), //S
  319. SkillTreeTable.getInstance().getExpertiseLevel(6), //S80
  320. SkillTreeTable.getInstance().getExpertiseLevel(7) //S84
  321. };
  322.  
  323. private static final int[] COMMON_CRAFT_LEVELS = { 5, 20, 28, 36, 43, 49, 55, 62 };
  324.  
  325. public class AIAccessor extends L2Character.AIAccessor
  326. {
  327. protected AIAccessor()
  328. {
  329.  
  330. }
  331.  
  332. public L2PcInstance getPlayer()
  333. {
  334. return L2PcInstance.this;
  335. }
  336.  
  337. public void doPickupItem(L2Object object)
  338. {
  339. L2PcInstance.this.doPickupItem(object);
  340. }
  341.  
  342. public void doInteract(L2Character target)
  343. {
  344. L2PcInstance.this.doInteract(target);
  345. }
  346.  
  347. @Override
  348. public void doAttack(L2Character target)
  349. {
  350. super.doAttack(target);
  351.  
  352. // cancel the recent fake-death protection instantly if the player attacks or casts spells
  353. getPlayer().setRecentFakeDeath(false);
  354. }
  355.  
  356. @Override
  357. public void doCast(L2Skill skill)
  358. {
  359. super.doCast(skill);
  360.  
  361. // cancel the recent fake-death protection instantly if the player attacks or casts spells
  362. getPlayer().setRecentFakeDeath(false);
  363. }
  364. }
  365.  
  366. private L2GameClient _client;
  367.  
  368. private String _accountName;
  369. private long _deleteTimer;
  370.  
  371. private boolean _isOnline = false;
  372. private long _onlineTime;
  373. private long _onlineBeginTime;
  374. private long _lastAccess;
  375. private long _uptime;
  376.  
  377. private final ReentrantLock _subclassLock = new ReentrantLock();
  378. protected int _baseClass;
  379. protected int _activeClass;
  380. protected int _classIndex = 0;
  381.  
  382. /** data for mounted pets */
  383. private int _controlItemId;
  384. private L2PetData _data;
  385. private int _curFeed;
  386. protected Future<?> _mountFeedTask;
  387. private ScheduledFuture<?> _dismountTask;
  388.  
  389. /** The list of sub-classes this character has. */
  390. private Map<Integer, SubClass> _subClasses;
  391.  
  392. private PcAppearance _appearance;
  393.  
  394. /** The Identifier of the L2PcInstance */
  395. private int _charId = 0x00030b7a;
  396.  
  397. /** Combo PvP Skill System */
  398. private int combo = 0;
  399.  
  400. /** The Experience of the L2PcInstance before the last Death Penalty */
  401. private long _expBeforeDeath;
  402.  
  403. /** The Karma of the L2PcInstance (if higher than 0, the name of the L2PcInstance appears in red) */
  404. private int _karma;
  405.  
  406. /** The number of player killed during a PvP (the player killed was PvP Flagged) */
  407. private int _pvpKills;
  408.  
  409. /** The PK counter of the L2PcInstance (= Number of non PvP Flagged player killed) */
  410. private int _pkKills;
  411.  
  412. /** The PvP Flag state of the L2PcInstance (0=White, 1=Purple) */
  413. private byte _pvpFlag;
  414.  
  415. /** The Fame of this L2PcInstance */
  416. private int _fame;
  417. private ScheduledFuture<?> _fameTask;
  418.  
  419. /** Vitality recovery task */
  420. private ScheduledFuture<?> _vitalityTask;
  421.  
  422. private ScheduledFuture<?> _teleportWatchdog;
  423.  
  424. /** The Siege state of the L2PcInstance */
  425. private byte _siegeState = 0;
  426.  
  427. private int _curWeightPenalty = 0;
  428.  
  429. private int _pvpKillsAnnoun;
  430.  
  431. private int _lastCompassZone; // the last compass zone update send to the client
  432.  
  433. private boolean _isIn7sDungeon = false;
  434.  
  435. public int _bookmarkslot = 0; // The Teleport Bookmark Slot
  436.  
  437.  
  438. private int _zoneKills = 0;
  439.  
  440. public void setZoneKills(int kills)
  441. {
  442. _zoneKills = kills;
  443. }
  444. public int getZoneKills()
  445. {
  446. return _zoneKills;
  447. }
  448. public FastList<TeleportBookmark> tpbookmark = new FastList<TeleportBookmark>();
  449.  
  450. private final FloodProtectors _floodProtectors = new FloodProtectors(this);
  451.  
  452. private PunishLevel _punishLevel = PunishLevel.NONE;
  453. private long _punishTimer = 0;
  454. private ScheduledFuture<?> _punishTask;
  455.  
  456. public enum PunishLevel
  457. {
  458. NONE(0, ""),
  459. CHAT(1, "chat banned"),
  460. JAIL(2, "jailed"),
  461. CHAR(3, "banned"),
  462. ACC(4, "banned");
  463.  
  464. private int punValue;
  465. private String punString;
  466.  
  467. PunishLevel(int value, String string)
  468. {
  469. punValue = value;
  470. punString = string;
  471. }
  472.  
  473. public int value()
  474. {
  475. return punValue;
  476. }
  477.  
  478. public String string()
  479. {
  480. return punString;
  481. }
  482. }
  483.  
  484. /** Olympiad */
  485. private boolean _inOlympiadMode = false;
  486. private boolean _OlympiadStart = false;
  487. private int _olympiadGameId = -1;
  488. private int _olympiadSide = -1;
  489. public int olyBuff = 0;
  490.  
  491. /** Duel */
  492. private boolean _isInDuel = false;
  493. private int _duelState = Duel.DUELSTATE_NODUEL;
  494. private int _duelId = 0;
  495. private SystemMessageId _noDuelReason = SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL;
  496.  
  497. /** Boat */
  498. private boolean _inBoat;
  499. private L2BoatInstance _boat;
  500. private Point3D _inBoatPosition;
  501.  
  502. /** AirShip */
  503. private L2AirShipInstance _airShip;
  504. private boolean _inAirShip;
  505. private Point3D _inAirShipPosition;
  506.  
  507. public ScheduledFuture<?> _taskforfish;
  508. private int _mountType;
  509. private int _mountNpcId;
  510. private int _mountLevel;
  511. /** Store object used to summon the strider you are mounting **/
  512. private int _mountObjectID = 0;
  513.  
  514. public int _telemode = 0;
  515.  
  516. public boolean _exploring = false;
  517.  
  518. private boolean _inCrystallize;
  519. private boolean _inCraftMode;
  520.  
  521. private L2Transformation _transformation;
  522.  
  523. private static int _transformationId = 0;
  524.  
  525. /** The table containing all L2RecipeList of the L2PcInstance */
  526. private Map<Integer, L2RecipeList> _dwarvenRecipeBook = new FastMap<Integer, L2RecipeList>();
  527. private Map<Integer, L2RecipeList> _commonRecipeBook = new FastMap<Integer, L2RecipeList>();
  528.  
  529. /** True if the L2PcInstance is sitting */
  530. private boolean _waitTypeSitting;
  531.  
  532. /** True if the L2PcInstance is using the relax skill */
  533. private boolean _relax;
  534.  
  535. /** Location before entering Observer Mode */
  536. private int _obsX;
  537. private int _obsY;
  538. private int _obsZ;
  539. private boolean _observerMode = false;
  540.  
  541. /** Stored from last ValidatePosition **/
  542. private Point3D _lastServerPosition = new Point3D(0, 0, 0);
  543.  
  544. /** Previous coordinate sent to party in ValidatePosition **/
  545. private Point3D _lastPartyPosition = new Point3D(0, 0, 0);
  546.  
  547. /** The number of recommendation obtained by the L2PcInstance */
  548. private int _recomHave; // how much I was recommended by others
  549.  
  550. /** The number of recommendation that the L2PcInstance can give */
  551. private int _recomLeft; // how many recommendations I can give to others
  552.  
  553. /** Date when recommendation points were updated last time */
  554. private long _lastRecomUpdate;
  555.  
  556. private int _deaths; // how many times died character
  557.  
  558. /** List with the recommendations that I've give */
  559. private List<Integer> _recomChars = new FastList<Integer>();
  560.  
  561. /** The random number of the L2PcInstance */
  562. //private static final Random _rnd = new Random();
  563.  
  564. private PcInventory _inventory = new PcInventory(this);
  565. private PcWarehouse _warehouse;
  566. private PcFreight _freight;
  567. private List<PcFreight> _depositedFreight;
  568.  
  569. /** 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) */
  570. private int _privatestore;
  571.  
  572. private TradeList _activeTradeList;
  573. private ItemContainer _activeWarehouse;
  574. private L2ManufactureList _createList;
  575. private TradeList _sellList;
  576. private TradeList _buyList;
  577.  
  578. /** Bitmask used to keep track of one-time/newbie quest rewards*/
  579. private int _newbie;
  580.  
  581. private boolean _noble = false;
  582. private boolean _hero = false;
  583.  
  584. private boolean botCheck = false;
  585.  
  586. public String code = "";
  587.  
  588. /** The L2FolkInstance corresponding to the last Folk wich one the player talked. */
  589. private L2Npc _lastFolkNpc = null;
  590.  
  591. /** Last NPC Id talked on a quest */
  592. private int _questNpcObject = 0;
  593.  
  594. /** The table containing all Quests began by the L2PcInstance */
  595. private Map<String, QuestState> _quests = new FastMap<String, QuestState>();
  596.  
  597. /** The list containing all shortCuts of this L2PcInstance */
  598. private ShortCuts _shortCuts = new ShortCuts(this);
  599.  
  600. /** The list containing all macroses of this L2PcInstance */
  601. private MacroList _macroses = new MacroList(this);
  602.  
  603. private List<L2PcInstance> _snoopListener = new FastList<L2PcInstance>();
  604. private List<L2PcInstance> _snoopedPlayer = new FastList<L2PcInstance>();
  605.  
  606. private ClassId _skillLearningClassId;
  607.  
  608. // hennas
  609. private final L2HennaInstance[] _henna = new L2HennaInstance[3];
  610. private int _hennaSTR;
  611. private int _hennaINT;
  612. private int _hennaDEX;
  613. private int _hennaMEN;
  614. private int _hennaWIT;
  615. private int _hennaCON;
  616.  
  617. /** The L2Summon of the L2PcInstance */
  618. private L2Summon _summon = null;
  619. /** The L2Decoy of the L2PcInstance */
  620. private L2Decoy _decoy = null;
  621. /** The L2Trap of the L2PcInstance */
  622. private L2Trap _trap = null;
  623. /** The L2Agathion of the L2PcInstance */
  624. private int _agathionId = 0;
  625. // apparently, a L2PcInstance CAN have both a summon AND a tamed beast at the same time!!
  626. private L2TamedBeastInstance _tamedBeast = null;
  627.  
  628. // client radar
  629. //TODO: This needs to be better intergrated and saved/loaded
  630. private L2Radar _radar;
  631.  
  632. // these values are only stored temporarily
  633. private boolean _partyMatchingAutomaticRegistration;
  634. private boolean _partyMatchingShowLevel;
  635. private boolean _partyMatchingShowClass;
  636. private String _partyMatchingMemo;
  637.  
  638. // Clan related attributes
  639. /** The Clan Identifier of the L2PcInstance */
  640. private int _clanId;
  641.  
  642. /** The Clan object of the L2PcInstance */
  643. private L2Clan _clan;
  644.  
  645. /** Apprentice and Sponsor IDs */
  646. private int _apprentice = 0;
  647. private int _sponsor = 0;
  648.  
  649. private long _clanJoinExpiryTime;
  650. private long _clanCreateExpiryTime;
  651.  
  652. private int _powerGrade = 0;
  653. private int _clanPrivileges = 0;
  654.  
  655. /** L2PcInstance's pledge class (knight, Baron, etc.)*/
  656. private int _pledgeClass = 0;
  657. private int _pledgeType = 0;
  658.  
  659. /** Level at which the player joined the clan as an academy member*/
  660. private int _lvlJoinedAcademy = 0;
  661.  
  662. private int _wantsPeace = 0;
  663.  
  664. //Death Penalty Buff Level
  665. private int _deathPenaltyBuffLevel = 0;
  666.  
  667. // self resurrect during siege
  668. private boolean _charmOfCourage = false;
  669.  
  670. // charges
  671. private AtomicInteger _charges = new AtomicInteger();
  672. private ScheduledFuture<?> _chargeTask = null;
  673.  
  674. // Absorbed Souls
  675. private int _souls = 0;
  676. private ScheduledFuture<?> _soulTask = null;
  677.  
  678. // WorldPosition used by TARGET_SIGNET_GROUND
  679. private Point3D _currentSkillWorldPosition;
  680.  
  681. private L2AccessLevel _accessLevel;
  682.  
  683. private boolean _messageRefusal = false; // message refusal mode
  684. private boolean _dietMode = false; // ignore weight penalty
  685. private boolean _tradeRefusal = false; // Trade refusal
  686. private boolean _exchangeRefusal = false; // Exchange refusal
  687. private boolean _gainXpSpEnable = true;
  688.  
  689. private L2Party _party;
  690.  
  691. // this is needed to find the inviting player for Party response
  692. // there can only be one active party request at once
  693. private L2PcInstance _activeRequester;
  694. private long _requestExpireTime = 0;
  695. private L2Request _request = new L2Request(this);
  696. private L2ItemInstance _arrowItem;
  697. private L2ItemInstance _boltItem;
  698.  
  699. // Used for protection after teleport
  700. private long _protectEndTime = 0;
  701. public boolean isSpawnProtected() { return (_protectEndTime > 0); }
  702.  
  703. // protects a char from agro mobs when getting up from fake death
  704. private long _recentFakeDeathEndTime = 0;
  705. private boolean _isFakeDeath;
  706.  
  707. /** The fists L2Weapon of the L2PcInstance (used when no weapon is equiped) */
  708. private L2Weapon _fistsWeaponItem;
  709.  
  710. private final Map<Integer, String> _chars = new FastMap<Integer, String>();
  711.  
  712. //private byte _updateKnownCounter = 0;
  713.  
  714. /** The current higher Expertise of the L2PcInstance (None=0, D=1, C=2, B=3, A=4, S=5, S80=6, S84=7)*/
  715. private int _expertiseIndex; // index in EXPERTISE_LEVELS
  716. private int _expertisePenalty = 0;
  717.  
  718. private boolean _isEnchanting = false;
  719. private L2ItemInstance _activeEnchantItem = null;
  720. private L2ItemInstance _activeEnchantSupportItem = null;
  721. private L2ItemInstance _activeEnchantAttrItem = null;
  722. private long _activeEnchantTimestamp = 0;
  723.  
  724. protected boolean _inventoryDisable = false;
  725.  
  726. protected Map<Integer, L2CubicInstance> _cubics = new FastMap<Integer, L2CubicInstance>().setShared(true);
  727.  
  728. /** Active shots. A FastSet variable would actually suffice but this was changed to fix threading stability... */
  729. protected Map<Integer, Integer> _activeSoulShots = new FastMap<Integer, Integer>().setShared(true);
  730.  
  731. public final ReentrantLock soulShotLock = new ReentrantLock();
  732.  
  733. /** Event parameters */
  734. public int eventX;
  735. public int eventY;
  736. public int eventZ;
  737. public int eventkarma;
  738. public int eventpvpkills;
  739. public int eventpkkills;
  740. public String eventTitle;
  741. public LinkedList<String> kills = new LinkedList<String>();
  742. public boolean eventSitForced = false;
  743. public boolean atEvent = false;
  744.  
  745. /** new loto ticket **/
  746. private int _loto[] = new int[5];
  747. //public static int _loto_nums[] = {0,1,2,3,4,5,6,7,8,9,};
  748. /** new race ticket **/
  749. private int _race[] = new int[2];
  750.  
  751. private final BlockList _blockList = new BlockList();
  752.  
  753. private int _team = 0;
  754.  
  755. /** lvl of alliance with ketra orcs or varka silenos, used in quests and aggro checks
  756. * [-5,-1] varka, 0 neutral, [1,5] ketra
  757. * */
  758. private int _alliedVarkaKetra = 0;
  759.  
  760. private L2Fishing _fishCombat;
  761. private boolean _fishing = false;
  762. private int _fishx = 0;
  763. private int _fishy = 0;
  764. private int _fishz = 0;
  765.  
  766. private int[] _transformAllowedSkills = {};
  767. private ScheduledFuture<?> _taskRentPet;
  768. private ScheduledFuture<?> _taskWater;
  769.  
  770. /** Bypass validations */
  771. private List<String> _validBypass = new FastList<String>();
  772. private List<String> _validBypass2 = new FastList<String>();
  773.  
  774. private Forum _forumMail;
  775. private Forum _forumMemo;
  776.  
  777. /** Current skill in use. Note that L2Character has _lastSkillCast, but
  778. * this has the button presses */
  779. private SkillDat _currentSkill;
  780. private SkillDat _currentPetSkill;
  781.  
  782. /** Skills queued because a skill is already in progress */
  783. private SkillDat _queuedSkill;
  784.  
  785. /* Flag to disable equipment/skills while wearing formal wear **/
  786. private boolean _IsWearingFormalWear = false;
  787.  
  788. private int _cursedWeaponEquippedId = 0;
  789. private boolean _combatFlagEquippedId = false;
  790.  
  791. private int _reviveRequested = 0;
  792. private double _revivePower = 0;
  793. private boolean _revivePet = false;
  794.  
  795. private double _cpUpdateIncCheck = .0;
  796. private double _cpUpdateDecCheck = .0;
  797. private double _cpUpdateInterval = .0;
  798. private double _mpUpdateIncCheck = .0;
  799. private double _mpUpdateDecCheck = .0;
  800. private double _mpUpdateInterval = .0;
  801.  
  802. /* not used any more
  803. private boolean _isRidingFenrirWolf = false;
  804. private boolean _isRidingWFenrirWolf = false;
  805. private boolean _isRidingGreatSnowWolf = false;
  806. */
  807. private boolean _isRidingStrider = false;
  808. private boolean _isFlyingMounted = false;
  809.  
  810. /** Herbs Task Time **/
  811. private int _herbstask = 0;
  812. /** Task for Herbs */
  813. public class HerbTask implements Runnable
  814. {
  815. private String _process;
  816. private int _itemId;
  817. private long _count;
  818. private L2Object _reference;
  819. private boolean _sendMessage;
  820.  
  821. HerbTask(String process, int itemId, long count, L2Object reference, boolean sendMessage)
  822. {
  823. _process = process;
  824. _itemId = itemId;
  825. _count = count;
  826. _reference = reference;
  827. _sendMessage = sendMessage;
  828. }
  829.  
  830. public void run()
  831. {
  832. try
  833. {
  834. addItem(_process, _itemId, _count, _reference, _sendMessage);
  835. }
  836. catch (Exception e)
  837. {
  838. _log.log(Level.WARNING, "", e);
  839. }
  840. }
  841. }
  842.  
  843. /** ShortBuff clearing Task */
  844. ScheduledFuture<?> _shortBuffTask = null;
  845.  
  846. public class ShortBuffTask implements Runnable
  847. {
  848. private L2PcInstance _player = null;
  849.  
  850. public ShortBuffTask(L2PcInstance activeChar)
  851. {
  852. _player = activeChar;
  853. }
  854.  
  855. public void run()
  856. {
  857. if (_player == null)
  858. return;
  859.  
  860. _player.sendPacket(new ShortBuffStatusUpdate(0, 0, 0));
  861. setShortBuffTaskSkillId(0);
  862. }
  863. }
  864.  
  865. // L2JMOD Wedding
  866. private boolean _married = false;
  867. private int _partnerId = 0;
  868. private int _coupleId = 0;
  869. private boolean _engagerequest = false;
  870. private int _engageid = 0;
  871. private boolean _marryrequest = false;
  872. private boolean _marryaccepted = false;
  873.  
  874. /** Skill casting information (used to queue when several skills are cast in a short time) **/
  875. public class SkillDat
  876. {
  877. private L2Skill _skill;
  878. private boolean _ctrlPressed;
  879. private boolean _shiftPressed;
  880.  
  881. protected SkillDat(L2Skill skill, boolean ctrlPressed, boolean shiftPressed)
  882. {
  883. _skill = skill;
  884. _ctrlPressed = ctrlPressed;
  885. _shiftPressed = shiftPressed;
  886. }
  887.  
  888. public boolean isCtrlPressed()
  889. {
  890. return _ctrlPressed;
  891. }
  892.  
  893. public boolean isShiftPressed()
  894. {
  895. return _shiftPressed;
  896. }
  897.  
  898. public L2Skill getSkill()
  899. {
  900. return _skill;
  901. }
  902.  
  903. public int getSkillId()
  904. {
  905. return (getSkill() != null) ? getSkill().getId() : -1;
  906. }
  907. }
  908.  
  909. //summon friend
  910. private summonRequest _summonRequest = new summonRequest();
  911.  
  912. public class summonRequest
  913. {
  914. private L2PcInstance _target = null;
  915. private L2Skill _skill = null;
  916.  
  917. public void setTarget(L2PcInstance destination, L2Skill skill)
  918. {
  919. _target = destination;
  920. _skill = skill;
  921. }
  922.  
  923. public L2PcInstance getTarget()
  924. {
  925. return _target;
  926. }
  927.  
  928. public L2Skill getSkill()
  929. {
  930. return _skill;
  931. }
  932. }
  933.  
  934. private List<Integer> _completedAchievements = new ArrayList<Integer>();
  935.  
  936. public boolean readyAchievementsList()
  937. {
  938. if (_completedAchievements.isEmpty())
  939. return false;
  940. return true;
  941. }
  942.  
  943. public void saveAchievemntData()
  944. {
  945.  
  946. }
  947.  
  948. public void getAchievemntData()
  949. {
  950. Connection con = null;
  951. try
  952. {
  953. PreparedStatement statement;
  954. PreparedStatement insertStatement;
  955. ResultSet rs;
  956. con = L2DatabaseFactory.getInstance().getConnection();
  957.  
  958. statement = con.prepareStatement("SELECT * from achievements WHERE owner_id=" + getObjectId());
  959.  
  960. rs = statement.executeQuery();
  961.  
  962. String values = "owner_id";
  963. String in = Integer.toString(getObjectId());
  964. String questionMarks = in;
  965. int ilosc = AchievementsManager.getInstance().getAchievementList().size();
  966.  
  967. if (rs.next())
  968. {
  969. _completedAchievements.clear();
  970. for (int i=1; i <=ilosc; i++)
  971. {
  972. int a = rs.getInt("a" + i);
  973.  
  974. if (!_completedAchievements.contains(i))
  975. if (a == 1)
  976. _completedAchievements.add(i);
  977. }
  978. }
  979. else
  980. {
  981. //Player hasnt entry in database, means we have to create it.
  982.  
  983. for (int i=1; i <=ilosc; i++)
  984. {
  985. values += ", a" + i;
  986. questionMarks += ", 0";
  987. }
  988.  
  989. String s = "INSERT INTO achievements(" + values + ") VALUES (" + questionMarks + ")";
  990. insertStatement = con.prepareStatement(s);
  991.  
  992. insertStatement.execute();
  993. insertStatement.close();
  994. }
  995. }
  996. catch (Exception e)
  997. {
  998. _log.warning("[ACHIEVEMENTS ENGINE GETDATA]" + e);
  999. }
  1000. }
  1001.  
  1002. public void saveAchievementData(int achievementID)
  1003. {
  1004. Connection con = null;
  1005. try
  1006. {
  1007. con = L2DatabaseFactory.getInstance().getConnection();
  1008. Statement statement = con.createStatement();
  1009. statement.executeUpdate("UPDATE achievements SET a" + achievementID + "=1 WHERE owner_id=" + getObjectId());
  1010. statement.close();
  1011.  
  1012. if (!_completedAchievements.contains(achievementID))
  1013. _completedAchievements.add(achievementID);
  1014. }
  1015. catch (SQLException e)
  1016. {
  1017. _log.warning("[ACHIEVEMENTS SAVE GETDATA]" + e);
  1018. }
  1019.  
  1020. }
  1021.  
  1022. public List<Integer> getCompletedAchievements()
  1023. {
  1024. return _completedAchievements;
  1025. }
  1026.  
  1027. // open/close gates
  1028. private gatesRequest _gatesRequest = new gatesRequest();
  1029.  
  1030. public class gatesRequest
  1031. {
  1032. private L2DoorInstance _target = null;
  1033. public void setTarget(L2DoorInstance door)
  1034. {
  1035. _target = door;
  1036. }
  1037. public L2DoorInstance getDoor()
  1038. {
  1039. return _target;
  1040. }
  1041. }
  1042. /**
  1043. * Create a new L2PcInstance and add it in the characters table of the database.<BR><BR>
  1044. *
  1045. * <B><U> Actions</U> :</B><BR><BR>
  1046. * <li>Create a new L2PcInstance with an account name </li>
  1047. * <li>Set the name, the Hair Style, the Hair Color and the Face type of the L2PcInstance</li>
  1048. * <li>Add the player in the characters table of the database</li><BR><BR>
  1049. *
  1050. * @param objectId Identifier of the object to initialized
  1051. * @param template The L2PcTemplate to apply to the L2PcInstance
  1052. * @param accountName The name of the L2PcInstance
  1053. * @param name The name of the L2PcInstance
  1054. * @param hairStyle The hair style Identifier of the L2PcInstance
  1055. * @param hairColor The hair color Identifier of the L2PcInstance
  1056. * @param face The face type Identifier of the L2PcInstance
  1057. *
  1058. * @return The L2PcInstance added to the database or null
  1059. *
  1060. */
  1061. public static L2PcInstance create(int objectId, L2PcTemplate template, String accountName, String name, byte hairStyle, byte hairColor, byte face, boolean sex)
  1062. {
  1063. // Create a new L2PcInstance with an account name
  1064. PcAppearance app = new PcAppearance(face, hairColor, hairStyle, sex);
  1065. L2PcInstance player = new L2PcInstance(objectId, template, accountName, app);
  1066.  
  1067. // Set the name of the L2PcInstance
  1068. player.setName(name);
  1069.  
  1070. // Set the base class ID to that of the actual class ID.
  1071. player.setBaseClass(player.getClassId());
  1072. // Kept for backwards compabitility.
  1073. player.setNewbie(1);
  1074. // Add the player in the characters table of the database
  1075. boolean ok = player.createDb();
  1076.  
  1077. if (!ok)
  1078. return null;
  1079.  
  1080. return player;
  1081. }
  1082.  
  1083. public static L2PcInstance createDummyPlayer(int objectId, String name)
  1084. {
  1085. // Create a new L2PcInstance with an account name
  1086. L2PcInstance player = new L2PcInstance(objectId);
  1087. player.setName(name);
  1088.  
  1089. return player;
  1090. }
  1091.  
  1092. public String getAccountName()
  1093. {
  1094. if (getClient() == null || getClient().isDetached())
  1095. return "disconnected";
  1096. return getClient().getAccountName();
  1097. }
  1098.  
  1099. public Map<Integer, String> getAccountChars()
  1100. {
  1101. return _chars;
  1102. }
  1103.  
  1104. public int getRelation(L2PcInstance target)
  1105. {
  1106. int result = 0;
  1107.  
  1108. if (getClan() != null)
  1109. result |= RelationChanged.RELATION_CLAN_MEMBER;
  1110. if (isClanLeader())
  1111. result |= RelationChanged.RELATION_LEADER;
  1112. if (getParty() != null && getParty() == target.getParty())
  1113. {
  1114. result |= RelationChanged.RELATION_HAS_PARTY;
  1115. for (int i = 0; i < getParty().getPartyMembers().size(); i++)
  1116. {
  1117. if (getParty().getPartyMembers().get(i) != this)
  1118. continue;
  1119. switch (i)
  1120. {
  1121. case 0:
  1122. result |= RelationChanged.RELATION_PARTYLEADER; // 0x10
  1123. break;
  1124. case 1:
  1125. result |= RelationChanged.RELATION_PARTY4; // 0x8
  1126. break;
  1127. case 2:
  1128. result |= RelationChanged.RELATION_PARTY3+RelationChanged.RELATION_PARTY2+RelationChanged.RELATION_PARTY1; // 0x7
  1129. break;
  1130. case 3:
  1131. result |= RelationChanged.RELATION_PARTY3+RelationChanged.RELATION_PARTY2; // 0x6
  1132. break;
  1133. case 4:
  1134. result |= RelationChanged.RELATION_PARTY3+RelationChanged.RELATION_PARTY1; // 0x5
  1135. break;
  1136. case 5:
  1137. result |= RelationChanged.RELATION_PARTY3; // 0x4
  1138. break;
  1139. case 6:
  1140. result |= RelationChanged.RELATION_PARTY2+RelationChanged.RELATION_PARTY1; // 0x3
  1141. break;
  1142. case 7:
  1143. result |= RelationChanged.RELATION_PARTY2; // 0x2
  1144. break;
  1145. case 8:
  1146. result |= RelationChanged.RELATION_PARTY1; // 0x1
  1147. break;
  1148. }
  1149. }
  1150. }
  1151. if (getSiegeState() != 0)
  1152. {
  1153. result |= RelationChanged.RELATION_INSIEGE;
  1154. if (getSiegeState() != target.getSiegeState())
  1155. result |= RelationChanged.RELATION_ENEMY;
  1156. else
  1157. result |= RelationChanged.RELATION_ALLY;
  1158. if (getSiegeState() == 1)
  1159. result |= RelationChanged.RELATION_ATTACKER;
  1160. }
  1161.  
  1162. if (getClan() != null && target.getClan() != null)
  1163. {
  1164. if (target.getPledgeType() != L2Clan.SUBUNIT_ACADEMY
  1165. && getPledgeType() != L2Clan.SUBUNIT_ACADEMY
  1166. && target.getClan().isAtWarWith(getClan().getClanId()))
  1167. {
  1168. result |= RelationChanged.RELATION_1SIDED_WAR;
  1169. if (getClan().isAtWarWith(target.getClan().getClanId()))
  1170. result |= RelationChanged.RELATION_MUTUAL_WAR;
  1171. }
  1172. }
  1173. return result;
  1174. }
  1175.  
  1176. /**
  1177. * Retrieve a L2PcInstance from the characters table of the database and add it in _allObjects of the L2world (call restore method).<BR><BR>
  1178. *
  1179. * <B><U> Actions</U> :</B><BR><BR>
  1180. * <li>Retrieve the L2PcInstance from the characters table of the database </li>
  1181. * <li>Add the L2PcInstance object in _allObjects </li>
  1182. * <li>Set the x,y,z position of the L2PcInstance and make it invisible</li>
  1183. * <li>Update the overloaded status of the L2PcInstance</li><BR><BR>
  1184. *
  1185. * @param objectId Identifier of the object to initialized
  1186. *
  1187. * @return The L2PcInstance loaded from the database
  1188. *
  1189. */
  1190. public static L2PcInstance load(int objectId)
  1191. {
  1192. return restore(objectId);
  1193. }
  1194.  
  1195. private void initPcStatusUpdateValues()
  1196. {
  1197. _cpUpdateInterval = getMaxCp() / 352.0;
  1198. _cpUpdateIncCheck = getMaxCp();
  1199. _cpUpdateDecCheck = getMaxCp() - _cpUpdateInterval;
  1200. _mpUpdateInterval = getMaxMp() / 352.0;
  1201. _mpUpdateIncCheck = getMaxMp();
  1202. _mpUpdateDecCheck = getMaxMp() - _mpUpdateInterval;
  1203. }
  1204.  
  1205. /**
  1206. * Constructor of L2PcInstance (use L2Character constructor).<BR><BR>
  1207. *
  1208. * <B><U> Actions</U> :</B><BR><BR>
  1209. * <li>Call the L2Character constructor to create an empty _skills slot and copy basic Calculator set to this L2PcInstance </li>
  1210. * <li>Set the name of the L2PcInstance</li><BR><BR>
  1211. *
  1212. * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method SET the level of the L2PcInstance to 1</B></FONT><BR><BR>
  1213. *
  1214. * @param objectId Identifier of the object to initialized
  1215. * @param template The L2PcTemplate to apply to the L2PcInstance
  1216. * @param accountName The name of the account including this L2PcInstance
  1217. *
  1218. */
  1219. private L2PcInstance(int objectId, L2PcTemplate template, String accountName, PcAppearance app)
  1220. {
  1221. super(objectId, template);
  1222. super.initCharStatusUpdateValues();
  1223. initPcStatusUpdateValues();
  1224.  
  1225. _accountName = accountName;
  1226. app.setOwner(this);
  1227. _appearance = app;
  1228.  
  1229. // Create an AI
  1230. _ai = new L2PlayerAI(new L2PcInstance.AIAccessor());
  1231.  
  1232. // Create a L2Radar object
  1233. _radar = new L2Radar(this);
  1234.  
  1235. // Retrieve from the database all skills of this L2PcInstance and add them to _skills
  1236. // Retrieve from the database all items of this L2PcInstance and add them to _inventory
  1237. getInventory().restore();
  1238. if (!Config.WAREHOUSE_CACHE)
  1239. getWarehouse();
  1240. getFreight();
  1241. startVitalityTask();
  1242. }
  1243.  
  1244. private L2PcInstance(int objectId)
  1245. {
  1246. super(objectId, null);
  1247. super.initCharStatusUpdateValues();
  1248. initPcStatusUpdateValues();
  1249. }
  1250.  
  1251. @Override
  1252. public final PcKnownList getKnownList()
  1253. {
  1254. return (PcKnownList)super.getKnownList();
  1255. }
  1256.  
  1257. @Override
  1258. public void initKnownList()
  1259. {
  1260. setKnownList(new PcKnownList(this));
  1261. }
  1262.  
  1263. @Override
  1264. public final PcStat getStat()
  1265. {
  1266. return (PcStat)super.getStat();
  1267. }
  1268.  
  1269. @Override
  1270. public void initCharStat()
  1271. {
  1272. setStat(new PcStat(this));
  1273. }
  1274.  
  1275. @Override
  1276. public final PcStatus getStatus()
  1277. {
  1278. return (PcStatus)super.getStatus();
  1279. }
  1280.  
  1281. @Override
  1282. public void initCharStatus()
  1283. {
  1284. setStatus(new PcStatus(this));
  1285. }
  1286.  
  1287. @Override
  1288. public PcPosition getPosition()
  1289. {
  1290. return (PcPosition)super.getPosition();
  1291. }
  1292.  
  1293. @Override
  1294. public void initPosition()
  1295. {
  1296. setObjectPosition(new PcPosition(this));
  1297. }
  1298.  
  1299. public final PcAppearance getAppearance()
  1300. {
  1301. return _appearance;
  1302. }
  1303.  
  1304. /**
  1305. * Return the base L2PcTemplate link to the L2PcInstance.<BR><BR>
  1306. */
  1307. public final L2PcTemplate getBaseTemplate()
  1308. {
  1309. return CharTemplateTable.getInstance().getTemplate(_baseClass);
  1310. }
  1311.  
  1312. /** Return the L2PcTemplate link to the L2PcInstance. */
  1313. @Override
  1314. public final L2PcTemplate getTemplate() { return (L2PcTemplate)super.getTemplate(); }
  1315.  
  1316. public void setTemplate(ClassId newclass) { super.setTemplate(CharTemplateTable.getInstance().getTemplate(newclass)); }
  1317.  
  1318. /**
  1319. * Return the AI of the L2PcInstance (create it if necessary).<BR><BR>
  1320. */
  1321. @Override
  1322. public L2CharacterAI getAI()
  1323. {
  1324. L2CharacterAI ai = _ai; // copy handle
  1325. if (ai == null)
  1326. {
  1327. synchronized(this)
  1328. {
  1329. if (_ai == null) _ai = new L2PlayerAI(new L2PcInstance.AIAccessor());
  1330. return _ai;
  1331. }
  1332. }
  1333. return ai;
  1334. }
  1335.  
  1336.  
  1337. /**
  1338. * Calculate a destination to explore the area and set the AI Intention to AI_INTENTION_MOVE_TO.<BR><BR>
  1339. */
  1340. public void explore()
  1341. {
  1342. if (!_exploring) return;
  1343.  
  1344. if(getMountType() == 2)
  1345. return;
  1346.  
  1347. // Calculate the destination point (random)
  1348.  
  1349. int x = getX()+Rnd.nextInt(6000)-3000;
  1350. int y = getY()+Rnd.nextInt(6000)-3000;
  1351.  
  1352. if (x > Universe.MAX_X) x = Universe.MAX_X;
  1353. if (x < Universe.MIN_X) x = Universe.MIN_X;
  1354. if (y > Universe.MAX_Y) y = Universe.MAX_Y;
  1355. if (y < Universe.MIN_Y) y = Universe.MIN_Y;
  1356.  
  1357. int z = getZ();
  1358.  
  1359. L2CharPosition pos = new L2CharPosition(x,y,z,0);
  1360.  
  1361. // Set the AI Intention to AI_INTENTION_MOVE_TO
  1362. getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO,pos);
  1363.  
  1364. }
  1365.  
  1366. /** Return the Level of the L2PcInstance. */
  1367. @Override
  1368. public final int getLevel() { return getStat().getLevel(); }
  1369.  
  1370. /**
  1371. * Return the _newbie rewards state of the L2PcInstance.<BR><BR>
  1372. */
  1373. public int getNewbie()
  1374. {
  1375. return _newbie;
  1376. }
  1377.  
  1378. /**
  1379. * Set the _newbie rewards state of the L2PcInstance.<BR><BR>
  1380. *
  1381. * @param newbieRewards The Identifier of the _newbie state<BR><BR>
  1382. *
  1383. */
  1384. public void setNewbie(int newbieRewards)
  1385. {
  1386. _newbie = newbieRewards;
  1387. }
  1388.  
  1389.  
  1390. public void setBaseClass(int baseClass)
  1391. {
  1392. _baseClass = baseClass;
  1393. }
  1394.  
  1395. public void setBaseClass(ClassId classId)
  1396. {
  1397. _baseClass = classId.ordinal();
  1398. }
  1399.  
  1400. public boolean isInStoreMode() { return (getPrivateStoreType() > 0); }
  1401. // public boolean isInCraftMode() { return (getPrivateStoreType() == STORE_PRIVATE_MANUFACTURE); }
  1402.  
  1403. public boolean isInCraftMode()
  1404. {
  1405. return _inCraftMode;
  1406. }
  1407.  
  1408. public void isInCraftMode(boolean b)
  1409. {
  1410. _inCraftMode = b;
  1411. }
  1412.  
  1413. /**
  1414. * Manage Logout Task.<BR><BR>
  1415. */
  1416. public void logout()
  1417. {
  1418. if (getInventory().getItemByItemId(9819) != null)
  1419. {
  1420. Fort fort = FortManager.getInstance().getFort(this);
  1421. if (fort != null)
  1422. FortSiegeManager.getInstance().dropCombatFlag(this);
  1423. else
  1424. {
  1425. int slot = getInventory().getSlotFromItem(getInventory().getItemByItemId(9819));
  1426. getInventory().unEquipItemInBodySlotAndRecord(slot);
  1427. destroyItem("CombatFlag", getInventory().getItemByItemId(9819), null, true);
  1428. }
  1429. }
  1430. closeNetConnection();
  1431. }
  1432.  
  1433. /**
  1434. * Return a table containing all Common L2RecipeList of the L2PcInstance.<BR><BR>
  1435. */
  1436. public L2RecipeList[] getCommonRecipeBook()
  1437. {
  1438. return _commonRecipeBook.values().toArray(new L2RecipeList[_commonRecipeBook.values().size()]);
  1439. }
  1440.  
  1441. /**
  1442. * Return a table containing all Dwarf L2RecipeList of the L2PcInstance.<BR><BR>
  1443. */
  1444. public L2RecipeList[] getDwarvenRecipeBook()
  1445. {
  1446. return _dwarvenRecipeBook.values().toArray(new L2RecipeList[_dwarvenRecipeBook.values().size()]);
  1447. }
  1448.  
  1449. /**
  1450. * Add a new L2RecipList to the table _commonrecipebook containing all L2RecipeList of the L2PcInstance <BR><BR>
  1451. *
  1452. * @param recipe The L2RecipeList to add to the _recipebook
  1453. *
  1454. */
  1455. public void registerCommonRecipeList(L2RecipeList recipe, boolean saveToDb)
  1456. {
  1457. _commonRecipeBook.put(recipe.getId(), recipe);
  1458.  
  1459. if (saveToDb)
  1460. insertNewRecipeData(recipe.getId(), false);
  1461. }
  1462.  
  1463. /**
  1464. * Add a new L2RecipList to the table _recipebook containing all L2RecipeList of the L2PcInstance <BR><BR>
  1465. *
  1466. * @param recipe The L2RecipeList to add to the _recipebook
  1467. *
  1468. */
  1469. public void registerDwarvenRecipeList(L2RecipeList recipe, boolean saveToDb)
  1470. {
  1471. _dwarvenRecipeBook.put(recipe.getId(), recipe);
  1472.  
  1473. if (saveToDb)
  1474. insertNewRecipeData(recipe.getId(), true);
  1475. }
  1476.  
  1477. /**
  1478. * @param RecipeID The Identifier of the L2RecipeList to check in the player's recipe books
  1479. *
  1480. * @return
  1481. * <b>TRUE</b> if player has the recipe on Common or Dwarven Recipe book else returns <b>FALSE</b>
  1482. */
  1483. public boolean hasRecipeList(int recipeId)
  1484. {
  1485. if (_dwarvenRecipeBook.containsKey(recipeId))
  1486. return true;
  1487. else if(_commonRecipeBook.containsKey(recipeId))
  1488. return true;
  1489. else
  1490. return false;
  1491. }
  1492.  
  1493. /**
  1494. * Tries to remove a L2RecipList from the table _DwarvenRecipeBook or from table _CommonRecipeBook, those table contain all L2RecipeList of the L2PcInstance <BR><BR>
  1495. *
  1496. * @param RecipeID The Identifier of the L2RecipeList to remove from the _recipebook
  1497. *
  1498. */
  1499. public void unregisterRecipeList(int recipeId)
  1500. {
  1501. if (_dwarvenRecipeBook.remove(recipeId) != null)
  1502. deleteRecipeData(recipeId, true);
  1503. else if (_commonRecipeBook.remove(recipeId) != null)
  1504. deleteRecipeData(recipeId, false);
  1505. else
  1506. _log.warning("Attempted to remove unknown RecipeList: "+recipeId);
  1507.  
  1508. L2ShortCut[] allShortCuts = getAllShortCuts();
  1509.  
  1510. for (L2ShortCut sc : allShortCuts)
  1511. {
  1512. if (sc != null && sc.getId() == recipeId && sc.getType() == L2ShortCut.TYPE_RECIPE)
  1513. deleteShortCut(sc.getSlot(), sc.getPage());
  1514. }
  1515. }
  1516.  
  1517. private void insertNewRecipeData(int recipeId, boolean isDwarf)
  1518. {
  1519. Connection con = null;
  1520. try
  1521. {
  1522. con = L2DatabaseFactory.getInstance().getConnection();
  1523. PreparedStatement statement = con.prepareStatement("INSERT INTO character_recipebook (charId, id, classIndex, type) values(?,?,?,?)");
  1524. statement.setInt(1, getObjectId());
  1525. statement.setInt(2,recipeId);
  1526. statement.setInt(3, isDwarf ? _classIndex : 0);
  1527. statement.setInt(4, isDwarf ? 1 : 0);
  1528. statement.execute();
  1529. statement.close();
  1530. }
  1531. catch (SQLException e)
  1532. {
  1533. if(_log.isLoggable(Level.SEVERE))
  1534. _log.log(Level.SEVERE, "SQL exception while inserting recipe: "+recipeId+" from character "+getObjectId(), e);
  1535. }
  1536. finally
  1537. {
  1538. try
  1539. {
  1540. con.close();
  1541. }
  1542. catch (Exception e){}
  1543. }
  1544. }
  1545.  
  1546. private void deleteRecipeData(int recipeId, boolean isDwarf)
  1547. {
  1548. Connection con = null;
  1549.  
  1550. try
  1551. {
  1552. con = L2DatabaseFactory.getInstance().getConnection();
  1553. PreparedStatement statement = con.prepareStatement("DELETE FROM character_recipebook WHERE charId=? AND id=? AND classIndex=?");
  1554. statement.setInt(1, getObjectId());
  1555. statement.setInt(2, recipeId);
  1556. statement.setInt(3, isDwarf ? _classIndex : 0);
  1557. statement.execute();
  1558. statement.close();
  1559. }
  1560. catch (SQLException e)
  1561. {
  1562. if (_log.isLoggable(Level.SEVERE))
  1563. _log.log(Level.SEVERE, "SQL exception while deleting recipe: "+recipeId+" from character "+getObjectId(), e);
  1564. }
  1565. finally
  1566. {
  1567. try
  1568. {
  1569. con.close();
  1570. } catch (Exception e) {}
  1571. }
  1572. }
  1573.  
  1574. /**
  1575. * Returns the Id for the last talked quest NPC.<BR><BR>
  1576. */
  1577. public int getLastQuestNpcObject()
  1578. {
  1579. return _questNpcObject;
  1580. }
  1581.  
  1582. public void setLastQuestNpcObject(int npcId)
  1583. {
  1584. _questNpcObject = npcId;
  1585. }
  1586.  
  1587. /**
  1588. * Return the QuestState object corresponding to the quest name.<BR><BR>
  1589. *
  1590. * @param quest The name of the quest
  1591. *
  1592. */
  1593. public QuestState getQuestState(String quest)
  1594. {
  1595. return _quests.get(quest);
  1596. }
  1597.  
  1598. /**
  1599. * Add a QuestState to the table _quest containing all quests began by the L2PcInstance.<BR><BR>
  1600. *
  1601. * @param qs The QuestState to add to _quest
  1602. *
  1603. */
  1604. public void setQuestState(QuestState qs)
  1605. {
  1606. _quests.put(qs.getQuestName(), qs);
  1607. }
  1608.  
  1609.  
  1610. /**
  1611. * Remove a QuestState from the table _quest containing all quests began by the L2PcInstance.<BR><BR>
  1612. *
  1613. * @param quest The name of the quest
  1614. *
  1615. */
  1616. public void delQuestState(String quest)
  1617. {
  1618. _quests.remove(quest);
  1619. }
  1620.  
  1621. private QuestState[] addToQuestStateArray(QuestState[] questStateArray, QuestState state) {
  1622. int len = questStateArray.length;
  1623. QuestState[] tmp = new QuestState[len+1];
  1624. for (int i=0; i < len; i++)
  1625. tmp[i] = questStateArray[i];
  1626. tmp[len] = state;
  1627. return tmp;
  1628. }
  1629.  
  1630. /**
  1631. * Return a table containing all Quest in progress from the table _quests.<BR><BR>
  1632. */
  1633. public Quest[] getAllActiveQuests()
  1634. {
  1635. FastList<Quest> quests = new FastList<Quest>();
  1636.  
  1637. for (QuestState qs : _quests.values())
  1638. {
  1639. if (qs == null)
  1640. continue;
  1641.  
  1642. int questId = qs.getQuest().getQuestIntId();
  1643. if ((questId>19999) || (questId<1))
  1644. continue;
  1645.  
  1646. if (!qs.isStarted() && !Config.DEVELOPER)
  1647. continue;
  1648.  
  1649. quests.add(qs.getQuest());
  1650. }
  1651.  
  1652. return quests.toArray(new Quest[quests.size()]);
  1653. }
  1654.  
  1655. /**
  1656. * Return a table containing all QuestState to modify after a L2Attackable killing.<BR><BR>
  1657. *
  1658. * @param npcId The Identifier of the L2Attackable attacked
  1659. *
  1660. */
  1661. public QuestState[] getQuestsForAttacks(L2Npc npc)
  1662. {
  1663. // Create a QuestState table that will contain all QuestState to modify
  1664. QuestState[] states = null;
  1665.  
  1666. // Go through the QuestState of the L2PcInstance quests
  1667. for (Quest quest : npc.getTemplate().getEventQuests(Quest.QuestEventType.ON_ATTACK))
  1668. {
  1669. // Check if the Identifier of the L2Attackable attck is needed for the current quest
  1670. if (getQuestState(quest.getName())!=null)
  1671. {
  1672. // Copy the current L2PcInstance QuestState in the QuestState table
  1673. if (states == null)
  1674. states = new QuestState[]{getQuestState(quest.getName())};
  1675. else
  1676. states = addToQuestStateArray(states, getQuestState(quest.getName()));
  1677. }
  1678. }
  1679.  
  1680. // Return a table containing all QuestState to modify
  1681. return states;
  1682. }
  1683.  
  1684. /**
  1685. * Return a table containing all QuestState to modify after a L2Attackable killing.<BR><BR>
  1686. *
  1687. * @param npcId The Identifier of the L2Attackable killed
  1688. *
  1689. */
  1690. public QuestState[] getQuestsForKills(L2Npc npc)
  1691. {
  1692. // Create a QuestState table that will contain all QuestState to modify
  1693. QuestState[] states = null;
  1694.  
  1695. // Go through the QuestState of the L2PcInstance quests
  1696. for (Quest quest : npc.getTemplate().getEventQuests(Quest.QuestEventType.ON_KILL))
  1697. {
  1698. // Check if the Identifier of the L2Attackable killed is needed for the current quest
  1699. if (getQuestState(quest.getName())!=null)
  1700. {
  1701. // Copy the current L2PcInstance QuestState in the QuestState table
  1702. if (states == null)
  1703. states = new QuestState[]{getQuestState(quest.getName())};
  1704. else
  1705. states = addToQuestStateArray(states, getQuestState(quest.getName()));
  1706. }
  1707. }
  1708.  
  1709. // Return a table containing all QuestState to modify
  1710. return states;
  1711. }
  1712.  
  1713. /**
  1714. * Return a table containing all QuestState from the table _quests in which the L2PcInstance must talk to the NPC.<BR><BR>
  1715. *
  1716. * @param npcId The Identifier of the NPC
  1717. *
  1718. */
  1719. public QuestState[] getQuestsForTalk(int npcId)
  1720. {
  1721. // Create a QuestState table that will contain all QuestState to modify
  1722. QuestState[] states = null;
  1723.  
  1724. // Go through the QuestState of the L2PcInstance quests
  1725. Quest[] quests = NpcTable.getInstance().getTemplate(npcId).getEventQuests(Quest.QuestEventType.ON_TALK);
  1726. if (quests != null)
  1727. {
  1728. for (Quest quest: quests)
  1729. {
  1730. if (quest != null)
  1731. {
  1732. // Copy the current L2PcInstance QuestState in the QuestState table
  1733. if (getQuestState(quest.getName())!=null)
  1734. {
  1735. if (states == null)
  1736. states = new QuestState[]{getQuestState(quest.getName())};
  1737. else
  1738. states = addToQuestStateArray(states, getQuestState(quest.getName()));
  1739. }
  1740. }
  1741. }
  1742. }
  1743.  
  1744. // Return a table containing all QuestState to modify
  1745. return states;
  1746. }
  1747.  
  1748. public QuestState processQuestEvent(String quest, String event)
  1749. {
  1750. QuestState retval = null;
  1751. if (event == null)
  1752. event = "";
  1753. if (!_quests.containsKey(quest))
  1754. return retval;
  1755. QuestState qs = getQuestState(quest);
  1756. if (qs == null && event.length() == 0)
  1757. return retval;
  1758. if (qs == null) {
  1759. Quest q = QuestManager.getInstance().getQuest(quest);
  1760. if (q == null)
  1761. return retval;
  1762. qs = q.newQuestState(this);
  1763. }
  1764. if (qs != null) {
  1765. if (getLastQuestNpcObject() > 0)
  1766. {
  1767. L2Object object = L2World.getInstance().findObject(getLastQuestNpcObject());
  1768. if (object instanceof L2Npc && isInsideRadius(object, L2Npc.INTERACTION_DISTANCE, false, false))
  1769. {
  1770. L2Npc npc = (L2Npc)object;
  1771. QuestState[] states = getQuestsForTalk(npc.getNpcId());
  1772.  
  1773. if (states != null)
  1774. {
  1775. for (QuestState state : states)
  1776. {
  1777. if ((state.getQuest().getQuestIntId() == qs.getQuest().getQuestIntId()))
  1778. {
  1779. if (qs.getQuest().notifyEvent(event, npc, this))
  1780. showQuestWindow(quest, State.getStateName(qs.getState()));
  1781.  
  1782. retval = qs;
  1783. }
  1784. }
  1785. sendPacket(new QuestList());
  1786. }
  1787. }
  1788. }
  1789. }
  1790.  
  1791. return retval;
  1792. }
  1793.  
  1794. private void showQuestWindow(String questId, String stateId)
  1795. {
  1796. String path = "data/scripts/quests/"+questId+"/"+stateId+".htm";
  1797. String content = HtmCache.getInstance().getHtm(path); //TODO path for quests html
  1798.  
  1799. if (content != null)
  1800. {
  1801. if (Config.DEBUG)
  1802. _log.fine("Showing quest window for quest "+questId+" state "+stateId+" html path: " + path);
  1803.  
  1804. NpcHtmlMessage npcReply = new NpcHtmlMessage(5);
  1805. npcReply.setHtml(content);
  1806. sendPacket(npcReply);
  1807. }
  1808.  
  1809. sendPacket( ActionFailed.STATIC_PACKET );
  1810. }
  1811.  
  1812. /** List of all QuestState instance that needs to be notified of this L2PcInstance's or its pet's death */
  1813. private List<QuestState> _NotifyQuestOfDeathList = new FastList<QuestState>();
  1814.  
  1815. /**
  1816. * Add QuestState instance that is to be notified of L2PcInstance's death.<BR><BR>
  1817. *
  1818. * @param qs The QuestState that subscribe to this event
  1819. *
  1820. */
  1821. public void addNotifyQuestOfDeath (QuestState qs)
  1822. {
  1823. if (qs == null || _NotifyQuestOfDeathList.contains(qs))
  1824. return;
  1825.  
  1826. _NotifyQuestOfDeathList.add(qs);
  1827. }
  1828.  
  1829. /**
  1830. * Remove QuestState instance that is to be notified of L2PcInstance's death.<BR><BR>
  1831. *
  1832. * @param qs The QuestState that subscribe to this event
  1833. *
  1834. */
  1835. public void removeNotifyQuestOfDeath (QuestState qs)
  1836. {
  1837. if (qs == null || !_NotifyQuestOfDeathList.contains(qs))
  1838. return;
  1839.  
  1840. _NotifyQuestOfDeathList.remove(qs);
  1841. }
  1842.  
  1843. /**
  1844. * Return a list of QuestStates which registered for notify of death of this L2PcInstance.<BR><BR>
  1845. */
  1846. public final List<QuestState> getNotifyQuestOfDeath ()
  1847. {
  1848. if (_NotifyQuestOfDeathList == null)
  1849. _NotifyQuestOfDeathList = new FastList<QuestState>();
  1850.  
  1851. return _NotifyQuestOfDeathList;
  1852. }
  1853.  
  1854. /**
  1855. * Return a table containing all L2ShortCut of the L2PcInstance.<BR><BR>
  1856. */
  1857. public L2ShortCut[] getAllShortCuts()
  1858. {
  1859. return _shortCuts.getAllShortCuts();
  1860. }
  1861.  
  1862. /**
  1863. * Return the L2ShortCut of the L2PcInstance corresponding to the position (page-slot).<BR><BR>
  1864. *
  1865. * @param slot The slot in wich the shortCuts is equiped
  1866. * @param page The page of shortCuts containing the slot
  1867. *
  1868. */
  1869. public L2ShortCut getShortCut(int slot, int page)
  1870. {
  1871. return _shortCuts.getShortCut(slot, page);
  1872. }
  1873.  
  1874. /**
  1875. * Add a L2shortCut to the L2PcInstance _shortCuts<BR><BR>
  1876. */
  1877. public void registerShortCut(L2ShortCut shortcut)
  1878. {
  1879. _shortCuts.registerShortCut(shortcut);
  1880. }
  1881.  
  1882. /**
  1883. * Delete the L2ShortCut corresponding to the position (page-slot) from the L2PcInstance _shortCuts.<BR><BR>
  1884. */
  1885. public void deleteShortCut(int slot, int page)
  1886. {
  1887. _shortCuts.deleteShortCut(slot, page);
  1888. }
  1889.  
  1890. /**
  1891. * Add a L2Macro to the L2PcInstance _macroses<BR><BR>
  1892. */
  1893. public void registerMacro(L2Macro macro)
  1894. {
  1895. _macroses.registerMacro(macro);
  1896. }
  1897.  
  1898. /**
  1899. * Delete the L2Macro corresponding to the Identifier from the L2PcInstance _macroses.<BR><BR>
  1900. */
  1901. public void deleteMacro(int id)
  1902. {
  1903. _macroses.deleteMacro(id);
  1904. }
  1905.  
  1906. /**
  1907. * Return all L2Macro of the L2PcInstance.<BR><BR>
  1908. */
  1909. public MacroList getMacroses()
  1910. {
  1911. return _macroses;
  1912. }
  1913.  
  1914. /**
  1915. * Set the siege state of the L2PcInstance.<BR><BR>
  1916. * 1 = attacker, 2 = defender, 0 = not involved
  1917. */
  1918. public void setSiegeState(byte siegeState)
  1919. {
  1920. _siegeState = siegeState;
  1921. }
  1922. /**
  1923. * Get the siege state of the L2PcInstance.<BR><BR>
  1924. * 1 = attacker, 2 = defender, 0 = not involved
  1925. */
  1926. public byte getSiegeState()
  1927. {
  1928. return _siegeState;
  1929. }
  1930.  
  1931. /**
  1932. * Set the PvP Flag of the L2PcInstance.<BR><BR>
  1933. */
  1934. public void setPvpFlag(int pvpFlag)
  1935. {
  1936. _pvpFlag = (byte)pvpFlag;
  1937. }
  1938.  
  1939. public byte getPvpFlag()
  1940. {
  1941. return _pvpFlag;
  1942. }
  1943.  
  1944. @Override
  1945. public void updatePvPFlag(int value)
  1946. {
  1947. if (getPvpFlag() == value)
  1948. return;
  1949. setPvpFlag(value);
  1950.  
  1951. sendPacket(new UserInfo(this));
  1952. sendPacket(new ExBrExtraUserInfo(this));
  1953.  
  1954. // If this player has a pet update the pets pvp flag as well
  1955. if (getPet() != null) sendPacket(new RelationChanged(getPet(), getRelation(this), false));
  1956.  
  1957. Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
  1958. //synchronized (getKnownList().getKnownPlayers())
  1959. {
  1960. for (L2PcInstance target : plrs)
  1961. {
  1962. target.sendPacket(new RelationChanged(this, getRelation(this), isAutoAttackable(target)));
  1963. if (getPet() != null)
  1964. target.sendPacket(new RelationChanged(getPet(), getRelation(this), isAutoAttackable(target)));
  1965. }
  1966. }
  1967. }
  1968.  
  1969. @Override
  1970. public void revalidateZone(boolean force)
  1971. {
  1972. // Cannot validate if not in a world region (happens during teleport)
  1973. if (getWorldRegion() == null) return;
  1974.  
  1975. // This function is called too often from movement code
  1976. if (force) _zoneValidateCounter = 4;
  1977. else
  1978. {
  1979. _zoneValidateCounter--;
  1980. if (_zoneValidateCounter < 0)
  1981. _zoneValidateCounter = 4;
  1982. else return;
  1983. }
  1984.  
  1985. getWorldRegion().revalidateZones(this);
  1986.  
  1987. if (Config.ALLOW_WATER)
  1988. checkWaterState();
  1989.  
  1990. if (isInsideZone(ZONE_SIEGE))
  1991. {
  1992. if (_lastCompassZone == ExSetCompassZoneCode.SIEGEWARZONE2) return;
  1993. _lastCompassZone = ExSetCompassZoneCode.SIEGEWARZONE2;
  1994. ExSetCompassZoneCode cz = new ExSetCompassZoneCode(ExSetCompassZoneCode.SIEGEWARZONE2);
  1995. sendPacket(cz);
  1996. }
  1997. else if (isInsideZone(ZONE_PVP))
  1998. {
  1999. if (_lastCompassZone == ExSetCompassZoneCode.PVPZONE) return;
  2000. _lastCompassZone = ExSetCompassZoneCode.PVPZONE;
  2001. ExSetCompassZoneCode cz = new ExSetCompassZoneCode(ExSetCompassZoneCode.PVPZONE);
  2002. sendPacket(cz);
  2003. }
  2004. else if (isIn7sDungeon())
  2005. {
  2006. if (_lastCompassZone == ExSetCompassZoneCode.SEVENSIGNSZONE) return;
  2007. _lastCompassZone = ExSetCompassZoneCode.SEVENSIGNSZONE;
  2008. ExSetCompassZoneCode cz = new ExSetCompassZoneCode(ExSetCompassZoneCode.SEVENSIGNSZONE);
  2009. sendPacket(cz);
  2010. }
  2011. else if (isInsideZone(ZONE_PEACE))
  2012. {
  2013. if (_lastCompassZone == ExSetCompassZoneCode.PEACEZONE) return;
  2014. _lastCompassZone = ExSetCompassZoneCode.PEACEZONE;
  2015. ExSetCompassZoneCode cz = new ExSetCompassZoneCode(ExSetCompassZoneCode.PEACEZONE);
  2016. sendPacket(cz);
  2017. }
  2018. else
  2019. {
  2020. if (_lastCompassZone == ExSetCompassZoneCode.GENERALZONE) return;
  2021. if (_lastCompassZone == ExSetCompassZoneCode.SIEGEWARZONE2) updatePvPStatus();
  2022. _lastCompassZone = ExSetCompassZoneCode.GENERALZONE;
  2023. ExSetCompassZoneCode cz = new ExSetCompassZoneCode(ExSetCompassZoneCode.GENERALZONE);
  2024. sendPacket(cz);
  2025. }
  2026. }
  2027.  
  2028. /**
  2029. * Return True if the L2PcInstance can Craft Dwarven Recipes.<BR><BR>
  2030. */
  2031. public boolean hasDwarvenCraft()
  2032. {
  2033. return getSkillLevel(L2Skill.SKILL_CREATE_DWARVEN) >= 1;
  2034. }
  2035.  
  2036. public int getDwarvenCraft()
  2037. {
  2038. return getSkillLevel(L2Skill.SKILL_CREATE_DWARVEN);
  2039. }
  2040.  
  2041. /**
  2042. * Return True if the L2PcInstance can Craft Dwarven Recipes.<BR><BR>
  2043. */
  2044. public boolean hasCommonCraft()
  2045. {
  2046. return getSkillLevel(L2Skill.SKILL_CREATE_COMMON) >= 1;
  2047. }
  2048.  
  2049. public int getCommonCraft()
  2050. {
  2051. return getSkillLevel(L2Skill.SKILL_CREATE_COMMON);
  2052. }
  2053.  
  2054. /**
  2055. * Return the PK counter of the L2PcInstance.<BR><BR>
  2056. */
  2057. public int getPkKills()
  2058. {
  2059. return _pkKills;
  2060. }
  2061.  
  2062. /**
  2063. * Set the PK counter of the L2PcInstance.<BR><BR>
  2064. */
  2065. public void setPkKills(int pkKills)
  2066. {
  2067. _pkKills = pkKills;
  2068. }
  2069.  
  2070. /**
  2071. * Return the _deleteTimer of the L2PcInstance.<BR><BR>
  2072. */
  2073. public long getDeleteTimer()
  2074. {
  2075. return _deleteTimer;
  2076. }
  2077.  
  2078. /**
  2079. * Set the _deleteTimer of the L2PcInstance.<BR><BR>
  2080. */
  2081. public void setDeleteTimer(long deleteTimer)
  2082. {
  2083. _deleteTimer = deleteTimer;
  2084. }
  2085.  
  2086. /**
  2087. * Return the current weight of the L2PcInstance.<BR><BR>
  2088. */
  2089. public int getCurrentLoad()
  2090. {
  2091. return _inventory.getTotalWeight();
  2092. }
  2093. /**
  2094. * Return date of las update of recomPoints
  2095. */
  2096. public long getLastRecomUpdate()
  2097. {
  2098. return _lastRecomUpdate;
  2099. }
  2100. public void setLastRecomUpdate(long date)
  2101. {
  2102. _lastRecomUpdate = date;
  2103. }
  2104. /**
  2105. * Return the number of recommandation obtained by the L2PcInstance.<BR><BR>
  2106. */
  2107. public int getRecomHave()
  2108. {
  2109. return _recomHave;
  2110. }
  2111.  
  2112. /**
  2113. * Increment the number of recommandation obtained by the L2PcInstance (Max : 255).<BR><BR>
  2114. */
  2115. protected void incRecomHave()
  2116. {
  2117. if (_recomHave < 255)
  2118. _recomHave++;
  2119. }
  2120.  
  2121. /**
  2122. * Set the number of recommandation obtained by the L2PcInstance (Max : 255).<BR><BR>
  2123. */
  2124. public void setRecomHave(int value)
  2125. {
  2126. if (value > 255)
  2127. _recomHave = 255;
  2128. else if (value < 0)
  2129. _recomHave = 0;
  2130. else
  2131. _recomHave = value;
  2132. }
  2133.  
  2134.  
  2135.  
  2136. /**
  2137. * Return the number of recommandation that the L2PcInstance can give.<BR><BR>
  2138. */
  2139. public int getRecomLeft()
  2140. {
  2141. return _recomLeft;
  2142. }
  2143.  
  2144. public int getDeaths()
  2145. {
  2146. return _deaths;
  2147. }
  2148. /**
  2149. * Increase the deaths
  2150. */
  2151. public void increaseDeaths()
  2152. {
  2153. setDeaths(getDeaths() + 1);
  2154. }
  2155.  
  2156. public void setDeaths(int deaths)
  2157. {
  2158. _deaths = deaths;
  2159. }
  2160.  
  2161. /**
  2162. * Increment the number of recommandation that the L2PcInstance can give.<BR><BR>
  2163. */
  2164. protected void decRecomLeft()
  2165. {
  2166. if (_recomLeft > 0)
  2167. _recomLeft--;
  2168. }
  2169.  
  2170. public void giveRecom(L2PcInstance target)
  2171. {
  2172. if (Config.ALT_RECOMMEND)
  2173. {
  2174. Connection con = null;
  2175. try
  2176. {
  2177. con = L2DatabaseFactory.getInstance().getConnection();
  2178. PreparedStatement statement = con.prepareStatement(ADD_CHAR_RECOM);
  2179. statement.setInt(1, getObjectId());
  2180. statement.setInt(2, target.getObjectId());
  2181. statement.execute();
  2182. statement.close();
  2183. }
  2184. catch (Exception e)
  2185. {
  2186. _log.log(Level.SEVERE, "Failed updating character recommendations.", e);
  2187. }
  2188. finally
  2189. {
  2190. try { con.close(); } catch (Exception e) {}
  2191. }
  2192. }
  2193. target.incRecomHave();
  2194. decRecomLeft();
  2195. _recomChars.add(target.getObjectId());
  2196. }
  2197.  
  2198. public boolean canRecom(L2PcInstance target)
  2199. {
  2200. return !_recomChars.contains(target.getObjectId());
  2201. }
  2202.  
  2203. /**
  2204. * Set the exp of the L2PcInstance before a death
  2205. * @param exp
  2206. */
  2207. public void setExpBeforeDeath(long exp)
  2208. {
  2209. _expBeforeDeath = exp;
  2210. }
  2211.  
  2212. public long getExpBeforeDeath()
  2213. {
  2214. return _expBeforeDeath;
  2215. }
  2216.  
  2217. /**
  2218. * Return the Karma of the L2PcInstance.<BR><BR>
  2219. */
  2220. public int getKarma()
  2221. {
  2222. return _karma;
  2223. }
  2224.  
  2225. /**
  2226. * Set the Karma of the L2PcInstance and send a Server->Client packet StatusUpdate (broadcast).<BR><BR>
  2227. */
  2228. public void setKarma(int karma)
  2229. {
  2230. if (karma < 0) karma = 0;
  2231. if (_karma == 0 && karma > 0)
  2232. {
  2233. Collection<L2Object> objs = getKnownList().getKnownObjects().values();
  2234. //synchronized (getKnownList().getKnownObjects())
  2235. {
  2236. for (L2Object object : objs)
  2237. {
  2238. if (!(object instanceof L2GuardInstance))
  2239. continue;
  2240.  
  2241. if (((L2GuardInstance) object).getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)
  2242. ((L2GuardInstance) object).getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null);
  2243. }
  2244. }
  2245. }
  2246. else if (_karma > 0 && karma == 0)
  2247. {
  2248. // Send a Server->Client StatusUpdate packet with Karma and PvP Flag to the L2PcInstance and all L2PcInstance to inform (broadcast)
  2249. setKarmaFlag(0);
  2250. }
  2251.  
  2252. _karma = karma;
  2253. broadcastKarma();
  2254. }
  2255.  
  2256. /**
  2257. * Return the max weight that the L2PcInstance can load.<BR><BR>
  2258. */
  2259. public int getMaxLoad()
  2260. {
  2261. // Weight Limit = (CON Modifier*69000)*Skills
  2262. // Source http://l2p.bravehost.com/weightlimit.html (May 2007)
  2263. // Fitted exponential curve to the data
  2264. int con = getCON();
  2265. if (con < 1) return 31000;
  2266. if (con > 59) return 176000;
  2267. double baseLoad = Math.pow(1.029993928, con)*30495.627366;
  2268. return (int)calcStat(Stats.MAX_LOAD, baseLoad*Config.ALT_WEIGHT_LIMIT, this, null);
  2269. }
  2270.  
  2271. public int getExpertisePenalty()
  2272. {
  2273. return _expertisePenalty;
  2274. }
  2275.  
  2276. public int getWeightPenalty()
  2277. {
  2278. if (_dietMode)
  2279. return 0;
  2280. return _curWeightPenalty;
  2281. }
  2282.  
  2283. /**
  2284. * Update the overloaded status of the L2PcInstance.<BR><BR>
  2285. */
  2286. public void refreshOverloaded()
  2287. {
  2288. int maxLoad = getMaxLoad();
  2289. if (maxLoad > 0)
  2290. {
  2291. long weightproc = (long)getCurrentLoad() * 1000 / maxLoad;
  2292. weightproc *= calcStat(Stats.WEIGHT_LIMIT, 1, this, null);
  2293. int newWeightPenalty;
  2294. if (weightproc < 500 || _dietMode)
  2295. {
  2296. newWeightPenalty = 0;
  2297. }
  2298. else if (weightproc < 666)
  2299. {
  2300. newWeightPenalty = 1;
  2301. }
  2302. else if ( weightproc < 800)
  2303. {
  2304. newWeightPenalty = 2;
  2305. }
  2306. else if (weightproc < 1000)
  2307. {
  2308. newWeightPenalty = 3;
  2309. }
  2310. else
  2311. {
  2312. newWeightPenalty = 4;
  2313. }
  2314.  
  2315. if (_curWeightPenalty != newWeightPenalty)
  2316. {
  2317. _curWeightPenalty = newWeightPenalty;
  2318. if (newWeightPenalty > 0 && !_dietMode)
  2319. {
  2320. super.addSkill(SkillTable.getInstance().getInfo(4270,newWeightPenalty));
  2321. setIsOverloaded(getCurrentLoad() > maxLoad);
  2322. }
  2323. else
  2324. {
  2325. super.removeSkill(getKnownSkill(4270));
  2326. setIsOverloaded(false);
  2327. }
  2328. sendPacket(new UserInfo(this));
  2329. sendPacket(new EtcStatusUpdate(this));
  2330. broadcastPacket(new CharInfo(this));
  2331. broadcastPacket(new ExBrExtraUserInfo(this));
  2332. }
  2333. }
  2334. }
  2335.  
  2336. public void refreshExpertisePenalty()
  2337. {
  2338. int newPenalty = 0;
  2339.  
  2340. for (L2ItemInstance item : getInventory().getItems())
  2341. {
  2342. if (item != null && item.isEquipped())
  2343. {
  2344. int crystaltype = item.getItem().getCrystalType();
  2345.  
  2346. if (crystaltype > newPenalty)
  2347. newPenalty = crystaltype;
  2348. }
  2349. }
  2350.  
  2351. newPenalty = newPenalty - getExpertiseIndex();
  2352.  
  2353. if (newPenalty <= 0)
  2354. newPenalty = 0;
  2355.  
  2356. if (getExpertisePenalty() != newPenalty)
  2357. {
  2358. _expertisePenalty = newPenalty;
  2359.  
  2360. if (newPenalty > 0)
  2361. super.addSkill(SkillTable.getInstance().getInfo(4267, 1)); // level used to be newPenalty
  2362. else
  2363. super.removeSkill(getKnownSkill(4267));
  2364.  
  2365. sendPacket(new EtcStatusUpdate(this));
  2366. }
  2367. }
  2368.  
  2369. public void checkIfWeaponIsAllowed()
  2370. {
  2371. // Override for Gamemasters
  2372. if (isGM())
  2373. return;
  2374.  
  2375. // Iterate through all effects currently on the character.
  2376. for (L2Effect currenteffect : getAllEffects())
  2377. {
  2378. L2Skill effectSkill = currenteffect.getSkill();
  2379.  
  2380. // Ignore all buff skills that are party related (ie. songs, dances) while still remaining weapon dependant on cast though.
  2381. if (!effectSkill.isOffensive() && !(effectSkill.getTargetType() == SkillTargetType.TARGET_PARTY && effectSkill.getSkillType() == L2SkillType.BUFF))
  2382. {
  2383. // Check to rest to assure current effect meets weapon requirements.
  2384. if (!effectSkill.getWeaponDependancy(this))
  2385. {
  2386. sendMessage(effectSkill.getName() + " cannot be used with this weapon.");
  2387.  
  2388. if (Config.DEBUG)
  2389. _log.info(" | Skill "+effectSkill.getName()+" has been disabled for ("+getName()+"); Reason: Incompatible Weapon Type.");
  2390.  
  2391. currenteffect.exit();
  2392. }
  2393. }
  2394.  
  2395. continue;
  2396. }
  2397. }
  2398.  
  2399. public void checkSSMatch(L2ItemInstance equipped, L2ItemInstance unequipped)
  2400. {
  2401. if (unequipped == null)
  2402. return;
  2403.  
  2404. if (unequipped.getItem().getType2() == L2Item.TYPE2_WEAPON &&
  2405. (equipped == null ? true : equipped.getItem().getCrystalType() != unequipped.getItem().getCrystalType()))
  2406. {
  2407. for (L2ItemInstance ss : getInventory().getItems())
  2408. {
  2409. if (ss == null)
  2410. continue;
  2411.  
  2412. int _itemId = ss.getItemId();
  2413.  
  2414. if (((_itemId >= 2509 && _itemId <= 2514) ||
  2415. (_itemId >= 3947 && _itemId <= 3952) ||
  2416. (_itemId <= 1804 && _itemId >= 1808) ||
  2417. _itemId == 5789 || _itemId == 5790 || _itemId == 1835
  2418. || (_itemId >=22072 && _itemId <=22086)) &&
  2419. ss.getItem().getCrystalType() == unequipped.getItem().getCrystalType())
  2420. {
  2421. sendPacket(new ExAutoSoulShot(_itemId, 0));
  2422.  
  2423. SystemMessage sm = new SystemMessage(SystemMessageId.AUTO_USE_OF_S1_CANCELLED);
  2424. sm.addString(ss.getItemName());
  2425. sendPacket(sm);
  2426. }
  2427. }
  2428. }
  2429. }
  2430.  
  2431. public void useEquippableItem(L2ItemInstance item, boolean abortAttack)
  2432. {
  2433. // Equip or unEquip
  2434. L2ItemInstance[] items = null;
  2435. final boolean isEquiped = item.isEquipped();
  2436. final int oldInvLimit = getInventoryLimit();
  2437. SystemMessage sm = null;
  2438. L2ItemInstance old = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LRHAND);
  2439. if (old == null)
  2440. old = getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
  2441.  
  2442. checkSSMatch(item, old);
  2443.  
  2444. if (isEquiped)
  2445. {
  2446. if (item.getEnchantLevel() > 0)
  2447. {
  2448. sm = new SystemMessage(SystemMessageId.EQUIPMENT_S1_S2_REMOVED);
  2449. sm.addNumber(item.getEnchantLevel());
  2450. sm.addItemName(item);
  2451. }
  2452. else
  2453. {
  2454. sm = new SystemMessage(SystemMessageId.S1_DISARMED);
  2455. sm.addItemName(item);
  2456. }
  2457. sendPacket(sm);
  2458.  
  2459. int slot = getInventory().getSlotFromItem(item);
  2460. // we cant unequip talisman by body slot
  2461. if (slot == L2Item.SLOT_DECO)
  2462. items = getInventory().unEquipItemInSlotAndRecord(item.getLocationSlot());
  2463. else
  2464. items = getInventory().unEquipItemInBodySlotAndRecord(slot);
  2465. }
  2466. else
  2467. {
  2468. int tempBodyPart = item.getItem().getBodyPart();
  2469. L2ItemInstance tempItem = getInventory().getPaperdollItemByL2ItemId(tempBodyPart);
  2470.  
  2471. //check if the item replaces a wear-item
  2472. if (tempItem != null && tempItem.isWear())
  2473. {
  2474. // dont allow an item to replace a wear-item
  2475. return;
  2476. }
  2477. else if (tempBodyPart == L2Item.SLOT_LR_HAND)
  2478. {
  2479. // this may not remove left OR right hand equipment
  2480. tempItem = getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
  2481. if (tempItem != null && tempItem.isWear()) return;
  2482.  
  2483. tempItem = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
  2484. if (tempItem != null && tempItem.isWear()) return;
  2485. }
  2486. else if (tempBodyPart == L2Item.SLOT_FULL_ARMOR)
  2487. {
  2488. // this may not remove chest or leggins
  2489. tempItem = getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST);
  2490. if (tempItem != null && tempItem.isWear()) return;
  2491.  
  2492. tempItem = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LEGS);
  2493. if (tempItem != null && tempItem.isWear()) return;
  2494. }
  2495.  
  2496. if (item.getEnchantLevel() > 0)
  2497. {
  2498. sm = new SystemMessage(SystemMessageId.S1_S2_EQUIPPED);
  2499. sm.addNumber(item.getEnchantLevel());
  2500. sm.addItemName(item);
  2501. }
  2502. else
  2503. {
  2504. sm = new SystemMessage(SystemMessageId.S1_EQUIPPED);
  2505. sm.addItemName(item);
  2506. }
  2507. sendPacket(sm);
  2508.  
  2509. items = getInventory().equipItemAndRecord(item);
  2510.  
  2511. // Consume mana - will start a task if required; returns if item is not a shadow item
  2512. item.decreaseMana(false);
  2513. }
  2514. sm = null;
  2515.  
  2516. refreshExpertisePenalty();
  2517.  
  2518. /**
  2519. // remove effects which doesn't match weapon type (but not party buffs)
  2520. if (item.getItem().getType2() == L2Item.TYPE2_WEAPON)
  2521. checkIfWeaponIsAllowed();
  2522. **/
  2523.  
  2524. broadcastUserInfo();
  2525.  
  2526. InventoryUpdate iu = new InventoryUpdate();
  2527. iu.addItems(Arrays.asList(items));
  2528. sendPacket(iu);
  2529.  
  2530. if (abortAttack) abortAttack();
  2531.  
  2532. if (getInventoryLimit() != oldInvLimit)
  2533. sendPacket(new ExStorageMaxCount(this));
  2534. }
  2535.  
  2536. /**
  2537. * Return the the PvP Kills of the L2PcInstance (Number of player killed during a PvP).<BR><BR>
  2538. */
  2539. public int getPvpKills()
  2540. {
  2541. return _pvpKills;
  2542. }
  2543. public void colorsCheck()
  2544. {
  2545. if (Config.ALLOW_PVP_TITLE_COLOR_SYSTEM)
  2546. {
  2547. for (int i : Config.PVP_COLORS.keySet())
  2548. {
  2549. if (getPvpKills() >= i)
  2550. {
  2551. getAppearance().setTitleColor(Config.PVP_COLORS.get(i));
  2552. broadcastUserInfo();
  2553. }
  2554. }
  2555. }
  2556.  
  2557.  
  2558. }
  2559.  
  2560. /**
  2561. * Set the the PvP Kills of the L2PcInstance (Number of player killed during a PvP).<BR><BR>
  2562. */
  2563. public void setPvpKills(int pvpKills)
  2564. {
  2565. _pvpKills = pvpKills;
  2566. }
  2567.  
  2568. public int getPvpKillsAnnoun()
  2569. {
  2570. return _pvpKillsAnnoun;
  2571. }
  2572.  
  2573. public void setPvpKillsAnnoun(int pvpKillsAnnoun)
  2574. {
  2575. _pvpKillsAnnoun = pvpKillsAnnoun;
  2576. }
  2577.  
  2578. /**
  2579. * Return the Fame of this L2PcInstance <BR><BR>
  2580. * @return
  2581. */
  2582. public int getFame()
  2583. {
  2584. return _fame;
  2585. }
  2586.  
  2587. /**
  2588. * Set the Fame of this L2PcInstane <BR><BR>
  2589. * @param fame
  2590. */
  2591. public void setFame(int fame)
  2592. {
  2593. if (fame > Config.MAX_PERSONAL_FAME_POINTS)
  2594. _fame = Config.MAX_PERSONAL_FAME_POINTS;
  2595. else
  2596. _fame = fame;
  2597. }
  2598.  
  2599. /**
  2600. * Return the ClassId object of the L2PcInstance contained in L2PcTemplate.<BR><BR>
  2601. */
  2602. public ClassId getClassId()
  2603. {
  2604. return getTemplate().classId;
  2605. }
  2606.  
  2607. /**
  2608. * Set the template of the L2PcInstance.<BR><BR>
  2609. *
  2610. * @param Id The Identifier of the L2PcTemplate to set to the L2PcInstance
  2611. *
  2612. */
  2613. public void setClassId(int Id)
  2614. {
  2615. if (!_subclassLock.tryLock())
  2616. return;
  2617.  
  2618. try
  2619. {
  2620. if (getLvlJoinedAcademy() != 0 && _clan != null && PlayerClass.values()[Id].getLevel() == ClassLevel.Third)
  2621. {
  2622. if(getLvlJoinedAcademy() <= 16)
  2623. _clan.setReputationScore(_clan.getReputationScore()+Config.JOIN_ACADEMY_MAX_REP_SCORE, true);
  2624. else if(getLvlJoinedAcademy() >= 39)
  2625. _clan.setReputationScore(_clan.getReputationScore()+Config.JOIN_ACADEMY_MIN_REP_SCORE, true);
  2626. else
  2627. _clan.setReputationScore(_clan.getReputationScore()+(Config.JOIN_ACADEMY_MAX_REP_SCORE-(getLvlJoinedAcademy()-16)*20), true);
  2628. setLvlJoinedAcademy(0);
  2629. //oust pledge member from the academy, cuz he has finished his 2nd class transfer
  2630. SystemMessage msg = new SystemMessage(SystemMessageId.CLAN_MEMBER_S1_EXPELLED);
  2631. msg.addPcName(this);
  2632. _clan.broadcastToOnlineMembers(msg);
  2633. _clan.broadcastToOnlineMembers(new PledgeShowMemberListDelete(getName()));
  2634. _clan.removeClanMember(getObjectId(), 0);
  2635. sendPacket(new SystemMessage(SystemMessageId.ACADEMY_MEMBERSHIP_TERMINATED));
  2636.  
  2637. // receive graduation gift
  2638. getInventory().addItem("Gift",8181,1,this,null); // give academy circlet
  2639. }
  2640. if (isSubClassActive())
  2641. {
  2642. getSubClasses().get(_classIndex).setClassId(Id);
  2643. }
  2644. setTarget(this);
  2645. broadcastPacket(new MagicSkillUse(this, 5103, 1, 1000, 0));
  2646. setClassTemplate(Id);
  2647. if (getClassId().level() == 3)
  2648. sendPacket(new SystemMessage(SystemMessageId.THIRD_CLASS_TRANSFER));
  2649. else
  2650. sendPacket(new SystemMessage(SystemMessageId.CLASS_TRANSFER));
  2651.  
  2652. // Update class icon in party and clan
  2653. if (isInParty())
  2654. getParty().broadcastToPartyMembers(new PartySmallWindowUpdate(this));
  2655.  
  2656. if (getClan() != null)
  2657. getClan().broadcastToOnlineMembers(new PledgeShowMemberListUpdate(this));
  2658.  
  2659. if (Config.AUTO_LEARN_SKILLS)
  2660. rewardSkills();
  2661. }
  2662. finally
  2663. {
  2664. _subclassLock.unlock();
  2665. }
  2666. }
  2667.  
  2668. /** Return the Experience of the L2PcInstance. */
  2669. public long getExp() { return getStat().getExp(); }
  2670.  
  2671. public void setActiveEnchantAttrItem(L2ItemInstance stone)
  2672. {
  2673. _activeEnchantAttrItem = stone;
  2674. }
  2675.  
  2676. public L2ItemInstance getActiveEnchantAttrItem()
  2677. {
  2678. return _activeEnchantAttrItem;
  2679. }
  2680.  
  2681. public void setActiveEnchantItem(L2ItemInstance scroll)
  2682. {
  2683. // If we dont have a Enchant Item, we are not enchanting.
  2684. if (scroll == null)
  2685. {
  2686. setActiveEnchantSupportItem(null);
  2687. setActiveEnchantTimestamp(0);
  2688. setIsEnchanting(false);
  2689. }
  2690. _activeEnchantItem = scroll;
  2691. }
  2692.  
  2693. public L2ItemInstance getActiveEnchantItem()
  2694. {
  2695. return _activeEnchantItem;
  2696. }
  2697.  
  2698. public void setActiveEnchantSupportItem(L2ItemInstance item)
  2699. {
  2700. _activeEnchantSupportItem = item;
  2701. }
  2702.  
  2703. public L2ItemInstance getActiveEnchantSupportItem()
  2704. {
  2705. return _activeEnchantSupportItem;
  2706. }
  2707.  
  2708. public long getActiveEnchantTimestamp()
  2709. {
  2710. return _activeEnchantTimestamp;
  2711. }
  2712.  
  2713. public void setActiveEnchantTimestamp(long val)
  2714. {
  2715. _activeEnchantTimestamp = val;
  2716. }
  2717.  
  2718. public void setIsEnchanting(boolean val)
  2719. {
  2720. _isEnchanting = val;
  2721. }
  2722.  
  2723. public boolean isEnchanting()
  2724. {
  2725. return _isEnchanting;
  2726. }
  2727.  
  2728. /**
  2729. * Set the fists weapon of the L2PcInstance (used when no weapon is equiped).<BR><BR>
  2730. *
  2731. * @param weaponItem The fists L2Weapon to set to the L2PcInstance
  2732. *
  2733. */
  2734. public void setFistsWeaponItem(L2Weapon weaponItem)
  2735. {
  2736. _fistsWeaponItem = weaponItem;
  2737. }
  2738.  
  2739. /**
  2740. * Return the fists weapon of the L2PcInstance (used when no weapon is equiped).<BR><BR>
  2741. */
  2742. public L2Weapon getFistsWeaponItem()
  2743. {
  2744. return _fistsWeaponItem;
  2745. }
  2746.  
  2747. /**
  2748. * Return the fists weapon of the L2PcInstance Class (used when no weapon is equiped).<BR><BR>
  2749. */
  2750. public L2Weapon findFistsWeaponItem(int classId)
  2751. {
  2752. L2Weapon weaponItem = null;
  2753. if ((classId >= 0x00) && (classId <= 0x09))
  2754. {
  2755. //human fighter fists
  2756. L2Item temp = ItemTable.getInstance().getTemplate(246);
  2757. weaponItem = (L2Weapon)temp;
  2758. }
  2759. else if ((classId >= 0x0a) && (classId <= 0x11))
  2760. {
  2761. //human mage fists
  2762. L2Item temp = ItemTable.getInstance().getTemplate(251);
  2763. weaponItem = (L2Weapon)temp;
  2764. }
  2765. else if ((classId >= 0x12) && (classId <= 0x18))
  2766. {
  2767. //elven fighter fists
  2768. L2Item temp = ItemTable.getInstance().getTemplate(244);
  2769. weaponItem = (L2Weapon)temp;
  2770. }
  2771. else if ((classId >= 0x19) && (classId <= 0x1e))
  2772. {
  2773. //elven mage fists
  2774. L2Item temp = ItemTable.getInstance().getTemplate(249);
  2775. weaponItem = (L2Weapon)temp;
  2776. }
  2777. else if ((classId >= 0x1f) && (classId <= 0x25))
  2778. {
  2779. //dark elven fighter fists
  2780. L2Item temp = ItemTable.getInstance().getTemplate(245);
  2781. weaponItem = (L2Weapon)temp;
  2782. }
  2783. else if ((classId >= 0x26) && (classId <= 0x2b))
  2784. {
  2785. //dark elven mage fists
  2786. L2Item temp = ItemTable.getInstance().getTemplate(250);
  2787. weaponItem = (L2Weapon)temp;
  2788. }
  2789. else if ((classId >= 0x2c) && (classId <= 0x30))
  2790. {
  2791. //orc fighter fists
  2792. L2Item temp = ItemTable.getInstance().getTemplate(248);
  2793. weaponItem = (L2Weapon)temp;
  2794. }
  2795. else if ((classId >= 0x31) && (classId <= 0x34))
  2796. {
  2797. //orc mage fists
  2798. L2Item temp = ItemTable.getInstance().getTemplate(252);
  2799. weaponItem = (L2Weapon)temp;
  2800. }
  2801. else if ((classId >= 0x35) && (classId <= 0x39))
  2802. {
  2803. //dwarven fists
  2804. L2Item temp = ItemTable.getInstance().getTemplate(247);
  2805. weaponItem = (L2Weapon)temp;
  2806. }
  2807.  
  2808. return weaponItem;
  2809. }
  2810.  
  2811. /**
  2812. * Give Expertise skill of this level and remove beginner Lucky skill.<BR><BR>
  2813. *
  2814. * <B><U> Actions</U> :</B><BR><BR>
  2815. * <li>Get the Level of the L2PcInstance </li>
  2816. * <li>If L2PcInstance Level is 5, remove beginner Lucky skill </li>
  2817. * <li>Add the Expertise skill corresponding to its Expertise level</li>
  2818. * <li>Update the overloaded status of the L2PcInstance</li><BR><BR>
  2819. *
  2820. * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T give other free skills (SP needed = 0)</B></FONT><BR><BR>
  2821. *
  2822. */
  2823. public void rewardSkills()
  2824. {
  2825. // Get the Level of the L2PcInstance
  2826. int lvl = getLevel();
  2827.  
  2828. // Remove beginner Lucky skill
  2829. if (lvl == 10)
  2830. {
  2831. L2Skill skill = SkillTable.getInstance().getInfo(194, 1);
  2832. skill = removeSkill(skill);
  2833.  
  2834. if (Config.DEBUG && skill != null) _log.fine("removed skill 'Lucky' from "+getName());
  2835. }
  2836.  
  2837. // Calculate the current higher Expertise of the L2PcInstance
  2838. for (int i=0; i < EXPERTISE_LEVELS.length; i++)
  2839. {
  2840. if (lvl >= EXPERTISE_LEVELS[i])
  2841. setExpertiseIndex(i);
  2842. }
  2843.  
  2844. // Add the Expertise skill corresponding to its Expertise level
  2845. if (getExpertiseIndex() > 0)
  2846. {
  2847. L2Skill skill = SkillTable.getInstance().getInfo(239, getExpertiseIndex());
  2848. addSkill(skill, true);
  2849.  
  2850. if (Config.DEBUG) _log.fine("awarded "+getName()+" with new expertise.");
  2851.  
  2852. }
  2853. else
  2854. {
  2855. if (Config.DEBUG) _log.fine("No skills awarded at lvl: "+lvl);
  2856. }
  2857.  
  2858. //Active skill dwarven craft
  2859.  
  2860. if (getSkillLevel(1321) < 1 && getRace() == Race.Dwarf)
  2861. {
  2862. L2Skill skill = SkillTable.getInstance().getInfo(1321,1);
  2863. addSkill(skill, true);
  2864. }
  2865.  
  2866. //Active skill common craft
  2867. if (getSkillLevel(1322) < 1)
  2868. {
  2869. L2Skill skill = SkillTable.getInstance().getInfo(1322,1);
  2870. addSkill(skill, true);
  2871. }
  2872.  
  2873. for(int i = 0; i < COMMON_CRAFT_LEVELS.length; i++)
  2874. {
  2875. if(lvl >= COMMON_CRAFT_LEVELS[i] && getSkillLevel(1320) < (i+1))
  2876. {
  2877. L2Skill skill = SkillTable.getInstance().getInfo(1320, (i+1));
  2878. addSkill(skill, true);
  2879. }
  2880. }
  2881.  
  2882. // Auto-Learn skills if activated
  2883. if (Config.AUTO_LEARN_SKILLS)
  2884. {
  2885. giveAvailableSkills();
  2886. }
  2887. checkItemRestriction();
  2888. sendSkillList();
  2889. }
  2890.  
  2891. /**
  2892. * Regive all skills which aren't saved to database, like Noble, Hero, Clan Skills<BR><BR>
  2893. *
  2894. */
  2895. public void regiveTemporarySkills()
  2896. {
  2897. // Do not call this on enterworld or char load
  2898.  
  2899. // Add noble skills if noble
  2900. if (isNoble())
  2901. setNoble(true);
  2902.  
  2903. // Add Hero skills if hero
  2904. if (isHero())
  2905. setHero(true);
  2906.  
  2907. // Add clan skills
  2908. if (getClan() != null)
  2909. {
  2910. L2Clan clan = getClan();
  2911. if (clan.getReputationScore() >= 0)
  2912. {
  2913. L2Skill[] skills = getClan().getAllSkills();
  2914. for (L2Skill sk : skills)
  2915. {
  2916. if(sk.getMinPledgeClass() <= getPledgeClass())
  2917. addSkill(sk, false);
  2918. }
  2919. }
  2920. if (clan.getLevel() >= SiegeManager.getInstance().getSiegeClanMinLevel() && isClanLeader())
  2921. SiegeManager.getInstance().addSiegeSkills(this);
  2922. if (getClan().getHasCastle() > 0)
  2923. CastleManager.getInstance().getCastleByOwner(getClan()).giveResidentialSkills(this);
  2924. if (getClan().getHasFort() > 0)
  2925. FortManager.getInstance().getFortByOwner(getClan()).giveResidentialSkills(this);
  2926. }
  2927.  
  2928. // Reload passive skills from armors / jewels / weapons
  2929. getInventory().reloadEquippedItems();
  2930.  
  2931. // Add Death Penalty Buff Level
  2932. restoreDeathPenaltyBuffLevel();
  2933. }
  2934.  
  2935. /**
  2936. * Give all available skills to the player.<br><br>
  2937. *
  2938. */
  2939. private void giveAvailableSkills()
  2940. {
  2941. int unLearnable = 0;
  2942. int skillCounter = 0;
  2943.  
  2944. // Get available skills
  2945. L2SkillLearn[] skills = SkillTreeTable.getInstance().getAvailableSkills(this, getClassId());
  2946. while (skills.length > unLearnable)
  2947. {
  2948. for (L2SkillLearn s: skills)
  2949. {
  2950. L2Skill sk = SkillTable.getInstance().getInfo(s.getId(), s.getLevel());
  2951. if (sk == null || (sk.getId() == L2Skill.SKILL_DIVINE_INSPIRATION && !Config.AUTO_LEARN_DIVINE_INSPIRATION))
  2952. {
  2953. unLearnable++;
  2954. continue;
  2955. }
  2956.  
  2957. if (getSkillLevel(sk.getId()) == -1)
  2958. skillCounter++;
  2959.  
  2960. // fix when learning toggle skills
  2961. if (sk.isToggle())
  2962. {
  2963. L2Effect toggleEffect = getFirstEffect(sk.getId());
  2964. if (toggleEffect != null)
  2965. {
  2966. // stop old toggle skill effect, and give new toggle skill effect back
  2967. toggleEffect.exit();
  2968. sk.getEffects(this, this);
  2969. }
  2970. }
  2971.  
  2972. addSkill(sk, true);
  2973. }
  2974.  
  2975. // Get new available skills
  2976. skills = SkillTreeTable.getInstance().getAvailableSkills(this, getClassId());
  2977. }
  2978.  
  2979. sendMessage("You have learned " + skillCounter + " new skills.");
  2980. }
  2981.  
  2982. /** Set the Experience value of the L2PcInstance. */
  2983. public void setExp(long exp)
  2984. {
  2985. if (exp < 0)
  2986. exp = 0;
  2987.  
  2988. getStat().setExp(exp);
  2989. }
  2990.  
  2991. /**
  2992. * Return the Race object of the L2PcInstance.<BR><BR>
  2993. */
  2994. public Race getRace()
  2995. {
  2996. if (!isSubClassActive())
  2997. return getTemplate().race;
  2998.  
  2999. L2PcTemplate charTemp = CharTemplateTable.getInstance().getTemplate(_baseClass);
  3000. return charTemp.race;
  3001. }
  3002.  
  3003. public L2Radar getRadar()
  3004. {
  3005. return _radar;
  3006. }
  3007.  
  3008. /** Return the SP amount of the L2PcInstance. */
  3009. public int getSp() { return getStat().getSp(); }
  3010.  
  3011. /** Set the SP amount of the L2PcInstance. */
  3012. public void setSp(int sp)
  3013. {
  3014. if (sp < 0)
  3015. sp = 0;
  3016.  
  3017. super.getStat().setSp(sp);
  3018. }
  3019.  
  3020. /**
  3021. * Return true if this L2PcInstance is a clan leader in
  3022. * ownership of the passed castle
  3023. */
  3024. public boolean isCastleLord(int castleId)
  3025. {
  3026. L2Clan clan = getClan();
  3027.  
  3028. // player has clan and is the clan leader, check the castle info
  3029. if ((clan != null) && (clan.getLeader().getPlayerInstance() == this))
  3030. {
  3031. // if the clan has a castle and it is actually the queried castle, return true
  3032. Castle castle = CastleManager.getInstance().getCastleByOwner(clan);
  3033. if ((castle != null) && (castle == CastleManager.getInstance().getCastleById(castleId)))
  3034. return true;
  3035. }
  3036.  
  3037. return false;
  3038. }
  3039. /**
  3040. * Return the Clan Identifier of the L2PcInstance.<BR><BR>
  3041. */
  3042. public int getClanId()
  3043. {
  3044. return _clanId;
  3045. }
  3046.  
  3047. /**
  3048. * Return the Clan Crest Identifier of the L2PcInstance or 0.<BR><BR>
  3049. */
  3050. public int getClanCrestId()
  3051. {
  3052. if (_clan != null && _clan.hasCrest())
  3053. return _clan.getCrestId();
  3054.  
  3055. return 0;
  3056. }
  3057.  
  3058. /**
  3059. * @return The Clan CrestLarge Identifier or 0
  3060. */
  3061. public int getClanCrestLargeId()
  3062. {
  3063. if (_clan != null && _clan.hasCrestLarge())
  3064. return _clan.getCrestLargeId();
  3065.  
  3066. return 0;
  3067. }
  3068.  
  3069. public long getClanJoinExpiryTime()
  3070. {
  3071. return _clanJoinExpiryTime;
  3072. }
  3073.  
  3074. public void setClanJoinExpiryTime(long time)
  3075. {
  3076. _clanJoinExpiryTime = time;
  3077. }
  3078.  
  3079. public long getClanCreateExpiryTime()
  3080. {
  3081. return _clanCreateExpiryTime;
  3082. }
  3083.  
  3084. public void setClanCreateExpiryTime(long time)
  3085. {
  3086. _clanCreateExpiryTime = time;
  3087. }
  3088.  
  3089. public void setOnlineTime(long time)
  3090. {
  3091. _onlineTime = time;
  3092. _onlineBeginTime = System.currentTimeMillis();
  3093. }
  3094.  
  3095. /**
  3096. * Return the PcInventory Inventory of the L2PcInstance contained in _inventory.<BR><BR>
  3097. */
  3098. @Override
  3099. public PcInventory getInventory()
  3100. {
  3101. return _inventory;
  3102. }
  3103.  
  3104. /**
  3105. * Delete a ShortCut of the L2PcInstance _shortCuts.<BR><BR>
  3106. */
  3107. public void removeItemFromShortCut(int objectId)
  3108. {
  3109. _shortCuts.deleteShortCutByObjectId(objectId);
  3110. }
  3111.  
  3112. /**
  3113. * Return True if the L2PcInstance is sitting.<BR><BR>
  3114. */
  3115. public boolean isSitting()
  3116. {
  3117. return _waitTypeSitting;
  3118. }
  3119.  
  3120. /**
  3121. * Set _waitTypeSitting to given value
  3122. */
  3123. public void setIsSitting(boolean state)
  3124. {
  3125. _waitTypeSitting = state;
  3126. }
  3127. /**
  3128. * Sit down the L2PcInstance, set the AI Intention to AI_INTENTION_REST and send a Server->Client ChangeWaitType packet (broadcast)<BR><BR>
  3129. */
  3130. public void sitDown()
  3131. {
  3132. if ((isCastingNow() || isCastingSimultaneouslyNow()) && !_relax)
  3133. {
  3134. sendMessage("Cannot sit while casting");
  3135. return;
  3136. }
  3137.  
  3138. if (!_waitTypeSitting && !isAttackingDisabled() && !isOutOfControl() && !isImmobilized())
  3139. {
  3140. breakAttack();
  3141. setIsSitting(true);
  3142. broadcastPacket(new ChangeWaitType (this, ChangeWaitType.WT_SITTING));
  3143. // Schedule a sit down task to wait for the animation to finish
  3144. ThreadPoolManager.getInstance().scheduleGeneral(new SitDownTask(this), 2500);
  3145. setIsParalyzed(true);
  3146. }
  3147. }
  3148. /**
  3149. * Sit down Task
  3150. */
  3151. class SitDownTask implements Runnable
  3152. {
  3153. L2PcInstance _player;
  3154. SitDownTask(L2PcInstance player)
  3155. {
  3156. _player = player;
  3157. }
  3158. public void run()
  3159. {
  3160. _player.setIsParalyzed(false);
  3161. _player.getAI().setIntention(CtrlIntention.AI_INTENTION_REST);
  3162. }
  3163. }
  3164. /**
  3165. * Stand up Task
  3166. */
  3167. class StandUpTask implements Runnable
  3168. {
  3169. L2PcInstance _player;
  3170. StandUpTask(L2PcInstance player)
  3171. {
  3172. _player = player;
  3173. }
  3174. public void run()
  3175. {
  3176. _player.setIsSitting(false);
  3177. _player.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  3178. }
  3179. }
  3180. /**
  3181. * Stand up the L2PcInstance, set the AI Intention to AI_INTENTION_IDLE and send a Server->Client ChangeWaitType packet (broadcast)<BR><BR>
  3182. */
  3183. public void standUp()
  3184. {
  3185. if (L2Event.active && eventSitForced)
  3186. {
  3187. sendMessage("A dark force beyond your mortal understanding makes your knees to shake when you try to stand up ...");
  3188. }
  3189. else if (_waitTypeSitting && !isInStoreMode() && !isAlikeDead())
  3190. {
  3191. if (_relax)
  3192. {
  3193. setRelax(false);
  3194. stopEffects(L2EffectType.RELAXING);
  3195. }
  3196.  
  3197. broadcastPacket(new ChangeWaitType (this, ChangeWaitType.WT_STANDING));
  3198. // Schedule a stand up task to wait for the animation to finish
  3199. ThreadPoolManager.getInstance().scheduleGeneral(new StandUpTask(this), 2500);
  3200. }
  3201. }
  3202.  
  3203. /**
  3204. * Set the value of the _relax value. Must be True if using skill Relax and False if not.
  3205. */
  3206. public void setRelax(boolean val)
  3207. {
  3208. _relax = val;
  3209. }
  3210.  
  3211. /**
  3212. * Return the PcWarehouse object of the L2PcInstance.<BR><BR>
  3213. */
  3214. public PcWarehouse getWarehouse()
  3215. {
  3216. if (_warehouse == null)
  3217. {
  3218. _warehouse = new PcWarehouse(this);
  3219. _warehouse.restore();
  3220. }
  3221. if (Config.WAREHOUSE_CACHE)
  3222. WarehouseCacheManager.getInstance().addCacheTask(this);
  3223. return _warehouse;
  3224. }
  3225.  
  3226. /**
  3227. * Free memory used by Warehouse
  3228. */
  3229. public void clearWarehouse()
  3230. {
  3231. if (_warehouse != null)
  3232. _warehouse.deleteMe();
  3233. _warehouse = null;
  3234. }
  3235.  
  3236. /**
  3237. * Return the PcFreight object of the L2PcInstance.<BR><BR>
  3238. */
  3239. public PcFreight getFreight()
  3240. {
  3241. if (_freight == null)
  3242. {
  3243. _freight = new PcFreight(this);
  3244. _freight.restore();
  3245. }
  3246. return _freight;
  3247. }
  3248.  
  3249. /**
  3250. * Free memory used by Freight
  3251. */
  3252. public void clearFreight()
  3253. {
  3254. if (_freight != null)
  3255. _freight.deleteMe();
  3256. _freight = null;
  3257. }
  3258.  
  3259. /**
  3260. * Return deposited PcFreight object for the objectId
  3261. * or create new if not exist
  3262. */
  3263. public PcFreight getDepositedFreight(int objectId)
  3264. {
  3265. if (_depositedFreight == null)
  3266. _depositedFreight = new FastList<PcFreight>();
  3267. else
  3268. {
  3269. for (PcFreight freight : _depositedFreight)
  3270. {
  3271. if (freight != null && freight.getOwnerId() == objectId)
  3272. return freight;
  3273. }
  3274. }
  3275.  
  3276. PcFreight freight = new PcFreight(null);
  3277. freight.doQuickRestore(objectId);
  3278. _depositedFreight.add(freight);
  3279. return freight;
  3280. }
  3281.  
  3282. /**
  3283. * Clear memory used by deposited freight
  3284. */
  3285. public void clearDepositedFreight()
  3286. {
  3287. if (_depositedFreight == null)
  3288. return;
  3289.  
  3290. for (PcFreight freight : _depositedFreight)
  3291. {
  3292. if (freight != null)
  3293. {
  3294. try
  3295. {
  3296. freight.deleteMe();
  3297. }
  3298. catch (Exception e)
  3299. {
  3300. _log.log(Level.SEVERE, "clearDepositedFreight()", e);
  3301. }
  3302. }
  3303. }
  3304. _depositedFreight.clear();
  3305. _depositedFreight = null;
  3306. }
  3307.  
  3308. /**
  3309. * Return the Identifier of the L2PcInstance.<BR><BR>
  3310. */
  3311. public int getCharId()
  3312. {
  3313. return _charId;
  3314. }
  3315.  
  3316. /**
  3317. * Set the Identifier of the L2PcInstance.<BR><BR>
  3318. */
  3319. public void setCharId(int charId)
  3320. {
  3321. _charId = charId;
  3322. }
  3323.  
  3324. /**
  3325. * Return the Adena amount of the L2PcInstance.<BR><BR>
  3326. */
  3327. public long getAdena()
  3328. {
  3329. return _inventory.getAdena();
  3330. }
  3331.  
  3332. /**
  3333. * Return the Ancient Adena amount of the L2PcInstance.<BR><BR>
  3334. */
  3335. public long getAncientAdena()
  3336. {
  3337. return _inventory.getAncientAdena();
  3338. }
  3339.  
  3340. /**
  3341. * Add adena to Inventory of the L2PcInstance and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3342. * @param process : String Identifier of process triggering this action
  3343. * @param count : int Quantity of adena to be added
  3344. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3345. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3346. */
  3347. public void addAdena(String process, long count, L2Object reference, boolean sendMessage)
  3348. {
  3349. if (sendMessage)
  3350. {
  3351. SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_ADENA);
  3352. sm.addItemNumber(count);
  3353. sendPacket(sm);
  3354. }
  3355.  
  3356. if (count > 0)
  3357. {
  3358. _inventory.addAdena(process, count, this, reference);
  3359.  
  3360. // Send update packet
  3361. if (!Config.FORCE_INVENTORY_UPDATE)
  3362. {
  3363. InventoryUpdate iu = new InventoryUpdate();
  3364. iu.addItem(_inventory.getAdenaInstance());
  3365. sendPacket(iu);
  3366. }
  3367. else sendPacket(new ItemList(this, false));
  3368. }
  3369. }
  3370.  
  3371. /**
  3372. * Reduce adena in Inventory of the L2PcInstance and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3373. * @param process : String Identifier of process triggering this action
  3374. * @param count : long Quantity of adena to be reduced
  3375. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3376. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3377. * @return boolean informing if the action was successfull
  3378. */
  3379. public boolean reduceAdena(String process, long count, L2Object reference, boolean sendMessage)
  3380. {
  3381. if (count > getAdena())
  3382. {
  3383. if (sendMessage) sendPacket(new SystemMessage(SystemMessageId.YOU_NOT_ENOUGH_ADENA));
  3384. return false;
  3385. }
  3386.  
  3387. if (count > 0)
  3388. {
  3389. L2ItemInstance adenaItem = _inventory.getAdenaInstance();
  3390. _inventory.reduceAdena(process, count, this, reference);
  3391.  
  3392. // Send update packet
  3393. if (!Config.FORCE_INVENTORY_UPDATE)
  3394. {
  3395. InventoryUpdate iu = new InventoryUpdate();
  3396. iu.addItem(adenaItem);
  3397. sendPacket(iu);
  3398. }
  3399. else sendPacket(new ItemList(this, false));
  3400.  
  3401. if (sendMessage)
  3402. {
  3403. SystemMessage sm = new SystemMessage(SystemMessageId.DISAPPEARED_ADENA);
  3404. sm.addItemNumber(count);
  3405. sendPacket(sm);
  3406. }
  3407. }
  3408.  
  3409. return true;
  3410. }
  3411.  
  3412. /**
  3413. * Add ancient adena to Inventory of the L2PcInstance and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3414. *
  3415. * @param process : String Identifier of process triggering this action
  3416. * @param count : int Quantity of ancient adena to be added
  3417. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3418. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3419. */
  3420. public void addAncientAdena(String process, long count, L2Object reference, boolean sendMessage)
  3421. {
  3422. if (sendMessage)
  3423. {
  3424. SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S);
  3425. sm.addItemName(PcInventory.ANCIENT_ADENA_ID);
  3426. sm.addItemNumber(count);
  3427. sendPacket(sm);
  3428. }
  3429.  
  3430. if (count > 0)
  3431. {
  3432. _inventory.addAncientAdena(process, count, this, reference);
  3433.  
  3434. if (!Config.FORCE_INVENTORY_UPDATE)
  3435. {
  3436. InventoryUpdate iu = new InventoryUpdate();
  3437. iu.addItem(_inventory.getAncientAdenaInstance());
  3438. sendPacket(iu);
  3439. }
  3440. else sendPacket(new ItemList(this, false));
  3441. }
  3442. }
  3443.  
  3444. /**
  3445. * Reduce ancient adena in Inventory of the L2PcInstance and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3446. * @param process : String Identifier of process triggering this action
  3447. * @param count : long Quantity of ancient adena to be reduced
  3448. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3449. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3450. * @return boolean informing if the action was successfull
  3451. */
  3452. public boolean reduceAncientAdena(String process, long count, L2Object reference, boolean sendMessage)
  3453. {
  3454. if (count > getAncientAdena())
  3455. {
  3456. if (sendMessage)
  3457. sendPacket(new SystemMessage(SystemMessageId.YOU_NOT_ENOUGH_ADENA));
  3458.  
  3459. return false;
  3460. }
  3461.  
  3462. if (count > 0)
  3463. {
  3464. L2ItemInstance ancientAdenaItem = _inventory.getAncientAdenaInstance();
  3465. _inventory.reduceAncientAdena(process, count, this, reference);
  3466.  
  3467. if (!Config.FORCE_INVENTORY_UPDATE)
  3468. {
  3469. InventoryUpdate iu = new InventoryUpdate();
  3470. iu.addItem(ancientAdenaItem);
  3471. sendPacket(iu);
  3472. }
  3473. else
  3474. {
  3475. sendPacket(new ItemList(this, false));
  3476. }
  3477.  
  3478. if (sendMessage)
  3479. {
  3480. SystemMessage sm = new SystemMessage(SystemMessageId.S2_S1_DISAPPEARED);
  3481. sm.addItemName(PcInventory.ANCIENT_ADENA_ID);
  3482. sm.addItemNumber(count);
  3483. sendPacket(sm);
  3484. }
  3485. }
  3486.  
  3487. return true;
  3488. }
  3489.  
  3490. /**
  3491. * Adds item to inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3492. * @param process : String Identifier of process triggering this action
  3493. * @param item : L2ItemInstance to be added
  3494. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3495. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3496. */
  3497. public void addItem(String process, L2ItemInstance item, L2Object reference, boolean sendMessage)
  3498. {
  3499. if (item.getCount() > 0)
  3500. {
  3501. // Sends message to client if requested
  3502. if (sendMessage)
  3503. {
  3504. if (item.getCount() > 1)
  3505. {
  3506. SystemMessage sm = new SystemMessage(SystemMessageId.YOU_PICKED_UP_S1_S2);
  3507. sm.addItemName(item);
  3508. sm.addItemNumber(item.getCount());
  3509. sendPacket(sm);
  3510. }
  3511. else if (item.getEnchantLevel() > 0)
  3512. {
  3513. SystemMessage sm = new SystemMessage(SystemMessageId.YOU_PICKED_UP_A_S1_S2);
  3514. sm.addNumber(item.getEnchantLevel());
  3515. sm.addItemName(item);
  3516. sendPacket(sm);
  3517. }
  3518. else
  3519. {
  3520. SystemMessage sm = new SystemMessage(SystemMessageId.YOU_PICKED_UP_S1);
  3521. sm.addItemName(item);
  3522. sendPacket(sm);
  3523. }
  3524. }
  3525.  
  3526. // Add the item to inventory
  3527. L2ItemInstance newitem = _inventory.addItem(process, item, this, reference);
  3528.  
  3529. // Send inventory update packet
  3530. if (!Config.FORCE_INVENTORY_UPDATE)
  3531. {
  3532. InventoryUpdate playerIU = new InventoryUpdate();
  3533. playerIU.addItem(newitem);
  3534. sendPacket(playerIU);
  3535. }
  3536. else
  3537. {
  3538. sendPacket(new ItemList(this, false));
  3539. }
  3540.  
  3541. // Update current load as well
  3542. StatusUpdate su = new StatusUpdate(getObjectId());
  3543. su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  3544. sendPacket(su);
  3545.  
  3546. // If over capacity, drop the item
  3547. if (!isGM() && !_inventory.validateCapacity(0) && newitem.isDropable())
  3548. dropItem("InvDrop", newitem, null, true);
  3549.  
  3550. // Cursed Weapon
  3551. else if(CursedWeaponsManager.getInstance().isCursed(newitem.getItemId()))
  3552. {
  3553. CursedWeaponsManager.getInstance().activate(this, newitem);
  3554. }
  3555.  
  3556. // Combat Flag
  3557. else if(FortSiegeManager.getInstance().isCombat(item.getItemId()))
  3558. {
  3559. if(FortSiegeManager.getInstance().activateCombatFlag(this, item))
  3560. {
  3561. Fort fort = FortManager.getInstance().getFort(this);
  3562. fort.getSiege().announceToPlayer(new SystemMessage(SystemMessageId.C1_ACQUIRED_THE_FLAG), this.getName());
  3563. }
  3564. }
  3565. }
  3566. }
  3567.  
  3568. /**
  3569. * Adds item to Inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3570. * @param process : String Identifier of process triggering this action
  3571. * @param itemId : int Item Identifier of the item to be added
  3572. * @param count : long Quantity of items to be added
  3573. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3574. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3575. */
  3576. public void addItem(String process, int itemId, long count, L2Object reference, boolean sendMessage)
  3577. {
  3578. if (count > 0)
  3579. {
  3580. L2ItemInstance item = null;
  3581. if(ItemTable.getInstance().getTemplate(itemId) != null)
  3582. {
  3583. item = ItemTable.getInstance().createDummyItem(itemId);
  3584. }
  3585. else
  3586. {
  3587. _log.log(Level.SEVERE, "Item doesn't exist so cannot be added. Item ID: " + itemId);
  3588. return;
  3589. }
  3590. // Sends message to client if requested
  3591. if (sendMessage && ((!isCastingNow() && item.getItemType() == L2EtcItemType.HERB)
  3592. || item.getItemType() != L2EtcItemType.HERB))
  3593. {
  3594. if (count > 1)
  3595. {
  3596. if (process.equalsIgnoreCase("sweep") || process.equalsIgnoreCase("Quest"))
  3597. {
  3598. SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S);
  3599. sm.addItemName(itemId);
  3600. sm.addItemNumber(count);
  3601. sendPacket(sm);
  3602. }
  3603. else
  3604. {
  3605. SystemMessage sm = new SystemMessage(SystemMessageId.YOU_PICKED_UP_S1_S2);
  3606. sm.addItemName(itemId);
  3607. sm.addItemNumber(count);
  3608. sendPacket(sm);
  3609. }
  3610. }
  3611. else
  3612. {
  3613. if (process.equalsIgnoreCase("sweep") || process.equalsIgnoreCase("Quest"))
  3614. {
  3615. SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_ITEM);
  3616. sm.addItemName(itemId);
  3617. sendPacket(sm);
  3618. }
  3619. else
  3620. {
  3621. SystemMessage sm = new SystemMessage(SystemMessageId.YOU_PICKED_UP_S1);
  3622. sm.addItemName(itemId);
  3623. sendPacket(sm);
  3624. }
  3625. }
  3626. }
  3627. //Auto use herbs - autoloot
  3628. if (item.getItemType() == L2EtcItemType.HERB) //If item is herb dont add it to iv :]
  3629. {
  3630. if(!isCastingNow())
  3631. {
  3632. L2ItemInstance herb = new L2ItemInstance(_charId, itemId);
  3633. IItemHandler handler = ItemHandler.getInstance().getItemHandler(herb.getEtcItem());
  3634. if (handler == null)
  3635. _log.warning("No item handler registered for Herb - item ID " + herb.getItemId() + ".");
  3636. else
  3637. {
  3638. handler.useItem(this, herb);
  3639. if(_herbstask>=100)
  3640. _herbstask -=100;
  3641. }
  3642. }
  3643. else
  3644. {
  3645. _herbstask += 100;
  3646. ThreadPoolManager.getInstance().scheduleAi(new HerbTask(process, itemId, count, reference, sendMessage), _herbstask);
  3647. }
  3648. }
  3649. else
  3650. {
  3651. // Add the item to inventory
  3652. L2ItemInstance createdItem = _inventory.addItem(process, itemId, count, this, reference);
  3653.  
  3654. // If over capacity, drop the item
  3655. if (!isGM() && !_inventory.validateCapacity(0) && createdItem.isDropable())
  3656. dropItem("InvDrop", createdItem, null, true);
  3657.  
  3658. // Cursed Weapon
  3659. else if(CursedWeaponsManager.getInstance().isCursed(createdItem.getItemId()))
  3660. CursedWeaponsManager.getInstance().activate(this, createdItem);
  3661.  
  3662. // Combat Flag
  3663. else if(FortSiegeManager.getInstance().isCombat(createdItem.getItemId()))
  3664. {
  3665. if( FortSiegeManager.getInstance().activateCombatFlag(this, item))
  3666. {
  3667. Fort fort = FortManager.getInstance().getFort(this);
  3668. fort.getSiege().announceToPlayer(new SystemMessage(SystemMessageId.C1_ACQUIRED_THE_FLAG), this.getName());
  3669. }
  3670. }
  3671. }
  3672. }
  3673. }
  3674.  
  3675. /**
  3676. * Destroy item from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3677. * @param process : String Identifier of process triggering this action
  3678. * @param item : L2ItemInstance to be destroyed
  3679. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3680. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3681. * @return boolean informing if the action was successfull
  3682. */
  3683. public boolean destroyItem(String process, L2ItemInstance item, L2Object reference, boolean sendMessage)
  3684. {
  3685. return this.destroyItem(process, item, item.getCount(), reference, sendMessage);
  3686. }
  3687.  
  3688. /**
  3689. * Destroy item from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3690. * @param process : String Identifier of process triggering this action
  3691. * @param item : L2ItemInstance to be destroyed
  3692. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3693. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3694. * @return boolean informing if the action was successfull
  3695. */
  3696. public boolean destroyItem(String process, L2ItemInstance item, long count, L2Object reference, boolean sendMessage)
  3697. {
  3698. item = _inventory.destroyItem(process, item, count, this, reference);
  3699.  
  3700. if (item == null)
  3701. {
  3702. if (sendMessage)
  3703. {
  3704. sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
  3705. }
  3706. return false;
  3707. }
  3708.  
  3709. // Send inventory update packet
  3710. if (!Config.FORCE_INVENTORY_UPDATE)
  3711. {
  3712. InventoryUpdate playerIU = new InventoryUpdate();
  3713. playerIU.addItem(item);
  3714. sendPacket(playerIU);
  3715. }
  3716. else
  3717. {
  3718. sendPacket(new ItemList(this, false));
  3719. }
  3720.  
  3721. // Update current load as well
  3722. StatusUpdate su = new StatusUpdate(getObjectId());
  3723. su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  3724. sendPacket(su);
  3725.  
  3726. // Sends message to client if requested
  3727. if (sendMessage)
  3728. {
  3729. SystemMessage sm = new SystemMessage(SystemMessageId.S2_S1_DISAPPEARED);
  3730. sm.addItemName(item);
  3731. sm.addItemNumber(count);
  3732. sendPacket(sm);
  3733. }
  3734.  
  3735. return true;
  3736. }
  3737.  
  3738. /**
  3739. * Destroys item from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3740. * @param process : String Identifier of process triggering this action
  3741. * @param objectId : int Item Instance identifier of the item to be destroyed
  3742. * @param count : int Quantity of items to be destroyed
  3743. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3744. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3745. * @return boolean informing if the action was successfull
  3746. */
  3747. @Override
  3748. public boolean destroyItem(String process, int objectId, long count, L2Object reference, boolean sendMessage)
  3749. {
  3750. L2ItemInstance item = _inventory.getItemByObjectId(objectId);
  3751.  
  3752. if (item == null)
  3753. {
  3754. if (sendMessage)
  3755. {
  3756. sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
  3757. }
  3758.  
  3759. return false;
  3760. }
  3761. return this.destroyItem(process, item, count, reference, sendMessage);
  3762. }
  3763.  
  3764. /**
  3765. * Destroys shots from inventory without logging and only occasional saving to database.
  3766. * Sends a Server->Client InventoryUpdate packet to the L2PcInstance.
  3767. * @param process : String Identifier of process triggering this action
  3768. * @param objectId : int Item Instance identifier of the item to be destroyed
  3769. * @param count : int Quantity of items to be destroyed
  3770. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3771. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3772. * @return boolean informing if the action was successfull
  3773. */
  3774. public boolean destroyItemWithoutTrace(String process, int objectId, long count, L2Object reference, boolean sendMessage)
  3775. {
  3776. L2ItemInstance item = _inventory.getItemByObjectId(objectId);
  3777.  
  3778. if (item == null || item.getCount() < count)
  3779. {
  3780. if (sendMessage)
  3781. {
  3782. sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
  3783. }
  3784.  
  3785. return false;
  3786. }
  3787.  
  3788. return this.destroyItem(null, item, count, reference, sendMessage);
  3789. }
  3790.  
  3791. /**
  3792. * Destroy item from inventory by using its <B>itemId</B> and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3793. * @param process : String Identifier of process triggering this action
  3794. * @param itemId : int Item identifier of the item to be destroyed
  3795. * @param count : int Quantity of items to be destroyed
  3796. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3797. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3798. * @return boolean informing if the action was successfull
  3799. */
  3800. @Override
  3801. public boolean destroyItemByItemId(String process, int itemId, long count, L2Object reference, boolean sendMessage)
  3802. {
  3803. L2ItemInstance item = _inventory.getItemByItemId(itemId);
  3804.  
  3805. if (item == null || item.getCount() < count || _inventory.destroyItemByItemId(process, itemId, count, this, reference) == null)
  3806. {
  3807. if (sendMessage)
  3808. sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
  3809.  
  3810. return false;
  3811. }
  3812.  
  3813. // Send inventory update packet
  3814. if (!Config.FORCE_INVENTORY_UPDATE)
  3815. {
  3816. InventoryUpdate playerIU = new InventoryUpdate();
  3817. playerIU.addItem(item);
  3818. sendPacket(playerIU);
  3819. }
  3820. else sendPacket(new ItemList(this, false));
  3821.  
  3822. // Update current load as well
  3823. StatusUpdate su = new StatusUpdate(getObjectId());
  3824. su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  3825. sendPacket(su);
  3826.  
  3827. // Sends message to client if requested
  3828. if (sendMessage)
  3829. {
  3830. SystemMessage sm = new SystemMessage(SystemMessageId.S2_S1_DISAPPEARED);
  3831. sm.addItemName(itemId);
  3832. sm.addItemNumber(count);
  3833. sendPacket(sm);
  3834. }
  3835.  
  3836. return true;
  3837. }
  3838.  
  3839. /**
  3840. * Destroy all weared items from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3841. * @param process : String Identifier of process triggering this action
  3842. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3843. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3844. * @return boolean informing if the action was successfull
  3845. */
  3846. public void destroyWearedItems(String process, L2Object reference, boolean sendMessage)
  3847. {
  3848.  
  3849. // Go through all Items of the inventory
  3850. for (L2ItemInstance item : getInventory().getItems())
  3851. {
  3852. // Check if the item is a Try On item in order to remove it
  3853. if (item.isWear())
  3854. {
  3855. if (item.isEquipped())
  3856. getInventory().unEquipItemInSlotAndRecord(item.getLocationSlot());
  3857.  
  3858. if (_inventory.destroyItem(process, item, this, reference) == null)
  3859. {
  3860. _log.warning("Player " + getName() + " can't destroy weared item: " + item.getName() + "[ " + item.getObjectId() + " ]");
  3861. continue;
  3862. }
  3863.  
  3864. // Send an Unequipped Message in system window of the player for each Item
  3865. SystemMessage sm = new SystemMessage(SystemMessageId.S1_DISARMED);
  3866. sm.addItemName(item);
  3867. sendPacket(sm);
  3868.  
  3869. }
  3870. }
  3871.  
  3872.  
  3873. // Send the StatusUpdate Server->Client Packet to the player with new CUR_LOAD (0x0e) information
  3874. StatusUpdate su = new StatusUpdate(getObjectId());
  3875. su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  3876. sendPacket(su);
  3877.  
  3878. // Send the ItemList Server->Client Packet to the player in order to refresh its Inventory
  3879. ItemList il = new ItemList(getInventory().getItems(), true);
  3880. sendPacket(il);
  3881.  
  3882. // Send a Server->Client packet UserInfo to this L2PcInstance and CharInfo to all L2PcInstance in its _KnownPlayers
  3883. broadcastUserInfo();
  3884.  
  3885. // Sends message to client if requested
  3886. sendMessage("Trying-on mode has ended.");
  3887.  
  3888. }
  3889.  
  3890. /**
  3891. * Transfers item to another ItemContainer and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3892. * @param process : String Identifier of process triggering this action
  3893. * @param itemId : int Item Identifier of the item to be transfered
  3894. * @param count : long Quantity of items to be transfered
  3895. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3896. * @return L2ItemInstance corresponding to the new item or the updated item in inventory
  3897. */
  3898. public L2ItemInstance transferItem(String process, int objectId, long count, Inventory target, L2Object reference)
  3899. {
  3900. L2ItemInstance oldItem = checkItemManipulation(objectId, count, "transfer");
  3901. if (oldItem == null) return null;
  3902. L2ItemInstance newItem = getInventory().transferItem(process, objectId, count, target, this, reference);
  3903. if (newItem == null) return null;
  3904.  
  3905. // Send inventory update packet
  3906. if (!Config.FORCE_INVENTORY_UPDATE)
  3907. {
  3908. InventoryUpdate playerIU = new InventoryUpdate();
  3909.  
  3910. if (oldItem.getCount() > 0 && oldItem != newItem)
  3911. playerIU.addModifiedItem(oldItem);
  3912. else
  3913. playerIU.addRemovedItem(oldItem);
  3914.  
  3915. sendPacket(playerIU);
  3916. }
  3917. else sendPacket(new ItemList(this, false));
  3918.  
  3919. // Update current load as well
  3920. StatusUpdate playerSU = new StatusUpdate(getObjectId());
  3921. playerSU.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  3922. sendPacket(playerSU);
  3923.  
  3924. // Send target update packet
  3925. if (target instanceof PcInventory)
  3926. {
  3927. L2PcInstance targetPlayer = ((PcInventory)target).getOwner();
  3928.  
  3929. if (!Config.FORCE_INVENTORY_UPDATE)
  3930. {
  3931. InventoryUpdate playerIU = new InventoryUpdate();
  3932.  
  3933. if (newItem.getCount() > count)
  3934. playerIU.addModifiedItem(newItem);
  3935. else
  3936. playerIU.addNewItem(newItem);
  3937.  
  3938. targetPlayer.sendPacket(playerIU);
  3939. }
  3940. else targetPlayer.sendPacket(new ItemList(targetPlayer, false));
  3941.  
  3942. // Update current load as well
  3943. playerSU = new StatusUpdate(targetPlayer.getObjectId());
  3944. playerSU.addAttribute(StatusUpdate.CUR_LOAD, targetPlayer.getCurrentLoad());
  3945. targetPlayer.sendPacket(playerSU);
  3946. }
  3947. else if (target instanceof PetInventory)
  3948. {
  3949. PetInventoryUpdate petIU = new PetInventoryUpdate();
  3950.  
  3951. if (newItem.getCount() > count)
  3952. petIU.addModifiedItem(newItem);
  3953. else
  3954. petIU.addNewItem(newItem);
  3955.  
  3956. ((PetInventory)target).getOwner().getOwner().sendPacket(petIU);
  3957. getPet().getInventory().refreshWeight();
  3958. }
  3959. return newItem;
  3960. }
  3961.  
  3962. /**
  3963. * Drop item from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  3964. * @param process : String Identifier of process triggering this action
  3965. * @param item : L2ItemInstance to be dropped
  3966. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  3967. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  3968. * @return boolean informing if the action was successfull
  3969. */
  3970. public boolean dropItem(String process, L2ItemInstance item, L2Object reference, boolean sendMessage)
  3971. {
  3972. item = _inventory.dropItem(process, item, this, reference);
  3973.  
  3974. if (item == null)
  3975. {
  3976. if (sendMessage)
  3977. sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
  3978.  
  3979. return false;
  3980. }
  3981.  
  3982. item.dropMe(this, getX() + Rnd.get(50) - 25, getY() + Rnd.get(50) - 25, getZ() + 20);
  3983.  
  3984. if (Config.AUTODESTROY_ITEM_AFTER >0 && Config.DESTROY_DROPPED_PLAYER_ITEM && !Config.LIST_PROTECTED_ITEMS.contains(item.getItemId()))
  3985. {
  3986. if ( (item.isEquipable() && Config.DESTROY_EQUIPABLE_PLAYER_ITEM) || !item.isEquipable())
  3987. ItemsAutoDestroy.getInstance().addItem(item);
  3988. }
  3989. if (Config.DESTROY_DROPPED_PLAYER_ITEM){
  3990. if (!item.isEquipable() || (item.isEquipable() && Config.DESTROY_EQUIPABLE_PLAYER_ITEM ))
  3991. item.setProtected(false);
  3992. else
  3993. item.setProtected(true);
  3994. }
  3995. else
  3996. item.setProtected(true);
  3997.  
  3998. // Send inventory update packet
  3999. if (!Config.FORCE_INVENTORY_UPDATE)
  4000. {
  4001. InventoryUpdate playerIU = new InventoryUpdate();
  4002. playerIU.addItem(item);
  4003. sendPacket(playerIU);
  4004. }
  4005. else sendPacket(new ItemList(this, false));
  4006.  
  4007. // Update current load as well
  4008. StatusUpdate su = new StatusUpdate(getObjectId());
  4009. su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  4010. sendPacket(su);
  4011.  
  4012. // Sends message to client if requested
  4013. if (sendMessage)
  4014. {
  4015. SystemMessage sm = new SystemMessage(SystemMessageId.YOU_DROPPED_S1);
  4016. sm.addItemName(item);
  4017. sendPacket(sm);
  4018. }
  4019.  
  4020. return true;
  4021. }
  4022.  
  4023. /**
  4024. * Drop item from inventory by using its <B>objectID</B> and send a Server->Client InventoryUpdate packet to the L2PcInstance.
  4025. * @param process : String Identifier of process triggering this action
  4026. * @param objectId : int Item Instance identifier of the item to be dropped
  4027. * @param count : long Quantity of items to be dropped
  4028. * @param x : int coordinate for drop X
  4029. * @param y : int coordinate for drop Y
  4030. * @param z : int coordinate for drop Z
  4031. * @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
  4032. * @param sendMessage : boolean Specifies whether to send message to Client about this action
  4033. * @return L2ItemInstance corresponding to the new item or the updated item in inventory
  4034. */
  4035. public L2ItemInstance dropItem(String process, int objectId, long count, int x, int y, int z, L2Object reference, boolean sendMessage)
  4036. {
  4037. L2ItemInstance invitem = _inventory.getItemByObjectId(objectId);
  4038. L2ItemInstance item = _inventory.dropItem(process, objectId, count, this, reference);
  4039.  
  4040. if (item == null)
  4041. {
  4042. if (sendMessage)
  4043. sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
  4044.  
  4045. return null;
  4046. }
  4047.  
  4048. item.dropMe(this, x, y, z);
  4049.  
  4050. if (Config.AUTODESTROY_ITEM_AFTER >0 && Config.DESTROY_DROPPED_PLAYER_ITEM && !Config.LIST_PROTECTED_ITEMS.contains(item.getItemId()))
  4051. {
  4052. if ( (item.isEquipable() && Config.DESTROY_EQUIPABLE_PLAYER_ITEM) || !item.isEquipable())
  4053. ItemsAutoDestroy.getInstance().addItem(item);
  4054. }
  4055. if (Config.DESTROY_DROPPED_PLAYER_ITEM){
  4056. if (!item.isEquipable() || (item.isEquipable() && Config.DESTROY_EQUIPABLE_PLAYER_ITEM ))
  4057. item.setProtected(false);
  4058. else
  4059. item.setProtected(true);
  4060. }
  4061. else
  4062. item.setProtected(true);
  4063.  
  4064. // Send inventory update packet
  4065. if (!Config.FORCE_INVENTORY_UPDATE)
  4066. {
  4067. InventoryUpdate playerIU = new InventoryUpdate();
  4068. playerIU.addItem(invitem);
  4069. sendPacket(playerIU);
  4070. }
  4071. else
  4072. {
  4073. sendPacket(new ItemList(this, false));
  4074. }
  4075.  
  4076. // Update current load as well
  4077. StatusUpdate su = new StatusUpdate(getObjectId());
  4078. su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
  4079. sendPacket(su);
  4080.  
  4081. // Sends message to client if requested
  4082. if (sendMessage)
  4083. {
  4084. SystemMessage sm = new SystemMessage(SystemMessageId.YOU_DROPPED_S1);
  4085. sm.addItemName(item);
  4086. sendPacket(sm);
  4087. }
  4088.  
  4089. return item;
  4090. }
  4091.  
  4092. public L2ItemInstance checkItemManipulation(int objectId, long count, String action)
  4093. {
  4094. //TODO: if we remove objects that are not visisble from the L2World, we'll have to remove this check
  4095. if (L2World.getInstance().findObject(objectId) == null)
  4096. {
  4097. _log.finest(getObjectId()+": player tried to " + action + " item not available in L2World");
  4098. return null;
  4099. }
  4100.  
  4101. L2ItemInstance item = getInventory().getItemByObjectId(objectId);
  4102.  
  4103. if (item == null || item.getOwnerId() != getObjectId())
  4104. {
  4105. _log.finest(getObjectId()+": player tried to " + action + " item he is not owner of");
  4106. return null;
  4107. }
  4108.  
  4109. if (count < 0 || (count > 1 && !item.isStackable()))
  4110. {
  4111. _log.finest(getObjectId()+": player tried to " + action + " item with invalid count: "+ count);
  4112. return null;
  4113. }
  4114.  
  4115. if (count > item.getCount())
  4116. {
  4117. _log.finest(getObjectId()+": player tried to " + action + " more items than he owns");
  4118. return null;
  4119. }
  4120.  
  4121. // Pet is summoned and not the item that summoned the pet AND not the buggle from strider you're mounting
  4122. if (getPet() != null && getPet().getControlItemId() == objectId || getMountObjectID() == objectId)
  4123. {
  4124. if (Config.DEBUG)
  4125. _log.finest(getObjectId()+": player tried to " + action + " item controling pet");
  4126.  
  4127. return null;
  4128. }
  4129.  
  4130. if (getActiveEnchantItem() != null && getActiveEnchantItem().getObjectId() == objectId)
  4131. {
  4132. if (Config.DEBUG)
  4133. _log.finest(getObjectId()+":player tried to " + action + " an enchant scroll he was using");
  4134.  
  4135. return null;
  4136. }
  4137.  
  4138. if (item.isWear())
  4139. {
  4140. // cannot drop/trade wear-items
  4141. return null;
  4142. }
  4143.  
  4144. // We cannot put a Weapon with Augmention in WH while casting (Possible Exploit)
  4145. if (item.isAugmented() && (isCastingNow() || this.isCastingSimultaneouslyNow()))
  4146. return null;
  4147.  
  4148. return item;
  4149. }
  4150.  
  4151. /**
  4152. * Set _protectEndTime according settings.
  4153. */
  4154. public void setProtection(boolean protect)
  4155. {
  4156. if (Config.DEVELOPER && (protect || _protectEndTime > 0))
  4157. _log.warning(getName() + ": Protection " + (protect?"ON " + (GameTimeController.getGameTicks() + Config.PLAYER_SPAWN_PROTECTION * GameTimeController.TICKS_PER_SECOND) :"OFF") + " (currently " + GameTimeController.getGameTicks() + ")");
  4158.  
  4159. _protectEndTime = protect ? GameTimeController.getGameTicks() + Config.PLAYER_SPAWN_PROTECTION * GameTimeController.TICKS_PER_SECOND : 0;
  4160. }
  4161.  
  4162. /**
  4163. * Set protection from agro mobs when getting up from fake death, according settings.
  4164. */
  4165. public void setRecentFakeDeath(boolean protect)
  4166. {
  4167. _recentFakeDeathEndTime = protect ? GameTimeController.getGameTicks() + Config.PLAYER_FAKEDEATH_UP_PROTECTION * GameTimeController.TICKS_PER_SECOND : 0;
  4168. }
  4169.  
  4170. public boolean isRecentFakeDeath()
  4171. {
  4172. return _recentFakeDeathEndTime > GameTimeController.getGameTicks();
  4173. }
  4174.  
  4175. public final boolean isFakeDeath()
  4176. {
  4177. return _isFakeDeath;
  4178. }
  4179.  
  4180. public final void setIsFakeDeath(boolean value)
  4181. {
  4182. _isFakeDeath = value;
  4183. }
  4184.  
  4185. @Override
  4186. public final boolean isAlikeDead()
  4187. {
  4188. if (super.isAlikeDead())
  4189. return true;
  4190.  
  4191. return isFakeDeath();
  4192. }
  4193.  
  4194. /**
  4195. * Get the client owner of this char.<BR><BR>
  4196. */
  4197. public L2GameClient getClient()
  4198. {
  4199. return _client;
  4200. }
  4201.  
  4202. public void setClient(L2GameClient client)
  4203. {
  4204. _client = client;
  4205. }
  4206.  
  4207. /**
  4208. * Close the active connection with the client.<BR><BR>
  4209. */
  4210. public void closeNetConnection()
  4211. {
  4212. L2GameClient client = _client;
  4213. if (client != null)
  4214. {
  4215. if (client.isDetached())
  4216. {
  4217. client.cleanMe(true);
  4218. }
  4219. else
  4220. {
  4221. if (!client.getConnection().isClosed())
  4222. {
  4223. client.close(new LeaveWorld());
  4224. }
  4225. }
  4226. }
  4227. }
  4228.  
  4229. public Point3D getCurrentSkillWorldPosition()
  4230. {
  4231. return _currentSkillWorldPosition;
  4232. }
  4233.  
  4234. public void setCurrentSkillWorldPosition(Point3D worldPosition)
  4235. {
  4236. _currentSkillWorldPosition = worldPosition;
  4237. }
  4238.  
  4239. /**
  4240. *
  4241. * @see net.sf.l2j.gameserver.model.actor.L2Character#doAttack(net.sf.l2j.gameserver.model.actor.L2Character)
  4242. */
  4243. @Override
  4244. protected void doAttack(L2Character target)
  4245. {
  4246. if (getAppearance().getInvisible())
  4247. {
  4248. L2Effect eInvisible = getFirstEffect(L2EffectType.HIDE);
  4249. if (eInvisible != null)
  4250. eInvisible.exit();
  4251. }
  4252.  
  4253. super.doAttack(target);
  4254. }
  4255.  
  4256. /**
  4257. *
  4258. * @see net.sf.l2j.gameserver.model.actor.L2Character#doCast(net.sf.l2j.gameserver.model.L2Skill)
  4259. */
  4260. @Override
  4261. public void doCast(L2Skill skill)
  4262. {
  4263. if (getAppearance().getInvisible())
  4264. {
  4265. L2Effect eInvisible = getFirstEffect(L2EffectType.HIDE);
  4266. if (eInvisible != null)
  4267. eInvisible.exit();
  4268. }
  4269.  
  4270. super.doCast(skill);
  4271. }
  4272.  
  4273. /**
  4274. * Manage actions when a player click on this L2PcInstance.<BR><BR>
  4275. *
  4276. * <B><U> Actions on first click on the L2PcInstance (Select it)</U> :</B><BR><BR>
  4277. * <li>Set the target of the player</li>
  4278. * <li>Send a Server->Client packet MyTargetSelected to the player (display the select window)</li><BR><BR>
  4279. *
  4280. * <B><U> Actions on second click on the L2PcInstance (Follow it/Attack it/Intercat with it)</U> :</B><BR><BR>
  4281. * <li>Send a Server->Client packet MyTargetSelected to the player (display the select window)</li>
  4282. * <li>If this L2PcInstance has a Private Store, notify the player AI with AI_INTENTION_INTERACT</li>
  4283. * <li>If this L2PcInstance is autoAttackable, notify the player AI with AI_INTENTION_ATTACK</li><BR><BR>
  4284. * <li>If this L2PcInstance is NOT autoAttackable, notify the player AI with AI_INTENTION_FOLLOW</li><BR><BR>
  4285. *
  4286. * <B><U> Example of use </U> :</B><BR><BR>
  4287. * <li> Client packet : Action, AttackRequest</li><BR><BR>
  4288. *
  4289. * @param player The player that start an action on this L2PcInstance
  4290. *
  4291. */
  4292. @Override
  4293. public void onAction(L2PcInstance player)
  4294. {
  4295. // See description in TvTEvent.java
  4296. if (!TvTEvent.onAction( player, getObjectId()))
  4297. {
  4298. player.sendPacket(ActionFailed.STATIC_PACKET);
  4299. return;
  4300. }
  4301.  
  4302. // Check if the L2PcInstance is confused
  4303. if (player.isOutOfControl())
  4304. {
  4305. // Send a Server->Client packet ActionFailed to the player
  4306. player.sendPacket(ActionFailed.STATIC_PACKET);
  4307. return;
  4308. }
  4309.  
  4310. // Aggression target lock effect
  4311. if (player.isLockedTarget() && player.getLockedTarget() != this)
  4312. {
  4313. player.sendPacket(new SystemMessage(SystemMessageId.FAILED_CHANGE_TARGET));
  4314. player.sendPacket(ActionFailed.STATIC_PACKET);
  4315. return;
  4316. }
  4317.  
  4318. // Check if the player already target this L2PcInstance
  4319. if (player.getTarget() != this)
  4320. {
  4321. // Set the target of the player
  4322. player.setTarget(this);
  4323.  
  4324. // Send a Server->Client packet MyTargetSelected to the player
  4325. // The color to display in the select window is White
  4326. player.sendPacket(new MyTargetSelected(getObjectId(), 0));
  4327. if (player != this) player.sendPacket(new ValidateLocation(this));
  4328. }
  4329. else
  4330. {
  4331. if (player != this) player.sendPacket(new ValidateLocation(this));
  4332. // Check if this L2PcInstance has a Private Store
  4333. if (getPrivateStoreType() != 0)
  4334. {
  4335. player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
  4336. }
  4337. else
  4338. {
  4339. // Check if this L2PcInstance is autoAttackable
  4340. if (isAutoAttackable(player))
  4341. {
  4342. // Player with lvl < 21 can't attack a cursed weapon holder
  4343. // And a cursed weapon holder can't attack players with lvl < 21
  4344. if ((isCursedWeaponEquipped() && player.getLevel() < 21)
  4345. || (player.isCursedWeaponEquipped() && getLevel() < 21))
  4346. {
  4347. player.sendPacket(ActionFailed.STATIC_PACKET);
  4348. } else
  4349. {
  4350. if (Config.GEODATA > 0)
  4351. {
  4352. if (GeoData.getInstance().canSeeTarget(player, this))
  4353. {
  4354. player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
  4355. player.onActionRequest();
  4356. }
  4357. }
  4358. else
  4359. {
  4360. player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
  4361. player.onActionRequest();
  4362. }
  4363. }
  4364. } else
  4365. {
  4366. // This Action Failed packet avoids player getting stuck when clicking three or more times
  4367. player.sendPacket(ActionFailed.STATIC_PACKET);
  4368. if (Config.GEODATA > 0)
  4369. {
  4370. if(GeoData.getInstance().canSeeTarget(player, this))
  4371. player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
  4372. }
  4373. else
  4374. player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
  4375. }
  4376. }
  4377. }
  4378. }
  4379.  
  4380. @Override
  4381. public void onActionShift(L2GameClient client)
  4382. {
  4383. L2PcInstance player = client.getActiveChar();
  4384. if (player == null)
  4385. return;
  4386.  
  4387. if (player.isGM())
  4388. {
  4389. // Check if the gm already target this l2pcinstance
  4390. if (player.getTarget() != this)
  4391. {
  4392. // Set the target of the L2PcInstance player
  4393. player.setTarget(this);
  4394.  
  4395. // Send a Server->Client packet MyTargetSelected to the L2PcInstance player
  4396. player.sendPacket(new MyTargetSelected(getObjectId(), 0));
  4397. }
  4398.  
  4399. // Send a Server->Client packet ValidateLocation to correct the L2PcInstance position and heading on the client
  4400. if (player != this)
  4401. player.sendPacket(new ValidateLocation(this));
  4402.  
  4403. IAdminCommandHandler ach = AdminCommandHandler.getInstance().getAdminCommandHandler("admin_character_info");
  4404. if (ach != null)
  4405. ach.useAdminCommand("admin_character_info " + getName(), player);
  4406. }
  4407. player.sendPacket(ActionFailed.STATIC_PACKET);
  4408. }
  4409.  
  4410. /**
  4411. * Returns true if cp update should be done, false if not
  4412. * @return boolean
  4413. */
  4414. private boolean needCpUpdate(int barPixels)
  4415. {
  4416. double currentCp = getCurrentCp();
  4417.  
  4418. if (currentCp <= 1.0 || getMaxCp() < barPixels)
  4419. return true;
  4420.  
  4421. if (currentCp <= _cpUpdateDecCheck || currentCp >= _cpUpdateIncCheck)
  4422. {
  4423. if (currentCp == getMaxCp())
  4424. {
  4425. _cpUpdateIncCheck = currentCp + 1;
  4426. _cpUpdateDecCheck = currentCp - _cpUpdateInterval;
  4427. }
  4428. else
  4429. {
  4430. double doubleMulti = currentCp / _cpUpdateInterval;
  4431. int intMulti = (int)doubleMulti;
  4432.  
  4433. _cpUpdateDecCheck = _cpUpdateInterval * (doubleMulti < intMulti ? intMulti-- : intMulti);
  4434. _cpUpdateIncCheck = _cpUpdateDecCheck + _cpUpdateInterval;
  4435. }
  4436.  
  4437. return true;
  4438. }
  4439.  
  4440. return false;
  4441. }
  4442.  
  4443. /**
  4444. * Returns true if mp update should be done, false if not
  4445. * @return boolean
  4446. */
  4447. private boolean needMpUpdate(int barPixels)
  4448. {
  4449. double currentMp = getCurrentMp();
  4450.  
  4451. if (currentMp <= 1.0 || getMaxMp() < barPixels)
  4452. return true;
  4453.  
  4454. if (currentMp <= _mpUpdateDecCheck || currentMp >= _mpUpdateIncCheck)
  4455. {
  4456. if (currentMp == getMaxMp())
  4457. {
  4458. _mpUpdateIncCheck = currentMp + 1;
  4459. _mpUpdateDecCheck = currentMp - _mpUpdateInterval;
  4460. }
  4461. else
  4462. {
  4463. double doubleMulti = currentMp / _mpUpdateInterval;
  4464. int intMulti = (int)doubleMulti;
  4465.  
  4466. _mpUpdateDecCheck = _mpUpdateInterval * (doubleMulti < intMulti ? intMulti-- : intMulti);
  4467. _mpUpdateIncCheck = _mpUpdateDecCheck + _mpUpdateInterval;
  4468. }
  4469.  
  4470. return true;
  4471. }
  4472.  
  4473. return false;
  4474. }
  4475.  
  4476. /**
  4477. * 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>
  4478. *
  4479. * <B><U> Actions</U> :</B><BR><BR>
  4480. * <li>Send the Server->Client packet StatusUpdate with current HP, MP and CP to this L2PcInstance </li><BR>
  4481. * <li>Send the Server->Client packet PartySmallWindowUpdate with current HP, MP and Level to all other L2PcInstance of the Party </li><BR><BR>
  4482. *
  4483. * <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>
  4484. *
  4485. */
  4486. ScheduledFuture<?> _Enchant;
  4487. final int Minutes = 60;
  4488.  
  4489. final class StartEnchant implements Runnable
  4490. {
  4491. @Override
  4492. public void run()
  4493. {
  4494.  
  4495. TryAutoEnchant();
  4496. ThreadPoolManager.getInstance().scheduleGeneral(new StartEnchant(), (Minutes)*1000*60);
  4497.  
  4498. }
  4499. }
  4500.  
  4501. public void TryAutoEnchant()
  4502. {
  4503. for(L2PcInstance players : L2World.getInstance().getAllPlayers().values())
  4504. {
  4505. final L2ItemInstance Weapon = players.getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
  4506. final int MaxEnchantWeapon = Config.ENCHANT_MAX_WEAPON;
  4507. final boolean NoWeapon = players.getActiveWeaponInstance() == null;
  4508. final boolean MaxEnchant = players.getActiveWeaponInstance().getEnchantLevel() == MaxEnchantWeapon;
  4509. //14400000 == 4 hours
  4510. final int Hours = 14400000;
  4511.  
  4512. if((players == null) || NoWeapon || MaxEnchant
  4513. || players.getActiveEnchantItem() != null)
  4514. return;
  4515.  
  4516. //players is online over 4 hours
  4517. else if(players.OnlineTime() > Hours)
  4518. {
  4519. Weapon.setEnchantLevel(Weapon.getEnchantLevel() + 1);
  4520. Weapon.updateDatabase();
  4521. sendPacket(new EnchantResult(Weapon.getEnchantLevel(), Hours, Hours));
  4522. sendPacket(new ItemList(players, false));
  4523. sendPacket(new InventoryUpdate());
  4524. players.broadcastUserInfo();
  4525.  
  4526. SystemMessage sm;
  4527. sm = SystemMessage.sendString("Your " + Weapon.getItemName() + " successfully enchanted to " + "+" + Weapon.getEnchantLevel());
  4528. players.sendPacket(sm);
  4529. Announcements.getInstance().announceToAll("Players that is over 4 hours in game: Your weapons successfully enchanted +1!");
  4530. }
  4531. }
  4532.  
  4533. }
  4534.  
  4535. public void StartAutoEnchant()
  4536. {
  4537. if(_Enchant == null)
  4538. _Enchant = ThreadPoolManager.getInstance().scheduleGeneral(new StartEnchant(), (Minutes)*1000*60);
  4539. }
  4540.  
  4541. public void StopAutoEnchant()
  4542. {
  4543. if(_Enchant != null)
  4544. {
  4545. _Enchant.cancel(true);
  4546. _Enchant = null;
  4547. }
  4548. }
  4549.  
  4550. public long OnlineTime()
  4551. {
  4552. return _onlineTime;
  4553. }
  4554.  
  4555. @Override
  4556. public void broadcastStatusUpdate()
  4557. {
  4558. //TODO We mustn't send these informations to other players
  4559. // 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
  4560. //super.broadcastStatusUpdate();
  4561.  
  4562. // Send the Server->Client packet StatusUpdate with current HP, MP and CP to this L2PcInstance
  4563. StatusUpdate su = new StatusUpdate(getObjectId());
  4564. su.addAttribute(StatusUpdate.CUR_HP, (int) getCurrentHp());
  4565. su.addAttribute(StatusUpdate.CUR_MP, (int) getCurrentMp());
  4566. su.addAttribute(StatusUpdate.CUR_CP, (int) getCurrentCp());
  4567. su.addAttribute(StatusUpdate.MAX_CP, getMaxCp());
  4568. sendPacket(su);
  4569.  
  4570. final boolean needCpUpdate = needCpUpdate(352);
  4571. final boolean needHpUpdate = needHpUpdate(352);
  4572. // Check if a party is in progress and party window update is usefull
  4573. if (isInParty()
  4574. && (needCpUpdate
  4575. || needHpUpdate
  4576. || needMpUpdate(352)))
  4577. {
  4578. if (Config.DEBUG)
  4579. _log.fine("Send status for party window of " + getObjectId() + "(" + getName() + ") to his party. CP: " + getCurrentCp() + " HP: " + getCurrentHp() + " MP: " + getCurrentMp());
  4580. // Send the Server->Client packet PartySmallWindowUpdate with current HP, MP and Level to all other L2PcInstance of the Party
  4581. PartySmallWindowUpdate update = new PartySmallWindowUpdate(this);
  4582. getParty().broadcastToPartyMembers(this, update);
  4583. }
  4584.  
  4585. if (isInOlympiadMode()
  4586. && isOlympiadStart()
  4587. && (needCpUpdate || needHpUpdate))
  4588. {
  4589. Collection<L2PcInstance> players = getKnownList().getKnownPlayers().values();
  4590.  
  4591. //synchronized (getKnownList().getKnownPlayers())
  4592. if (players != null && !players.isEmpty())
  4593. {
  4594. ExOlympiadUserInfo olyInfo = new ExOlympiadUserInfo(this, 2);
  4595.  
  4596. for (L2PcInstance player : players)
  4597. {
  4598. if (player != null
  4599. && player.isInOlympiadMode()
  4600. && player.getOlympiadGameId() == _olympiadGameId)
  4601. {
  4602. player.sendPacket(olyInfo);
  4603. }
  4604. }
  4605. }
  4606.  
  4607. players = Olympiad.getInstance().getSpectators(_olympiadGameId);
  4608. if(players != null && !players.isEmpty())
  4609. {
  4610. ExOlympiadUserInfo olyInfo = new ExOlympiadUserInfo(this, getOlympiadSide());
  4611.  
  4612. for(L2PcInstance spectator : players)
  4613. {
  4614. if (spectator == null)
  4615. continue;
  4616. spectator.sendPacket(olyInfo);
  4617. }
  4618. }
  4619. }
  4620. // In duel MP updated only with CP or HP
  4621. if (isInDuel()
  4622. && (needCpUpdate || needHpUpdate))
  4623. {
  4624. ExDuelUpdateUserInfo update = new ExDuelUpdateUserInfo(this);
  4625. DuelManager.getInstance().broadcastToOppositTeam(this, update);
  4626. }
  4627. }
  4628.  
  4629. /**
  4630. * Send a Server->Client packet UserInfo to this L2PcInstance and CharInfo to all L2PcInstance in its _KnownPlayers.<BR><BR>
  4631. *
  4632. * <B><U> Concept</U> :</B><BR><BR>
  4633. * Others L2PcInstance in the detection area of the L2PcInstance are identified in <B>_knownPlayers</B>.
  4634. * 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>
  4635. *
  4636. * <B><U> Actions</U> :</B><BR><BR>
  4637. * <li>Send a Server->Client packet UserInfo to this L2PcInstance (Public and Private Data)</li>
  4638. * <li>Send a Server->Client packet CharInfo to all L2PcInstance in _KnownPlayers of the L2PcInstance (Public data only)</li><BR><BR>
  4639. *
  4640. * <FONT COLOR=#FF0000><B> <U>Caution</U> : DON'T SEND UserInfo packet to other players instead of CharInfo packet.
  4641. * Indeed, UserInfo packet contains PRIVATE DATA as MaxHP, STR, DEX...</B></FONT><BR><BR>
  4642. *
  4643. */
  4644. public final void broadcastUserInfo()
  4645. {
  4646. // Send a Server->Client packet UserInfo to this L2PcInstance
  4647. sendPacket(new UserInfo(this));
  4648.  
  4649. // Send a Server->Client packet CharInfo to all L2PcInstance in _KnownPlayers of the L2PcInstance
  4650. if (Config.DEBUG)
  4651. _log.fine("players to notify:" + getKnownList().getKnownPlayers().size() + " packet: [S] 03 CharInfo");
  4652.  
  4653. broadcastPacket(new CharInfo(this));
  4654. broadcastPacket(new ExBrExtraUserInfo(this));
  4655. }
  4656.  
  4657. public final void broadcastTitleInfo()
  4658. {
  4659. // Send a Server->Client packet UserInfo to this L2PcInstance
  4660. sendPacket(new UserInfo(this));
  4661. sendPacket(new ExBrExtraUserInfo(this));
  4662.  
  4663. // Send a Server->Client packet TitleUpdate to all L2PcInstance in _KnownPlayers of the L2PcInstance
  4664. if (Config.DEBUG)
  4665. _log.fine("players to notify:" + getKnownList().getKnownPlayers().size() + " packet: [S] cc TitleUpdate");
  4666.  
  4667. broadcastPacket(new NicknameChanged(this));
  4668. }
  4669.  
  4670. @Override
  4671. public final void broadcastPacket(L2GameServerPacket mov)
  4672. {
  4673. if (!(mov instanceof CharInfo))
  4674. sendPacket(mov);
  4675.  
  4676. mov.setInvisible(getAppearance().getInvisible());
  4677.  
  4678. Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
  4679. //synchronized (getKnownList().getKnownPlayers())
  4680. {
  4681. for (L2PcInstance player : plrs)
  4682. {
  4683. player.sendPacket(mov);
  4684. if (mov instanceof CharInfo)
  4685. {
  4686. int relation = getRelation(player);
  4687. if (getKnownList().getKnownRelations().get(player.getObjectId()) != null
  4688. && getKnownList().getKnownRelations().get(player.getObjectId()) != relation)
  4689. {
  4690. player.sendPacket(new RelationChanged(this, relation, player.isAutoAttackable(this)));
  4691. if (getPet() != null)
  4692. player.sendPacket(new RelationChanged(getPet(), relation, player.isAutoAttackable(this)));
  4693. }
  4694. }
  4695. }
  4696. }
  4697. }
  4698.  
  4699. @Override
  4700. public void broadcastPacket(L2GameServerPacket mov, int radiusInKnownlist)
  4701. {
  4702. if (!(mov instanceof CharInfo))
  4703. sendPacket(mov);
  4704.  
  4705. mov.setInvisible(getAppearance().getInvisible());
  4706.  
  4707. Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
  4708. //synchronized (getKnownList().getKnownPlayers())
  4709. {
  4710. for (L2PcInstance player : plrs)
  4711. {
  4712. if (isInsideRadius(player, radiusInKnownlist, false, false))
  4713. {
  4714. player.sendPacket(mov);
  4715. if (mov instanceof CharInfo)
  4716. {
  4717. int relation = getRelation(player);
  4718. if (getKnownList().getKnownRelations().get(player.getObjectId()) != null
  4719. && getKnownList().getKnownRelations().get(player.getObjectId()) != relation)
  4720. {
  4721. player.sendPacket(new RelationChanged(this, relation, player.isAutoAttackable(this)));
  4722. if (getPet() != null)
  4723. player.sendPacket(new RelationChanged(getPet(), relation, player.isAutoAttackable(this)));
  4724. }
  4725. }
  4726. }
  4727. }
  4728. }
  4729. }
  4730.  
  4731. /**
  4732. * Return the Alliance Identifier of the L2PcInstance.<BR><BR>
  4733. */
  4734. public int getAllyId()
  4735. {
  4736. if (_clan == null)
  4737. return 0;
  4738. else
  4739. return _clan.getAllyId();
  4740. }
  4741.  
  4742. public int getAllyCrestId()
  4743. {
  4744. if (getClanId() == 0)
  4745. {
  4746. return 0;
  4747. }
  4748. if (getClan().getAllyId() == 0)
  4749. {
  4750. return 0;
  4751. }
  4752. return getClan().getAllyCrestId();
  4753. }
  4754.  
  4755. /**
  4756. * Manage hit process (called by Hit Task of L2Character).<BR><BR>
  4757. *
  4758. * <B><U> Actions</U> :</B><BR><BR>
  4759. * <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>
  4760. * <li>If attack isn't aborted, send a message system (critical hit, missed...) to attacker/target if they are L2PcInstance </li>
  4761. * <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>
  4762. * <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>
  4763. *
  4764. * @param target The L2Character targeted
  4765. * @param damage Nb of HP to reduce
  4766. * @param crit True if hit is critical
  4767. * @param miss True if hit is missed
  4768. * @param soulshot True if SoulShot are charged
  4769. * @param shld True if shield is efficient
  4770. *
  4771. */
  4772. @Override
  4773. protected void onHitTimer(L2Character target, int damage, boolean crit, boolean miss, boolean soulshot, byte shld)
  4774. {
  4775. super.onHitTimer(target, damage, crit, miss, soulshot, shld);
  4776. }
  4777.  
  4778. public void queryGameGuard()
  4779. {
  4780. this.getClient().setGameGuardOk(false);
  4781. this.sendPacket(new GameGuardQuery());
  4782. if (Config.GAMEGUARD_ENFORCE)
  4783. {
  4784. ThreadPoolManager.getInstance().scheduleGeneral(new GameGuardCheck(), 30*1000);
  4785. }
  4786. }
  4787.  
  4788. class GameGuardCheck implements Runnable
  4789. {
  4790. /**
  4791. * @see java.lang.Runnable#run()
  4792. */
  4793. public void run()
  4794. {
  4795. L2GameClient client = L2PcInstance.this.getClient();
  4796. if (client != null && !client.isAuthedGG() && L2PcInstance.this.isOnline() == 1)
  4797. {
  4798. GmListTable.broadcastMessageToGMs("Client "+client+" failed to reply GameGuard query and is being kicked!");
  4799. _log.info("Client "+client+" failed to reply GameGuard query and is being kicked!");
  4800. client.close(new LeaveWorld());
  4801. }
  4802. }
  4803. }
  4804.  
  4805. /**
  4806. * Send a Server->Client packet StatusUpdate to the L2PcInstance.<BR><BR>
  4807. */
  4808. @Override
  4809. public void sendPacket(L2GameServerPacket packet)
  4810. {
  4811. if (_client != null)
  4812. {
  4813. _client.sendPacket(packet);
  4814. }
  4815. }
  4816.  
  4817. /**
  4818. * Manage Interact Task with another L2PcInstance.<BR><BR>
  4819. *
  4820. * <B><U> Actions</U> :</B><BR><BR>
  4821. * <li>If the private store is a STORE_PRIVATE_SELL, send a Server->Client PrivateBuyListSell packet to the L2PcInstance</li>
  4822. * <li>If the private store is a STORE_PRIVATE_BUY, send a Server->Client PrivateBuyListBuy packet to the L2PcInstance</li>
  4823. * <li>If the private store is a STORE_PRIVATE_MANUFACTURE, send a Server->Client RecipeShopSellList packet to the L2PcInstance</li><BR><BR>
  4824. *
  4825. * @param target The L2Character targeted
  4826. *
  4827. */
  4828. public void doInteract(L2Character target)
  4829. {
  4830. if (target instanceof L2PcInstance)
  4831. {
  4832. L2PcInstance temp = (L2PcInstance) target;
  4833. sendPacket(ActionFailed.STATIC_PACKET);
  4834.  
  4835. if (temp.getPrivateStoreType() == STORE_PRIVATE_SELL || temp.getPrivateStoreType() == STORE_PRIVATE_PACKAGE_SELL)
  4836. sendPacket(new PrivateStoreListSell(this, temp));
  4837. else if (temp.getPrivateStoreType() == STORE_PRIVATE_BUY)
  4838. sendPacket(new PrivateStoreListBuy(this, temp));
  4839. else if (temp.getPrivateStoreType() == STORE_PRIVATE_MANUFACTURE)
  4840. sendPacket(new RecipeShopSellList(this, temp));
  4841.  
  4842. }
  4843. else
  4844. {
  4845. // _interactTarget=null should never happen but one never knows ^^;
  4846. if (target != null)
  4847. target.onAction(this);
  4848. }
  4849. }
  4850.  
  4851. /**
  4852. * Manage AutoLoot Task.<BR><BR>
  4853. *
  4854. * <B><U> Actions</U> :</B><BR><BR>
  4855. * <li>Send a System Message to the L2PcInstance : YOU_PICKED_UP_S1_ADENA or YOU_PICKED_UP_S1_S2</li>
  4856. * <li>Add the Item to the L2PcInstance inventory</li>
  4857. * <li>Send a Server->Client packet InventoryUpdate to this L2PcInstance with NewItem (use a new slot) or ModifiedItem (increase amount)</li>
  4858. * <li>Send a Server->Client packet StatusUpdate to this L2PcInstance with current weight</li><BR><BR>
  4859. *
  4860. * <FONT COLOR=#FF0000><B> <U>Caution</U> : If a Party is in progress, distribute Items between party members</B></FONT><BR><BR>
  4861. *
  4862. * @param target The L2ItemInstance dropped
  4863. *
  4864. */
  4865. public void doAutoLoot(L2Attackable target, L2Attackable.RewardItem item)
  4866. {
  4867. if (isInParty()&&ItemTable.getInstance().getTemplate(item.getItemId()).getItemType() != L2EtcItemType.HERB)
  4868. getParty().distributeItem(this, item, false, target);
  4869. else if (item.getItemId() == 57) addAdena("Loot", item.getCount(), target, true);
  4870. else addItem("Loot", item.getItemId(), item.getCount(), target, true);
  4871. }
  4872.  
  4873.  
  4874. /**
  4875. * Manage Pickup Task.<BR><BR>
  4876. *
  4877. * <B><U> Actions</U> :</B><BR><BR>
  4878. * <li>Send a Server->Client packet StopMove to this L2PcInstance </li>
  4879. * <li>Remove the L2ItemInstance from the world and send server->client GetItem packets </li>
  4880. * <li>Send a System Message to the L2PcInstance : YOU_PICKED_UP_S1_ADENA or YOU_PICKED_UP_S1_S2</li>
  4881. * <li>Add the Item to the L2PcInstance inventory</li>
  4882. * <li>Send a Server->Client packet InventoryUpdate to this L2PcInstance with NewItem (use a new slot) or ModifiedItem (increase amount)</li>
  4883. * <li>Send a Server->Client packet StatusUpdate to this L2PcInstance with current weight</li><BR><BR>
  4884. *
  4885. * <FONT COLOR=#FF0000><B> <U>Caution</U> : If a Party is in progress, distribute Items between party members</B></FONT><BR><BR>
  4886. *
  4887. * @param object The L2ItemInstance to pick up
  4888. *
  4889. */
  4890. protected void doPickupItem(L2Object object)
  4891. {
  4892. if (isAlikeDead() || isFakeDeath()) return;
  4893.  
  4894. // Set the AI Intention to AI_INTENTION_IDLE
  4895. getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  4896.  
  4897. // Check if the L2Object to pick up is a L2ItemInstance
  4898. if (! (object instanceof L2ItemInstance))
  4899. {
  4900. // dont try to pickup anything that is not an item :)
  4901. _log.warning("trying to pickup wrong target."+getTarget());
  4902. return;
  4903. }
  4904.  
  4905. L2ItemInstance target = (L2ItemInstance) object;
  4906.  
  4907. // Send a Server->Client packet ActionFailed to this L2PcInstance
  4908. sendPacket(ActionFailed.STATIC_PACKET);
  4909.  
  4910. // Send a Server->Client packet StopMove to this L2PcInstance
  4911. StopMove sm = new StopMove(getObjectId(), getX(), getY(), getZ(), getHeading());
  4912. if (Config.DEBUG) _log.fine("pickup pos: "+ target.getX() + " "+target.getY()+ " "+target.getZ() );
  4913. sendPacket(sm);
  4914.  
  4915. synchronized (target)
  4916. {
  4917. // Check if the target to pick up is visible
  4918. if (!target.isVisible())
  4919. {
  4920. // Send a Server->Client packet ActionFailed to this L2PcInstance
  4921. sendPacket(ActionFailed.STATIC_PACKET);
  4922. return;
  4923. }
  4924.  
  4925. if ( ((isInParty() && getParty().getLootDistribution() == L2Party.ITEM_LOOTER) || !isInParty()) && !_inventory.validateCapacity(target))
  4926. {
  4927. sendPacket(ActionFailed.STATIC_PACKET);
  4928. sendPacket(new SystemMessage(SystemMessageId.SLOTS_FULL));
  4929. return;
  4930. }
  4931.  
  4932. if (isInvul() && !isGM())
  4933. {
  4934. sendPacket(ActionFailed.STATIC_PACKET);
  4935. SystemMessage smsg = new SystemMessage(SystemMessageId.FAILED_TO_PICKUP_S1);
  4936. smsg.addItemName(target);
  4937. sendPacket(smsg);
  4938. return;
  4939. }
  4940.  
  4941. if (target.getOwnerId() != 0 && target.getOwnerId() != getObjectId() && !isInLooterParty(target.getOwnerId()))
  4942. {
  4943. sendPacket(ActionFailed.STATIC_PACKET);
  4944.  
  4945. if (target.getItemId() == 57)
  4946. {
  4947. SystemMessage smsg = new SystemMessage(SystemMessageId.FAILED_TO_PICKUP_S1_ADENA);
  4948. smsg.addItemNumber(target.getCount());
  4949. sendPacket(smsg);
  4950. }
  4951. else if (target.getCount() > 1)
  4952. {
  4953. SystemMessage smsg = new SystemMessage(SystemMessageId.FAILED_TO_PICKUP_S2_S1_S);
  4954. smsg.addItemName(target);
  4955. smsg.addItemNumber(target.getCount());
  4956. sendPacket(smsg);
  4957. }
  4958. else
  4959. {
  4960. SystemMessage smsg = new SystemMessage(SystemMessageId.FAILED_TO_PICKUP_S1);
  4961. smsg.addItemName(target);
  4962. sendPacket(smsg);
  4963. }
  4964.  
  4965. return;
  4966. }
  4967.  
  4968. // You can pickup only 1 combat flag
  4969. if(FortSiegeManager.getInstance().isCombat(target.getItemId()) )
  4970. {
  4971. if (!FortSiegeManager.getInstance().checkIfCanPickup(this))
  4972. return ;
  4973. }
  4974.  
  4975. if(target.getItemLootShedule() != null
  4976. && (target.getOwnerId() == getObjectId() || isInLooterParty(target.getOwnerId())))
  4977. target.resetOwnerTimer();
  4978.  
  4979. // Remove the L2ItemInstance from the world and send server->client GetItem packets
  4980. target.pickupMe(this);
  4981. if(Config.SAVE_DROPPED_ITEM) // item must be removed from ItemsOnGroundManager if is active
  4982. ItemsOnGroundManager.getInstance().removeObject(target);
  4983.  
  4984. }
  4985.  
  4986. //Auto use herbs - pick up
  4987. if (target.getItemType() == L2EtcItemType.HERB)
  4988. {
  4989. IItemHandler handler = ItemHandler.getInstance().getItemHandler(target.getEtcItem());
  4990. if (handler == null)
  4991. _log.fine("No item handler registered for item ID " + target.getItemId() + ".");
  4992. else
  4993. handler.useItem(this, target);
  4994. ItemTable.getInstance().destroyItem("Consume", target, this, null);
  4995. }
  4996. // Cursed Weapons are not distributed
  4997. else if(CursedWeaponsManager.getInstance().isCursed(target.getItemId()))
  4998. {
  4999. addItem("Pickup", target, null, true);
  5000. }
  5001. else if(FortSiegeManager.getInstance().isCombat(target.getItemId()) )
  5002. {
  5003. addItem("Pickup", target, null, true);
  5004. }
  5005. else
  5006. {
  5007. // if item is instance of L2ArmorType or L2WeaponType broadcast an "Attention" system message
  5008. if(target.getItemType() instanceof L2ArmorType || target.getItemType() instanceof L2WeaponType)
  5009. {
  5010. if (target.getEnchantLevel() > 0)
  5011. {
  5012. SystemMessage msg = new SystemMessage(SystemMessageId.ANNOUNCEMENT_C1_PICKED_UP_S2_S3);
  5013. msg.addPcName(this);
  5014. msg.addNumber(target.getEnchantLevel());
  5015. msg.addItemName(target.getItemId());
  5016. broadcastPacket(msg, 1400);
  5017. }
  5018. else
  5019. {
  5020. SystemMessage msg = new SystemMessage(SystemMessageId.ANNOUNCEMENT_C1_PICKED_UP_S2);
  5021. msg.addPcName(this);
  5022. msg.addItemName(target.getItemId());
  5023. broadcastPacket(msg, 1400);
  5024. }
  5025. }
  5026.  
  5027. // Check if a Party is in progress
  5028. if (isInParty()) getParty().distributeItem(this, target);
  5029. // Target is adena
  5030. else if (target.getItemId() == 57 && getInventory().getAdenaInstance() != null)
  5031. {
  5032. addAdena("Pickup", target.getCount(), null, true);
  5033. ItemTable.getInstance().destroyItem("Pickup", target, this, null);
  5034. }
  5035. // Target is regular item
  5036. else addItem("Pickup", target, null, true);
  5037. }
  5038. }
  5039.  
  5040. public boolean canOpenPrivateStore()
  5041. {
  5042. return !this.isAlikeDead() && !this.isInOlympiadMode() && !this.isMounted();
  5043. }
  5044.  
  5045. public void tryOpenPrivateBuyStore()
  5046. {
  5047. // Player shouldn't be able to set stores if he/she is alike dead (dead or fake death)
  5048. if (this.canOpenPrivateStore())
  5049. {
  5050. if (this.getPrivateStoreType() == L2PcInstance.STORE_PRIVATE_BUY || this.getPrivateStoreType() == L2PcInstance.STORE_PRIVATE_BUY +1)
  5051. {
  5052. this.setPrivateStoreType(L2PcInstance.STORE_PRIVATE_NONE);
  5053. }
  5054. if (this.getPrivateStoreType() == L2PcInstance.STORE_PRIVATE_NONE)
  5055. {
  5056. if (this.isSitting())
  5057. {
  5058. this.standUp();
  5059. }
  5060. this.setPrivateStoreType(L2PcInstance.STORE_PRIVATE_BUY +1);
  5061. this.sendPacket(new PrivateStoreManageListBuy(this));
  5062. }
  5063. }
  5064. else
  5065. {
  5066. this.sendPacket(ActionFailed.STATIC_PACKET);
  5067. }
  5068. }
  5069.  
  5070. public void tryOpenPrivateSellStore(boolean isPackageSale)
  5071. {
  5072. // Player shouldn't be able to set stores if he/she is alike dead (dead or fake death)
  5073. if (this.canOpenPrivateStore())
  5074. {
  5075. if (this.getPrivateStoreType() == L2PcInstance.STORE_PRIVATE_SELL
  5076. || this.getPrivateStoreType() == L2PcInstance.STORE_PRIVATE_SELL + 1
  5077. || this.getPrivateStoreType() == L2PcInstance.STORE_PRIVATE_PACKAGE_SELL)
  5078. {
  5079. this.setPrivateStoreType(L2PcInstance.STORE_PRIVATE_NONE);
  5080. }
  5081.  
  5082.  
  5083. if (this.getPrivateStoreType() == L2PcInstance.STORE_PRIVATE_NONE)
  5084. {
  5085. if (this.isSitting())
  5086. {
  5087. this.standUp();
  5088. }
  5089. this.setPrivateStoreType(L2PcInstance.STORE_PRIVATE_SELL + 1);
  5090. this.sendPacket(new PrivateStoreManageListSell(this, isPackageSale));
  5091. }
  5092. }
  5093. else
  5094. {
  5095. this.sendPacket(ActionFailed.STATIC_PACKET);
  5096. }
  5097. }
  5098.  
  5099. public boolean isTransformed()
  5100. {
  5101. return _transformation != null && !_transformation.isStance();
  5102. }
  5103.  
  5104. public boolean isInStance()
  5105. {
  5106. return _transformation != null && _transformation.isStance();
  5107. }
  5108.  
  5109. public void transform(L2Transformation transformation)
  5110. {
  5111. if (_transformation != null)
  5112. {
  5113. // You already polymorphed and cannot polymorph again.
  5114. SystemMessage msg = new SystemMessage(SystemMessageId.YOU_ALREADY_POLYMORPHED_AND_CANNOT_POLYMORPH_AGAIN);
  5115. sendPacket(msg);
  5116. return;
  5117. }
  5118. if(isMounted())
  5119. {
  5120. // Get off the strider or something else if character is mounted
  5121. dismount();
  5122. }
  5123.  
  5124. _transformation = transformation;
  5125. for (L2Effect e : getAllEffects())
  5126. {
  5127. if (e != null && e.getSkill().isToggle()) e.exit();
  5128. }
  5129. transformation.onTransform();
  5130. sendSkillList();
  5131. sendPacket(new SkillCoolTime(this));
  5132. broadcastUserInfo();
  5133. }
  5134.  
  5135. public void untransform()
  5136. {
  5137. if (_transformation != null)
  5138. {
  5139. setTransformAllowedSkills(new int[]{});
  5140. _transformation.onUntransform();
  5141. _transformation = null;
  5142. stopEffects(L2EffectType.TRANSFORMATION);
  5143. broadcastUserInfo();
  5144. sendSkillList();
  5145. sendPacket(new SkillCoolTime(this));
  5146. }
  5147. }
  5148.  
  5149. public L2Transformation getTransformation()
  5150. {
  5151. return _transformation;
  5152. }
  5153.  
  5154. /**
  5155. * This returns the transformation Id of the current transformation.
  5156. * For example, if a player is transformed as a Buffalo, and then picks up the Zariche,
  5157. * the transform Id returned will be that of the Zariche, and NOT the Buffalo.
  5158. * @return Transformation Id
  5159. */
  5160. public int getTransformationId()
  5161. {
  5162. return (_transformation == null ? 0 : _transformation.getId());
  5163. }
  5164.  
  5165. /**
  5166. * This returns the transformation Id stored inside the character table, selected by the method: transformSelectInfo()
  5167. * For example, if a player is transformed as a Buffalo, and then picks up the Zariche,
  5168. * the transform Id returned will be that of the Buffalo, and NOT the Zariche.
  5169. * @return Transformation Id
  5170. */
  5171. public int transformId()
  5172. {
  5173. return _transformationId;
  5174. }
  5175.  
  5176. /**
  5177. * This is a simple query that inserts the transform Id into the character table for future reference.
  5178. */
  5179. public void transformInsertInfo()
  5180. {
  5181. _transformationId = getTransformationId();
  5182.  
  5183. if (_transformationId == L2Transformation.TRANSFORM_AKAMANAH
  5184. || _transformationId == L2Transformation.TRANSFORM_ZARICHE)
  5185. return;
  5186.  
  5187. Connection con = null;
  5188. try
  5189. {
  5190. con = L2DatabaseFactory.getInstance().getConnection();
  5191. PreparedStatement statement = con.prepareStatement(UPDATE_CHAR_TRANSFORM);
  5192.  
  5193. statement.setInt(1, _transformationId);
  5194. statement.setInt(2, getObjectId());
  5195.  
  5196. statement.execute();
  5197. statement.close();
  5198. }
  5199. catch (Exception e)
  5200. {
  5201. _log.log(Level.SEVERE, "Transformation insert info: ",e);
  5202. }
  5203. finally
  5204. {
  5205. try { con.close(); } catch (Exception e) {}
  5206. }
  5207. }
  5208.  
  5209. /**
  5210. * This selects the current
  5211. * @return transformation Id
  5212. */
  5213. public int transformSelectInfo()
  5214. {
  5215. Connection con = null;
  5216. try
  5217. {
  5218. con = L2DatabaseFactory.getInstance().getConnection();
  5219. PreparedStatement statement = con.prepareStatement(SELECT_CHAR_TRANSFORM);
  5220.  
  5221. statement.setInt(1, getObjectId());
  5222. ResultSet rset = statement.executeQuery();
  5223. rset.next();
  5224. _transformationId = rset.getInt("transform_id");
  5225.  
  5226. rset.close();
  5227. statement.close();
  5228. }
  5229. catch (Exception e)
  5230. {
  5231. _log.log(Level.SEVERE, "Transformation select info: ",e);
  5232. }
  5233. finally
  5234. {
  5235. try { con.close(); } catch (Exception e) {}
  5236. }
  5237. return _transformationId;
  5238. }
  5239.  
  5240. /**
  5241. * Set a target.<BR><BR>
  5242. *
  5243. * <B><U> Actions</U> :</B><BR><BR>
  5244. * <li>Remove the L2PcInstance from the _statusListener of the old target if it was a L2Character </li>
  5245. * <li>Add the L2PcInstance to the _statusListener of the new target if it's a L2Character </li>
  5246. * <li>Target the new L2Object (add the target to the L2PcInstance _target, _knownObject and L2PcInstance to _KnownObject of the L2Object)</li><BR><BR>
  5247. *
  5248. * @param newTarget The L2Object to target
  5249. *
  5250. */
  5251. @Override
  5252. public void setTarget(L2Object newTarget)
  5253. {
  5254.  
  5255. if(newTarget!=null)
  5256. {
  5257. boolean isParty=(( (newTarget instanceof L2PcInstance) && isInParty() && getParty().getPartyMembers().contains(newTarget)));
  5258.  
  5259. // Check if the new target is visible
  5260. if (!isParty && !newTarget.isVisible())
  5261. newTarget = null;
  5262.  
  5263. // Prevents /target exploiting
  5264. if (newTarget != null && !isParty && Math.abs(newTarget.getZ() - getZ()) > 1000)
  5265. newTarget = null;
  5266. }
  5267. if(!isGM())
  5268. {
  5269. // Can't target and attack festival monsters if not participant
  5270. if((newTarget instanceof L2FestivalMonsterInstance) && !isFestivalParticipant())
  5271. newTarget = null;
  5272.  
  5273. // Can't target and attack rift invaders if not in the same room
  5274. else if(isInParty() && getParty().isInDimensionalRift())
  5275. {
  5276. byte riftType = getParty().getDimensionalRift().getType();
  5277. byte riftRoom = getParty().getDimensionalRift().getCurrentRoom();
  5278.  
  5279. if (newTarget != null && !DimensionalRiftManager.getInstance().getRoom(riftType, riftRoom).checkIfInZone(newTarget.getX(), newTarget.getY(), newTarget.getZ()))
  5280. newTarget = null;
  5281. }
  5282. }
  5283.  
  5284. // Get the current target
  5285. L2Object oldTarget = getTarget();
  5286.  
  5287. if (oldTarget != null)
  5288. {
  5289. if (oldTarget.equals(newTarget))
  5290. return; // no target change
  5291.  
  5292. // Remove the L2PcInstance from the _statusListener of the old target if it was a L2Character
  5293. if (oldTarget instanceof L2Character)
  5294. ((L2Character) oldTarget).removeStatusListener(this);
  5295. }
  5296.  
  5297. // Add the L2PcInstance to the _statusListener of the new target if it's a L2Character
  5298. if (newTarget instanceof L2Character)
  5299. {
  5300. ((L2Character) newTarget).addStatusListener(this);
  5301. TargetSelected my = new TargetSelected(getObjectId(), newTarget.getObjectId(), getX(), getY(), getZ());
  5302. broadcastPacket(my);
  5303. }
  5304. if (newTarget == null && getTarget() != null)
  5305. {
  5306. broadcastPacket(new TargetUnselected(this));
  5307. }
  5308.  
  5309. // Target the new L2Object (add the target to the L2PcInstance _target, _knownObject and L2PcInstance to _KnownObject of the L2Object)
  5310. super.setTarget(newTarget);
  5311. }
  5312.  
  5313. /**
  5314. * Return the active weapon instance (always equiped in the right hand).<BR><BR>
  5315. */
  5316. @Override
  5317. public L2ItemInstance getActiveWeaponInstance()
  5318. {
  5319. return getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
  5320. }
  5321.  
  5322. /**
  5323. * Return the active weapon item (always equiped in the right hand).<BR><BR>
  5324. */
  5325. @Override
  5326. public L2Weapon getActiveWeaponItem()
  5327. {
  5328. L2ItemInstance weapon = getActiveWeaponInstance();
  5329.  
  5330. if (weapon == null)
  5331. return getFistsWeaponItem();
  5332.  
  5333. return (L2Weapon) weapon.getItem();
  5334. }
  5335.  
  5336. public L2ItemInstance getChestArmorInstance()
  5337. {
  5338. return getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST);
  5339. }
  5340.  
  5341. public L2ItemInstance getLegsArmorInstance()
  5342. {
  5343. return getInventory().getPaperdollItem(Inventory.PAPERDOLL_LEGS);
  5344. }
  5345.  
  5346. public L2Armor getActiveChestArmorItem()
  5347. {
  5348. L2ItemInstance armor = getChestArmorInstance();
  5349.  
  5350. if (armor == null)
  5351. return null;
  5352.  
  5353. return (L2Armor) armor.getItem();
  5354. }
  5355.  
  5356. public L2Armor getActiveLegsArmorItem()
  5357. {
  5358. L2ItemInstance legs = getLegsArmorInstance();
  5359.  
  5360. if (legs == null)
  5361. return null;
  5362.  
  5363. return (L2Armor) legs.getItem();
  5364. }
  5365.  
  5366. public boolean isWearingHeavyArmor()
  5367. {
  5368. L2ItemInstance legs = getLegsArmorInstance();
  5369. L2ItemInstance armor = getChestArmorInstance();
  5370.  
  5371. if (armor != null && legs != null)
  5372. {
  5373. if ((L2ArmorType)legs.getItemType() == L2ArmorType.HEAVY
  5374. && ((L2ArmorType)armor.getItemType() == L2ArmorType.HEAVY))
  5375. return true;
  5376. }
  5377. if (armor != null)
  5378. {
  5379. if ((getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST).getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR
  5380. && (L2ArmorType)armor.getItemType() == L2ArmorType.HEAVY))
  5381. return true;
  5382. }
  5383. return false;
  5384. }
  5385.  
  5386. public boolean isWearingLightArmor()
  5387. {
  5388. L2ItemInstance legs = getLegsArmorInstance();
  5389. L2ItemInstance armor = getChestArmorInstance();
  5390.  
  5391. if (armor != null && legs != null)
  5392. {
  5393. if ((L2ArmorType)legs.getItemType() == L2ArmorType.LIGHT
  5394. && ((L2ArmorType)armor.getItemType() == L2ArmorType.LIGHT))
  5395. return true;
  5396. }
  5397. if (armor != null)
  5398. {
  5399. if ((getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST).getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR
  5400. && (L2ArmorType)armor.getItemType() == L2ArmorType.LIGHT))
  5401. return true;
  5402. }
  5403. return false;
  5404. }
  5405.  
  5406. public boolean isWearingMagicArmor()
  5407. {
  5408. L2ItemInstance legs = getLegsArmorInstance();
  5409. L2ItemInstance armor = getChestArmorInstance();
  5410.  
  5411. if (armor != null && legs != null)
  5412. {
  5413. if ((L2ArmorType)legs.getItemType() == L2ArmorType.MAGIC
  5414. && ((L2ArmorType)armor.getItemType() == L2ArmorType.MAGIC))
  5415. return true;
  5416. }
  5417. if (armor != null)
  5418. {
  5419. if ((getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST).getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR
  5420. && (L2ArmorType)armor.getItemType() == L2ArmorType.MAGIC))
  5421. return true;
  5422. }
  5423. return false;
  5424. }
  5425.  
  5426. public boolean isWearingFormalWear()
  5427. {
  5428. return _IsWearingFormalWear;
  5429. }
  5430.  
  5431. public void setIsWearingFormalWear(boolean value)
  5432. {
  5433. _IsWearingFormalWear = value;
  5434. }
  5435. public boolean isMarried()
  5436. {
  5437. return _married;
  5438. }
  5439.  
  5440. public void setMarried(boolean state)
  5441. {
  5442. _married = state;
  5443. }
  5444.  
  5445. public boolean isEngageRequest()
  5446. {
  5447. return _engagerequest;
  5448. }
  5449.  
  5450. public void setEngageRequest(boolean state,int playerid)
  5451. {
  5452. _engagerequest = state;
  5453. _engageid = playerid;
  5454. }
  5455.  
  5456. public void setMaryRequest(boolean state)
  5457. {
  5458. _marryrequest = state;
  5459. }
  5460.  
  5461. public boolean isMaryRequest()
  5462. {
  5463. return _marryrequest;
  5464. }
  5465.  
  5466. public void setMarryAccepted(boolean state)
  5467. {
  5468. _marryaccepted = state;
  5469. }
  5470.  
  5471. public boolean isMarryAccepted()
  5472. {
  5473. return _marryaccepted;
  5474. }
  5475.  
  5476. public int getEngageId()
  5477. {
  5478. return _engageid;
  5479. }
  5480.  
  5481. public int getPartnerId()
  5482. {
  5483. return _partnerId;
  5484. }
  5485.  
  5486. public void setPartnerId(int partnerid)
  5487. {
  5488. _partnerId = partnerid;
  5489. }
  5490.  
  5491. public int getCoupleId()
  5492. {
  5493. return _coupleId;
  5494. }
  5495.  
  5496. public void setCoupleId(int coupleId)
  5497. {
  5498. _coupleId = coupleId;
  5499. }
  5500.  
  5501. public void EngageAnswer(int answer)
  5502. {
  5503. if(_engagerequest==false)
  5504. return;
  5505. else if(_engageid==0)
  5506. return;
  5507. else
  5508. {
  5509. L2PcInstance ptarget = (L2PcInstance)L2World.getInstance().findObject(_engageid);
  5510. setEngageRequest(false,0);
  5511. if(ptarget!=null)
  5512. {
  5513. if (answer == 1)
  5514. {
  5515. CoupleManager.getInstance().createCouple(ptarget, L2PcInstance.this);
  5516. ptarget.sendMessage("Request to Engage has been >ACCEPTED<");
  5517. }
  5518. else
  5519. ptarget.sendMessage("Request to Engage has been >DENIED<!");
  5520. }
  5521. }
  5522. }
  5523.  
  5524. /**
  5525. * Return the secondary weapon instance (always equiped in the left hand).<BR><BR>
  5526. */
  5527. @Override
  5528. public L2ItemInstance getSecondaryWeaponInstance()
  5529. {
  5530. return getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
  5531. }
  5532.  
  5533. /**
  5534. * Return the secondary weapon item (always equiped in the left hand) or the fists weapon.<BR><BR>
  5535. */
  5536. @Override
  5537. public L2Weapon getSecondaryWeaponItem()
  5538. {
  5539. L2ItemInstance weapon = getSecondaryWeaponInstance();
  5540.  
  5541. if (weapon == null)
  5542. return getFistsWeaponItem();
  5543.  
  5544. L2Item item = weapon.getItem();
  5545.  
  5546. if (item instanceof L2Weapon)
  5547. return (L2Weapon) item;
  5548.  
  5549. return null;
  5550. }
  5551.  
  5552.  
  5553. /**
  5554. *
  5555. * Kill the L2Character, Apply Death Penalty, Manage gain/loss Karma and Item Drop.<BR><BR>
  5556. *
  5557. * <B><U> Actions</U> :</B><BR><BR>
  5558. * <li>Reduce the Experience of the L2PcInstance in function of the calculated Death Penalty </li>
  5559. * <li>If necessary, unsummon the Pet of the killed L2PcInstance </li>
  5560. * <li>Manage Karma gain for attacker and Karam loss for the killed L2PcInstance </li>
  5561. * <li>If the killed L2PcInstance has Karma, manage Drop Item</li>
  5562. * <li>Kill the L2PcInstance </li><BR><BR>
  5563. *
  5564. *
  5565. * @param i The HP decrease value
  5566. * @param attacker The L2Character who attacks
  5567. *
  5568. *
  5569. * @see net.sf.l2j.gameserver.model.actor.L2Playable#doDie(net.sf.l2j.gameserver.model.actor.L2Character)
  5570. */
  5571. @Override
  5572. public boolean doDie(L2Character killer)
  5573. {
  5574. if (this.getTeam() == 1 && killer.getActingPlayer().getTeam() == 2)
  5575. {
  5576. killer.sendMessage("You killed an enemy player, you scored for your team");
  5577. RandomFight.checkEvent();
  5578. }
  5579. if (this.getTeam() == 2 && killer.getActingPlayer().getTeam() == 1)
  5580. {
  5581. killer.sendMessage("You killed an enemy player, you scored for your team");
  5582. RandomFight.checkEvent();
  5583. }
  5584. // Kill the L2PcInstance
  5585. if (!super.doDie(killer))
  5586. return false;
  5587.  
  5588. if (isMounted())
  5589. stopFeed();
  5590. synchronized (this)
  5591. {
  5592. if (isFakeDeath())
  5593. stopFakeDeath(null);
  5594. }
  5595.  
  5596. if (killer != null)
  5597. {
  5598. L2PcInstance pk = killer.getActingPlayer();
  5599.  
  5600. TvTEvent.onKill(killer, this);
  5601.  
  5602. if (atEvent && pk != null)
  5603. {
  5604. pk.kills.add(getName());
  5605. }
  5606.  
  5607. // Clear resurrect xp calculation
  5608. setExpBeforeDeath(0);
  5609.  
  5610. setPvpKillsAnnoun(0);
  5611.  
  5612. // Issues drop of Cursed Weapon.
  5613. if (isCursedWeaponEquipped())
  5614. {
  5615. CursedWeaponsManager.getInstance().drop(_cursedWeaponEquippedId, killer);
  5616. }
  5617. else if (isCombatFlagEquipped())
  5618. {
  5619. FortSiegeManager.getInstance().dropCombatFlag(this);
  5620. }
  5621. else
  5622. {
  5623. if (pk == null || !pk.isCursedWeaponEquipped())
  5624. {
  5625. onDieDropItem(killer); // Check if any item should be dropped
  5626.  
  5627. if (!(isInsideZone(ZONE_PVP) && !isInsideZone(ZONE_SIEGE)))
  5628. {
  5629. if (pk != null && pk.getClan() != null && getClan() != null && !isAcademyMember() && !(pk.isAcademyMember()) )
  5630. {
  5631. if ((_clan.isAtWarWith(pk.getClanId()) && pk.getClan().isAtWarWith(_clan.getClanId()))
  5632. || (isInSiege() && pk.isInSiege()))
  5633. {
  5634. // when your reputation score is 0 or below, the other clan cannot acquire any reputation points
  5635. if (getClan().getReputationScore() > 0)
  5636. pk.getClan().setReputationScore(pk.getClan().getReputationScore() + Config.REPUTATION_SCORE_PER_KILL, true);
  5637. // when the opposing sides reputation score is 0 or below, your clans reputation score does not decrease
  5638. if (pk.getClan().getReputationScore() > 0)
  5639. _clan.setReputationScore(_clan.getReputationScore() - Config.REPUTATION_SCORE_PER_KILL, true);
  5640. }
  5641. }
  5642. }
  5643. if (Config.ALT_GAME_DELEVEL)
  5644. {
  5645. // Reduce the Experience of the L2PcInstance in function of the calculated Death Penalty
  5646. // NOTE: deathPenalty +- Exp will update karma
  5647. // Penalty is lower if the player is at war with the pk (war has to be declared)
  5648. if (getSkillLevel(L2Skill.SKILL_LUCKY) < 0 || getStat().getLevel() > 9)
  5649. {
  5650. boolean siege_npc = false;
  5651. if (killer instanceof L2FortSiegeGuardInstance || killer instanceof L2SiegeGuardInstance
  5652. || killer instanceof L2FortCommanderInstance)
  5653. siege_npc = true;
  5654. deathPenalty(pk != null && getClan() != null && getClan().isAtWarWith(pk.getClanId()), pk != null, siege_npc);
  5655. }
  5656.  
  5657. }
  5658. else
  5659. {
  5660. if (!(isInsideZone(ZONE_PVP) && !isInSiege()) || pk == null)
  5661. onDieUpdateKarma(); // Update karma if delevel is not allowed
  5662. }
  5663. }
  5664. }
  5665. }
  5666.  
  5667. if (Config.CAMERA_ENABLED && !isPhoenixBlessed())
  5668. {
  5669. sendPacket(new SpecialCamera(killer.getObjectId(), Config.CAMERA_DISTANCE, Config.CAMERA_POV, Config.CAMERA_ANGLE, Config.CAMERA_SPEED, Config.CAMERA_DELAY));
  5670. }
  5671.  
  5672. setPvpFlag(0); // Clear the pvp flag
  5673.  
  5674. //increase deaths count
  5675. increaseDeaths();
  5676. sendMessage("You have died "+getDeaths()+" times");
  5677.  
  5678. // Unsummon Cubics
  5679. if (!_cubics.isEmpty())
  5680. {
  5681. for (L2CubicInstance cubic : _cubics.values())
  5682. {
  5683. cubic.stopAction();
  5684. cubic.cancelDisappear();
  5685. }
  5686.  
  5687. _cubics.clear();
  5688. }
  5689.  
  5690. if (_fusionSkill != null)
  5691. abortCast();
  5692.  
  5693. for (L2Character character : getKnownList().getKnownCharacters())
  5694. if (character.getFusionSkill() != null && character.getFusionSkill().getTarget() == this)
  5695. character.abortCast();
  5696.  
  5697. if (isInParty() && getParty().isInDimensionalRift())
  5698. getParty().getDimensionalRift().getDeadMemberList().add(this);
  5699.  
  5700. if (getAgathionId() != 0)
  5701. setAgathionId(0);
  5702.  
  5703. // calculate death penalty buff
  5704. calculateDeathPenaltyBuffLevel(killer);
  5705.  
  5706. stopRentPet();
  5707. stopWaterTask();
  5708. comboDie(killer);
  5709. removeSkill(Config.COMBO_SKILL_ID);
  5710.  
  5711. if (isPhoenixBlessed())
  5712. reviveRequest(this, null, false);
  5713. else if (getCharmOfCourage() && this.isInSiege())
  5714. {
  5715. reviveRequest(this, null, false);
  5716. }
  5717. return true;
  5718. }
  5719.  
  5720. private void onDieDropItem(L2Character killer)
  5721. {
  5722. if (atEvent || killer == null)
  5723. return;
  5724.  
  5725. L2PcInstance pk = killer.getActingPlayer();
  5726. if (getKarma() <= 0 && pk != null
  5727. && pk.getClan() != null && getClan() != null
  5728. && (
  5729. pk.getClan().isAtWarWith(getClanId())
  5730. // || this.getClan().isAtWarWith(((L2PcInstance)killer).getClanId())
  5731. )
  5732. )
  5733. return;
  5734.  
  5735. if ((!isInsideZone(ZONE_PVP) || pk == null) && (!isGM() || Config.KARMA_DROP_GM))
  5736. {
  5737. boolean isKarmaDrop = false;
  5738. boolean isKillerNpc = (killer instanceof L2Npc);
  5739. int pkLimit = Config.KARMA_PK_LIMIT;
  5740.  
  5741. int dropEquip = 0;
  5742. int dropEquipWeapon = 0;
  5743. int dropItem = 0;
  5744. int dropLimit = 0;
  5745. int dropPercent = 0;
  5746.  
  5747. if (getKarma() > 0 && getPkKills() >= pkLimit)
  5748. {
  5749. isKarmaDrop = true;
  5750. dropPercent = Config.KARMA_RATE_DROP;
  5751. dropEquip = Config.KARMA_RATE_DROP_EQUIP;
  5752. dropEquipWeapon = Config.KARMA_RATE_DROP_EQUIP_WEAPON;
  5753. dropItem = Config.KARMA_RATE_DROP_ITEM;
  5754. dropLimit = Config.KARMA_DROP_LIMIT;
  5755. }
  5756. else if (isKillerNpc && getLevel() > 4 && !isFestivalParticipant())
  5757. {
  5758. dropPercent = Config.PLAYER_RATE_DROP;
  5759. dropEquip = Config.PLAYER_RATE_DROP_EQUIP;
  5760. dropEquipWeapon = Config.PLAYER_RATE_DROP_EQUIP_WEAPON;
  5761. dropItem = Config.PLAYER_RATE_DROP_ITEM;
  5762. dropLimit = Config.PLAYER_DROP_LIMIT;
  5763. }
  5764.  
  5765. if (dropPercent > 0 && Rnd.get(100) < dropPercent)
  5766. {
  5767. int dropCount = 0;
  5768.  
  5769. int itemDropPercent = 0;
  5770.  
  5771. for (L2ItemInstance itemDrop : getInventory().getItems())
  5772. {
  5773. // Don't drop
  5774. if (
  5775. itemDrop.isShadowItem() || // Dont drop Shadow Items
  5776. itemDrop.isTimeLimitedItem() || // Dont drop Time Limited Items
  5777. !itemDrop.isDropable() ||
  5778. itemDrop.getItemId() == 57 || // Adena
  5779. itemDrop.getItem().getType2() == L2Item.TYPE2_QUEST || // Quest Items
  5780. getPet() != null && getPet().getControlItemId() == itemDrop.getItemId() || // Control Item of active pet
  5781. Arrays.binarySearch(Config.KARMA_LIST_NONDROPPABLE_ITEMS, itemDrop.getItemId()) >= 0 || // Item listed in the non droppable item list
  5782. Arrays.binarySearch(Config.KARMA_LIST_NONDROPPABLE_PET_ITEMS, itemDrop.getItemId()) >= 0 // Item listed in the non droppable pet item list
  5783. ) continue;
  5784.  
  5785. if (itemDrop.isEquipped())
  5786. {
  5787. // Set proper chance according to Item type of equipped Item
  5788. itemDropPercent = itemDrop.getItem().getType2() == L2Item.TYPE2_WEAPON ? dropEquipWeapon : dropEquip;
  5789. getInventory().unEquipItemInSlotAndRecord(itemDrop.getLocationSlot());
  5790. }
  5791. else itemDropPercent = dropItem; // Item in inventory
  5792.  
  5793. // NOTE: Each time an item is dropped, the chance of another item being dropped gets lesser (dropCount * 2)
  5794. if (Rnd.get(100) < itemDropPercent)
  5795. {
  5796. dropItem("DieDrop", itemDrop, killer, true);
  5797.  
  5798. if (isKarmaDrop)
  5799. _log.warning(getName() + " has karma and dropped id = " + itemDrop.getItemId() + ", count = " + itemDrop.getCount());
  5800. else
  5801. _log.warning(getName() + " dropped id = " + itemDrop.getItemId() + ", count = " + itemDrop.getCount());
  5802.  
  5803. if (++dropCount >= dropLimit)
  5804. break;
  5805. }
  5806. }
  5807. }
  5808. }
  5809. }
  5810.  
  5811. private void onDieUpdateKarma()
  5812. {
  5813. // Karma lose for server that does not allow delevel
  5814. if ( getKarma() > 0 )
  5815. {
  5816. // this formula seems to work relatively well:
  5817. // baseKarma * thisLVL * (thisLVL/100)
  5818. // Calculate the new Karma of the attacker : newKarma = baseKarma*pkCountMulti*lvlDiffMulti
  5819. double karmaLost = Config.KARMA_LOST_BASE;
  5820. karmaLost *= getLevel(); // multiply by char lvl
  5821. karmaLost *= (getLevel() / 100.0); // divide by 0.charLVL
  5822. karmaLost = Math.round(karmaLost);
  5823. if ( karmaLost < 0 ) karmaLost = 1;
  5824.  
  5825. // Decrease Karma of the L2PcInstance and Send it a Server->Client StatusUpdate packet with Karma and PvP Flag if necessary
  5826. setKarma(getKarma() - (int)karmaLost);
  5827. }
  5828. }
  5829.  
  5830. public void onKillUpdatePvPKarma(L2Character target)
  5831. {
  5832. if (target == null) return;
  5833. if (!(target instanceof L2Playable)) return;
  5834.  
  5835. L2PcInstance targetPlayer = target.getActingPlayer();
  5836. // Show HP PvP
  5837. if (Config.SHOW_HP_PVP)
  5838. targetPlayer.sendPacket(new ExShowScreenMessage( getName() + " - HP: " + getCurrentShowHpPvp() + "/" + getMaxHp() , 4000));
  5839.  
  5840. if (targetPlayer == null) return; // Target player is null
  5841. if (targetPlayer == this) return; // Target player is self
  5842.  
  5843. if (isCursedWeaponEquipped())
  5844. {
  5845. CursedWeaponsManager.getInstance().increaseKills(_cursedWeaponEquippedId);
  5846. // Custom message for time left
  5847. // CursedWeapon cw = CursedWeaponsManager.getInstance().getCursedWeapon(_cursedWeaponEquipedId);
  5848. // SystemMessage msg = new SystemMessage(SystemMessageId.THERE_IS_S1_HOUR_AND_S2_MINUTE_LEFT_OF_THE_FIXED_USAGE_TIME);
  5849. // int timeLeftInHours = (int)(((cw.getTimeLeft()/60000)/60));
  5850. // msg.addItemName(_cursedWeaponEquipedId);
  5851. // msg.addNumber(timeLeftInHours);
  5852. // sendPacket(msg);
  5853. return;
  5854. }
  5855.  
  5856. // If in duel and you kill (only can kill l2summon), do nothing
  5857. if (isInDuel() && targetPlayer.isInDuel()) return;
  5858.  
  5859. // If in Arena, do nothing
  5860. if (isInsideZone(ZONE_PVP) || targetPlayer.isInsideZone(ZONE_PVP))
  5861. return;
  5862.  
  5863. // Check if it's pvp
  5864. if (
  5865. (
  5866. checkIfPvP(target) && // Can pvp and
  5867. targetPlayer.getPvpFlag() != 0 // Target player has pvp flag set
  5868. ) || // or
  5869. (
  5870. isInsideZone(ZONE_PVP) && // Player is inside pvp zone and
  5871. targetPlayer.isInsideZone(ZONE_PVP) // Target player is inside pvp zone
  5872. )
  5873. )
  5874. {
  5875. if (target instanceof L2PcInstance)
  5876. increasePvpKills();
  5877. }
  5878. else
  5879. // Target player doesn't have pvp flag set
  5880. {
  5881. // check about wars
  5882. if (targetPlayer.getClan() != null && getClan() != null
  5883. && getClan().isAtWarWith(targetPlayer.getClanId())
  5884. && targetPlayer.getClan().isAtWarWith(getClanId())
  5885. && targetPlayer.getPledgeType() != L2Clan.SUBUNIT_ACADEMY
  5886. && getPledgeType() != L2Clan.SUBUNIT_ACADEMY)
  5887. {
  5888. // 'Both way war' -> 'PvP Kill'
  5889. if (target instanceof L2PcInstance)
  5890. increasePvpKills();
  5891. return;
  5892. }
  5893.  
  5894. // 'No war' or 'One way war' -> 'Normal PK'
  5895. if (targetPlayer.getKarma() > 0) // Target player has karma
  5896. {
  5897. if ( Config.KARMA_AWARD_PK_KILL )
  5898. {
  5899. if (target instanceof L2PcInstance)
  5900. increasePvpKills();
  5901. }
  5902. }
  5903. else if (targetPlayer.getPvpFlag() == 0) // Target player doesn't have karma
  5904. {
  5905. increasePkKillsAndKarma(targetPlayer.getLevel(), target instanceof L2PcInstance);
  5906. //Unequip adventurer items
  5907. if(getInventory().getPaperdollItemId(7) >= 7816 && getInventory().getPaperdollItemId(7) <= 7831)
  5908. {
  5909. L2ItemInstance invItem = getInventory().getItemByItemId(getInventory().getPaperdollItemId(7));
  5910. if(invItem.isEquipped())
  5911. {
  5912. L2ItemInstance[] unequiped = getInventory().unEquipItemInSlotAndRecord(invItem.getLocationSlot());
  5913. InventoryUpdate iu = new InventoryUpdate();
  5914. for(L2ItemInstance itm: unequiped)
  5915. iu.addModifiedItem(itm);
  5916. sendPacket(iu);
  5917. }
  5918. refreshExpertisePenalty();
  5919. sendPacket(new SystemMessage(SystemMessageId.YOU_ARE_UNABLE_TO_EQUIP_THIS_ITEM_WHEN_YOUR_PK_COUNT_IS_GREATER_THAN_OR_EQUAL_TO_ONE));
  5920. }
  5921. }
  5922. }
  5923. }
  5924.  
  5925. /**
  5926. * Increase the pvp kills count and send the info to the player
  5927. *
  5928. */
  5929. public void increasePvpKills()
  5930. {
  5931. // Add karma to attacker and increase its PK counter
  5932. setPvpKills(getPvpKills() + 1);
  5933.  
  5934. if(Config.ALLOW_COMBO)
  5935. checkCombo();
  5936.  
  5937. PvpClanPoints();
  5938.  
  5939. //Xp & Sp -> PvP
  5940. addExpAndSp(5000, 500000);
  5941. {
  5942. sendMessage("You won 5000 Xp and 500000 Sp from you PvP.");
  5943. }
  5944.  
  5945. //Custom PvP Skills
  5946. if (Config.ALLOW_PVP_SKILLS)
  5947. {
  5948. for (int i : Config.PVP_SKILLS_LIST.keySet())
  5949. {
  5950. if (getPvpKills() == i)
  5951. {
  5952. addSkill(SkillTable.getInstance().getInfo(Config.PVP_SKILLS_LIST.get(i), SkillTable.getInstance().getMaxLevel(Config.PVP_SKILLS_LIST.get(i))), true);
  5953. break;
  5954. }
  5955. }
  5956. }
  5957.  
  5958. //Custom PvP Reward
  5959. if (Config.PVP_ACTIVAR)
  5960. {
  5961. addItem("Loot", Config.PVP_REWARD, Config.PVP_CANTIDAD, this, true);
  5962. }
  5963.  
  5964. if (Config.ALLOW_PVP_TITLE_COLOR_SYSTEM)
  5965. {
  5966. colorsCheck();
  5967. }
  5968.  
  5969. if (Config.ANNOUNS_PVP)
  5970. {
  5971. setPvpKillsAnnoun(getPvpKillsAnnoun() + 1);
  5972. if (Config.ANNOUNS_PVP_AMOUNTS.contains(getPvpKillsAnnoun()))
  5973. {
  5974. Announcements.getInstance().announceToAll(" " + getName() + " Killed consecutive " + getPvpKillsAnnoun() + " Victims ");
  5975. }
  5976. }
  5977.  
  5978. // Send a Server->Client UserInfo packet to attacker with its Karma and PK Counter
  5979. sendPacket(new UserInfo(this));
  5980. sendPacket(new ExBrExtraUserInfo(this));
  5981. }
  5982.  
  5983. private void checkCombo()
  5984. {
  5985. int i = 0;
  5986. combo++;
  5987. int combos = 0;
  5988.  
  5989. if(combo == Config.COMBO1_KILLS)
  5990. {
  5991. i = 1;
  5992. addSkill(SkillTable.getInstance().getInfo(Config.COMBO_SKILL_ID, Config.COMBO1_LEVEL), false);
  5993. combos = Config.COMBO1_KILLS;
  5994. }
  5995. else if(combo == Config.COMBO2_KILLS)
  5996. {
  5997. i = 2;
  5998. addSkill(SkillTable.getInstance().getInfo(Config.COMBO_SKILL_ID, Config.COMBO2_LEVEL), false);
  5999. combos = Config.COMBO2_KILLS;
  6000. }
  6001. else if(combo == Config.COMBO3_KILLS)
  6002. {
  6003. i = 3;
  6004. addSkill(SkillTable.getInstance().getInfo(Config.COMBO_SKILL_ID, Config.COMBO3_LEVEL), false);
  6005. combos = Config.COMBO3_KILLS;
  6006. }
  6007. else if(combo == Config.COMBO4_KILLS)
  6008. {
  6009. i = 4;
  6010. addSkill(SkillTable.getInstance().getInfo(Config.COMBO_SKILL_ID, Config.COMBO4_LEVEL), false);
  6011. combos = Config.COMBO4_KILLS;
  6012. }
  6013.  
  6014. if(i > 0)
  6015. {
  6016. sendMessage("You have been rewarded with a skill.");
  6017. sendMessage("You are in a Combo Mode with " +combos +" pvp kills in a row!");
  6018. }
  6019.  
  6020. i = 0;
  6021. combos = 0;
  6022. }
  6023.  
  6024. private void comboDie(L2Character killer)
  6025. {
  6026. if(combo > Config.COMBO1_KILLS)
  6027. {
  6028. killer.sendMessage("You Have killed "+getName() +" and he lost his combo with "+combo +" kills");
  6029. }
  6030. combo = 0;
  6031. }
  6032.  
  6033. public void PvpClanPoints()
  6034. {
  6035. if (Config.ALLOW_CLP)
  6036. {
  6037. if (isClanLeader() && getClan() != null)
  6038. {
  6039. sendMessage("You just take a pvp,your clan rewarded with" +Config.CP_EVERY_PVP +" clan points");
  6040. getClan().setReputationScore(getClan().getReputationScore()+Config.CP_EVERY_PVP, true);
  6041. }
  6042. }
  6043. }
  6044.  
  6045. /**
  6046. * Increase pk count, karma and send the info to the player
  6047. *
  6048. * @param targLVL : level of the killed player
  6049. * @param increasePk : true if PK counter should be increased too
  6050. */
  6051. public void increasePkKillsAndKarma(int targLVL, boolean increasePk)
  6052. {
  6053. int baseKarma = Config.KARMA_MIN_KARMA;
  6054. int newKarma = baseKarma;
  6055. int karmaLimit = Config.KARMA_MAX_KARMA;
  6056.  
  6057. int pkLVL = getLevel();
  6058. int pkPKCount = getPkKills();
  6059.  
  6060. int lvlDiffMulti = 0;
  6061. int pkCountMulti = 0;
  6062.  
  6063. // Check if the attacker has a PK counter greater than 0
  6064. if ( pkPKCount > 0 )
  6065. pkCountMulti = pkPKCount / 2;
  6066. else
  6067. pkCountMulti = 1;
  6068. if ( pkCountMulti < 1 ) pkCountMulti = 1;
  6069.  
  6070. // Calculate the level difference Multiplier between attacker and killed L2PcInstance
  6071. if ( pkLVL > targLVL )
  6072. lvlDiffMulti = pkLVL / targLVL;
  6073. else
  6074. lvlDiffMulti = 1;
  6075. if ( lvlDiffMulti < 1 ) lvlDiffMulti = 1;
  6076.  
  6077. // Calculate the new Karma of the attacker : newKarma = baseKarma*pkCountMulti*lvlDiffMulti
  6078. newKarma *= pkCountMulti;
  6079. newKarma *= lvlDiffMulti;
  6080.  
  6081. // Make sure newKarma is less than karmaLimit and higher than baseKarma
  6082. if ( newKarma < baseKarma ) newKarma = baseKarma;
  6083. if ( newKarma > karmaLimit ) newKarma = karmaLimit;
  6084.  
  6085. // Fix to prevent overflow (=> karma has a max value of 2 147 483 647)
  6086. if (getKarma() > (Integer.MAX_VALUE - newKarma))
  6087. newKarma = Integer.MAX_VALUE - getKarma();
  6088.  
  6089. // Add karma to attacker and increase its PK counter
  6090. setKarma(getKarma() + newKarma);
  6091. if (increasePk)
  6092. setPkKills(getPkKills() + 1);
  6093.  
  6094. // Delvl Player When they PK Another Player
  6095. getStat().removeExpAndSp((getExp() - Experience.LEVEL[getStat().getLevel() - 1]), 0);
  6096. broadcastKarma();
  6097. sendMessage("You Have Been Delvld for Wrong Actions! You are now level " +getLevel()+ " !");
  6098.  
  6099. // Send a Server->Client UserInfo packet to attacker with its Karma and PK Counter
  6100. sendPacket(new UserInfo(this));
  6101. sendPacket(new ExBrExtraUserInfo(this));
  6102. }
  6103.  
  6104. public int calculateKarmaLost(long exp)
  6105. {
  6106. // KARMA LOSS
  6107. // When a PKer gets killed by another player or a L2MonsterInstance, it loses a certain amount of Karma based on their level.
  6108. // this (with defaults) results in a level 1 losing about ~2 karma per death, and a lvl 70 loses about 11760 karma per death...
  6109. // You lose karma as long as you were not in a pvp zone and you did not kill urself.
  6110. // NOTE: exp for death (if delevel is allowed) is based on the players level
  6111.  
  6112. long expGained = Math.abs(exp);
  6113. expGained /= Config.KARMA_XP_DIVIDER;
  6114.  
  6115. // FIXME Micht : Maybe this code should be fixed and karma set to a long value
  6116. int karmaLost = 0;
  6117. if (expGained > Integer.MAX_VALUE)
  6118. karmaLost = Integer.MAX_VALUE;
  6119. else
  6120. karmaLost = (int)expGained;
  6121.  
  6122. if (karmaLost < Config.KARMA_LOST_BASE) karmaLost = Config.KARMA_LOST_BASE;
  6123. if (karmaLost > getKarma()) karmaLost = getKarma();
  6124.  
  6125. return karmaLost;
  6126. }
  6127.  
  6128. public void updatePvPStatus()
  6129. {
  6130. if (isInsideZone(ZONE_PVP)) return;
  6131. setPvpFlagLasts(System.currentTimeMillis() + Config.PVP_NORMAL_TIME);
  6132.  
  6133. if (getPvpFlag() == 0)
  6134. startPvPFlag();
  6135. }
  6136.  
  6137. public void updatePvPStatus(L2Character target)
  6138. {
  6139. L2PcInstance player_target = target.getActingPlayer();
  6140.  
  6141. if (player_target == null)
  6142. return;
  6143.  
  6144. if ((isInDuel() && player_target.getDuelId() == getDuelId())) return;
  6145. if ((!isInsideZone(ZONE_PVP) || !player_target.isInsideZone(ZONE_PVP)) && player_target.getKarma() == 0)
  6146. {
  6147. if (checkIfPvP(player_target))
  6148. setPvpFlagLasts(System.currentTimeMillis() + Config.PVP_PVP_TIME);
  6149. else
  6150. setPvpFlagLasts(System.currentTimeMillis() + Config.PVP_NORMAL_TIME);
  6151. if (getPvpFlag() == 0)
  6152. startPvPFlag();
  6153. }
  6154. }
  6155.  
  6156. /**
  6157. * Restore the specified % of experience this L2PcInstance has
  6158. * lost and sends a Server->Client StatusUpdate packet.<BR><BR>
  6159. */
  6160. public void restoreExp(double restorePercent)
  6161. {
  6162. if (getExpBeforeDeath() > 0)
  6163. {
  6164. // Restore the specified % of lost experience.
  6165. getStat().addExp((int)Math.round((getExpBeforeDeath() - getExp()) * restorePercent / 100));
  6166. setExpBeforeDeath(0);
  6167. }
  6168. }
  6169.  
  6170. /**
  6171. * Reduce the Experience (and level if necessary) of the L2PcInstance in function of the calculated Death Penalty.<BR><BR>
  6172. *
  6173. * <B><U> Actions</U> :</B><BR><BR>
  6174. * <li>Calculate the Experience loss </li>
  6175. * <li>Set the value of _expBeforeDeath </li>
  6176. * <li>Set the new Experience value of the L2PcInstance and Decrease its level if necessary </li>
  6177. * <li>Send a Server->Client StatusUpdate packet with its new Experience </li><BR><BR>
  6178. *
  6179. */
  6180. public void deathPenalty(boolean atwar, boolean killed_by_pc, boolean killed_by_siege_npc)
  6181. {
  6182. // TODO Need Correct Penalty
  6183. // Get the level of the L2PcInstance
  6184. final int lvl = getLevel();
  6185.  
  6186. byte level = (byte)getLevel();
  6187.  
  6188. int clan_luck = getSkillLevel(L2Skill.SKILL_CLAN_LUCK);
  6189.  
  6190. double clan_luck_modificator = 1.0;
  6191.  
  6192. if (!killed_by_pc)
  6193. {
  6194. switch (clan_luck)
  6195. {
  6196. case 3:
  6197. clan_luck_modificator = 0.8;
  6198. break;
  6199. case 2:
  6200. clan_luck_modificator = 0.8;
  6201. break;
  6202. case 1:
  6203. clan_luck_modificator = 0.88;
  6204. break;
  6205. default:
  6206. clan_luck_modificator = 1.0;
  6207. break;
  6208. }
  6209. }
  6210. else
  6211. {
  6212. switch (clan_luck)
  6213. {
  6214. case 3:
  6215. clan_luck_modificator = 0.5;
  6216. break;
  6217. case 2:
  6218. clan_luck_modificator = 0.5;
  6219. break;
  6220. case 1:
  6221. clan_luck_modificator = 0.5;
  6222. break;
  6223. default:
  6224. clan_luck_modificator = 1.0;
  6225. break;
  6226. }
  6227. }
  6228.  
  6229. //The death steal you some Exp
  6230. double percentLost = Config.PLAYER_XP_PERCENT_LOST[getLevel()]*clan_luck_modificator;
  6231.  
  6232. switch (level)
  6233. {
  6234. case 78:
  6235. percentLost = (1.5*clan_luck_modificator);
  6236. break;
  6237. case 77:
  6238. percentLost = (2.0*clan_luck_modificator);
  6239. break;
  6240. case 76:
  6241. percentLost = (2.5*clan_luck_modificator);
  6242. break;
  6243. default:
  6244. if (level < 40)
  6245. percentLost = (7.0*clan_luck_modificator);
  6246. else if (level >= 40 && level <= 75)
  6247. percentLost = (4.0*clan_luck_modificator);
  6248.  
  6249. break;
  6250. }
  6251.  
  6252. if (getKarma() > 0)
  6253. percentLost *= Config.RATE_KARMA_EXP_LOST;
  6254.  
  6255. if (isFestivalParticipant() || atwar)
  6256. percentLost /= 4.0;
  6257.  
  6258. // Calculate the Experience loss
  6259. long lostExp = 0;
  6260. if (!atEvent)
  6261. if (lvl < Experience.MAX_LEVEL)
  6262. lostExp = Math.round((getStat().getExpForLevel(lvl+1) - getStat().getExpForLevel(lvl)) * percentLost /100);
  6263. else
  6264. lostExp = Math.round((getStat().getExpForLevel(Experience.MAX_LEVEL) - getStat().getExpForLevel(Experience.MAX_LEVEL - 1)) * percentLost /100);
  6265.  
  6266. // Get the Experience before applying penalty
  6267. setExpBeforeDeath(getExp());
  6268.  
  6269. // No xp loss inside pvp zone unless
  6270. // - it's a siege zone and you're NOT participating
  6271. // - you're killed by a non-pc whose not belong to the siege
  6272. if (isInsideZone(ZONE_PVP))
  6273. {
  6274. // No xp loss for siege participants inside siege zone
  6275. if (isInsideZone(ZONE_SIEGE))
  6276. {
  6277. if (isInSiege() && (killed_by_pc || killed_by_siege_npc))
  6278. lostExp = 0;
  6279. }
  6280. else if (killed_by_pc)
  6281. lostExp = 0;
  6282. }
  6283.  
  6284. if (Config.DEBUG)
  6285. _log.fine(getName() + " died and lost " + lostExp + " experience.");
  6286.  
  6287. // Set the new Experience value of the L2PcInstance
  6288. getStat().addExp(-lostExp);
  6289. }
  6290.  
  6291. /**
  6292. * @param b
  6293. */
  6294. public void setPartyMatchingAutomaticRegistration(boolean b)
  6295. {
  6296. _partyMatchingAutomaticRegistration = b;
  6297. }
  6298.  
  6299. /**
  6300. * @param b
  6301. */
  6302. public void setPartyMatchingShowLevel(boolean b)
  6303. {
  6304. _partyMatchingShowLevel = b;
  6305. }
  6306.  
  6307. /**
  6308. * @param b
  6309. */
  6310. public void setPartyMatchingShowClass(boolean b)
  6311. {
  6312. _partyMatchingShowClass = b;
  6313. }
  6314.  
  6315. /**
  6316. * @param memo
  6317. */
  6318. public void setPartyMatchingMemo(String memo)
  6319. {
  6320. _partyMatchingMemo = memo;
  6321. }
  6322.  
  6323. public boolean isPartyMatchingAutomaticRegistration()
  6324. {
  6325. return _partyMatchingAutomaticRegistration;
  6326. }
  6327.  
  6328. public String getPartyMatchingMemo()
  6329. {
  6330. return _partyMatchingMemo;
  6331. }
  6332.  
  6333. public boolean isPartyMatchingShowClass()
  6334. {
  6335. return _partyMatchingShowClass;
  6336. }
  6337.  
  6338. public boolean isPartyMatchingShowLevel()
  6339. {
  6340. return _partyMatchingShowLevel;
  6341. }
  6342.  
  6343. /**
  6344. * Manage the increase level task of a L2PcInstance (Max MP, Max MP, Recommandation, Expertise and beginner skills...).<BR><BR>
  6345. *
  6346. * <B><U> Actions</U> :</B><BR><BR>
  6347. * <li>Send a Server->Client System Message to the L2PcInstance : YOU_INCREASED_YOUR_LEVEL </li>
  6348. * <li>Send a Server->Client packet StatusUpdate to the L2PcInstance with new LEVEL, MAX_HP and MAX_MP </li>
  6349. * <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>
  6350. * <li>Recalculate the party level</li>
  6351. * <li>Recalculate the number of Recommandation that the L2PcInstance can give</li>
  6352. * <li>Give Expertise skill of this level and remove beginner Lucky skill</li><BR><BR>
  6353. *
  6354. */
  6355. public void increaseLevel()
  6356. {
  6357. // 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)
  6358. setCurrentHpMp(getMaxHp(),getMaxMp());
  6359. setCurrentCp(getMaxCp());
  6360. }
  6361.  
  6362. /**
  6363. * Stop the HP/MP/CP Regeneration task.<BR><BR>
  6364. *
  6365. * <B><U> Actions</U> :</B><BR><BR>
  6366. * <li>Set the RegenActive flag to False </li>
  6367. * <li>Stop the HP/MP/CP Regeneration task </li><BR><BR>
  6368. *
  6369. */
  6370. public void stopAllTimers()
  6371. {
  6372. stopHpMpRegeneration();
  6373. stopWarnUserTakeBreak();
  6374. stopWaterTask();
  6375. stopFeed();
  6376. clearPetData();
  6377. storePetFood(_mountNpcId);
  6378. stopRentPet();
  6379. stopPvpRegTask();
  6380. stopPunishTask(true);
  6381. stopSoulTask();
  6382. stopChargeTask();
  6383. stopFameTask();
  6384. stopVitalityTask();
  6385. }
  6386.  
  6387. /**
  6388. * Return the L2Summon of the L2PcInstance or null.<BR><BR>
  6389. */
  6390. @Override
  6391. public L2Summon getPet()
  6392. {
  6393. return _summon;
  6394. }
  6395.  
  6396. /**
  6397. * Return the L2Decoy of the L2PcInstance or null.<BR><BR>
  6398. */
  6399. public L2Decoy getDecoy()
  6400. {
  6401. return _decoy;
  6402. }
  6403.  
  6404. /**
  6405. * Return the L2Trap of the L2PcInstance or null.<BR><BR>
  6406. */
  6407. public L2Trap getTrap()
  6408. {
  6409. return _trap;
  6410. }
  6411.  
  6412. /**
  6413. * Set the L2Summon of the L2PcInstance.<BR><BR>
  6414. */
  6415. public void setPet(L2Summon summon)
  6416. {
  6417. _summon = summon;
  6418. // update attack element value display
  6419. if ((_summon == null || _summon instanceof L2SummonInstance)
  6420. && getClassId().isSummoner() && getAttackElement() != Elementals.NONE)
  6421. sendPacket(new UserInfo(this));
  6422.  
  6423. }
  6424. /**
  6425. * Set the L2Decoy of the L2PcInstance.<BR><BR>
  6426. */
  6427. public void setDecoy(L2Decoy decoy)
  6428. {
  6429. _decoy = decoy;
  6430. }
  6431.  
  6432. /**
  6433. * Set the L2Trap of this L2PcInstance<BR><BR>
  6434. * @param trap
  6435. */
  6436. public void setTrap(L2Trap trap)
  6437. {
  6438. _trap = trap;
  6439. }
  6440.  
  6441. /**
  6442. * Return the L2Summon of the L2PcInstance or null.<BR><BR>
  6443. */
  6444. public L2TamedBeastInstance getTrainedBeast()
  6445. {
  6446. return _tamedBeast;
  6447. }
  6448.  
  6449. /**
  6450. * Set the L2Summon of the L2PcInstance.<BR><BR>
  6451. */
  6452. public void setTrainedBeast(L2TamedBeastInstance tamedBeast)
  6453. {
  6454. _tamedBeast = tamedBeast;
  6455. }
  6456.  
  6457. /**
  6458. * Return the L2PcInstance requester of a transaction (ex : FriendInvite, JoinAlly, JoinParty...).<BR><BR>
  6459. */
  6460. public L2Request getRequest()
  6461. {
  6462. return _request;
  6463. }
  6464.  
  6465. /**
  6466. * Set the L2PcInstance requester of a transaction (ex : FriendInvite, JoinAlly, JoinParty...).<BR><BR>
  6467. */
  6468. public synchronized void setActiveRequester(L2PcInstance requester)
  6469. {
  6470. _activeRequester = requester;
  6471. }
  6472.  
  6473. /**
  6474. * Return the L2PcInstance requester of a transaction (ex : FriendInvite, JoinAlly, JoinParty...).<BR><BR>
  6475. */
  6476. public L2PcInstance getActiveRequester()
  6477. {
  6478. return _activeRequester;
  6479. }
  6480.  
  6481. /**
  6482. * Return True if a transaction is in progress.<BR><BR>
  6483. */
  6484. public boolean isProcessingRequest()
  6485. {
  6486. return _activeRequester != null || _requestExpireTime > GameTimeController.getGameTicks();
  6487. }
  6488.  
  6489. /**
  6490. * Return True if a transaction is in progress.<BR><BR>
  6491. */
  6492. public boolean isProcessingTransaction() { return _activeRequester != null || _activeTradeList != null || _requestExpireTime > GameTimeController.getGameTicks(); }
  6493.  
  6494. /**
  6495. * Select the Warehouse to be used in next activity.<BR><BR>
  6496. */
  6497. public void onTransactionRequest(L2PcInstance partner)
  6498. {
  6499. _requestExpireTime = GameTimeController.getGameTicks() + REQUEST_TIMEOUT * GameTimeController.TICKS_PER_SECOND;
  6500. partner.setActiveRequester(this);
  6501. }
  6502.  
  6503. /**
  6504. * Return true if last request is expired.
  6505. * @return
  6506. */
  6507. public boolean isRequestExpired()
  6508. {
  6509. return !(_requestExpireTime > GameTimeController.getGameTicks());
  6510. }
  6511.  
  6512. /**
  6513. * Select the Warehouse to be used in next activity.<BR><BR>
  6514. */
  6515. public void onTransactionResponse()
  6516. {
  6517. _requestExpireTime = 0;
  6518. }
  6519.  
  6520. /**
  6521. * Select the Warehouse to be used in next activity.<BR><BR>
  6522. */
  6523. public void setActiveWarehouse(ItemContainer warehouse)
  6524. {
  6525. _activeWarehouse = warehouse;
  6526. }
  6527.  
  6528. /**
  6529. * Return active Warehouse.<BR><BR>
  6530. */
  6531. public ItemContainer getActiveWarehouse()
  6532. {
  6533. return _activeWarehouse;
  6534. }
  6535.  
  6536. /**
  6537. * Select the TradeList to be used in next activity.<BR><BR>
  6538. */
  6539. public void setActiveTradeList(TradeList tradeList)
  6540. {
  6541. _activeTradeList = tradeList;
  6542. }
  6543.  
  6544. /**
  6545. * Return active TradeList.<BR><BR>
  6546. */
  6547. public TradeList getActiveTradeList()
  6548. {
  6549. return _activeTradeList;
  6550. }
  6551.  
  6552. public void onTradeStart(L2PcInstance partner)
  6553. {
  6554. _activeTradeList = new TradeList(this);
  6555. _activeTradeList.setPartner(partner);
  6556.  
  6557. SystemMessage msg = new SystemMessage(SystemMessageId.BEGIN_TRADE_WITH_C1);
  6558. msg.addPcName(partner);
  6559. sendPacket(msg);
  6560. sendPacket(new TradeStart(this));
  6561. }
  6562.  
  6563. public void onTradeConfirm(L2PcInstance partner)
  6564. {
  6565. SystemMessage msg = new SystemMessage(SystemMessageId.C1_CONFIRMED_TRADE);
  6566. msg.addPcName(partner);
  6567. sendPacket(msg);
  6568. sendPacket(new TradeOtherDone());
  6569. }
  6570.  
  6571. public void onTradeCancel(L2PcInstance partner)
  6572. {
  6573. if (_activeTradeList == null)
  6574. return;
  6575.  
  6576. _activeTradeList.lock();
  6577. _activeTradeList = null;
  6578.  
  6579. sendPacket(new TradeDone(0));
  6580. SystemMessage msg = new SystemMessage(SystemMessageId.C1_CANCELED_TRADE);
  6581. msg.addPcName(partner);
  6582. sendPacket(msg);
  6583. }
  6584.  
  6585. public void onTradeFinish(boolean successfull)
  6586. {
  6587. _activeTradeList = null;
  6588. sendPacket(new TradeDone(1));
  6589. if (successfull)
  6590. sendPacket(new SystemMessage(SystemMessageId.TRADE_SUCCESSFUL));
  6591. }
  6592.  
  6593. public void startTrade(L2PcInstance partner)
  6594. {
  6595. onTradeStart(partner);
  6596. partner.onTradeStart(this);
  6597. }
  6598.  
  6599. public void cancelActiveTrade()
  6600. {
  6601. if (_activeTradeList == null)
  6602. return;
  6603.  
  6604. L2PcInstance partner = _activeTradeList.getPartner();
  6605. if (partner != null) partner.onTradeCancel(this);
  6606. onTradeCancel(this);
  6607. }
  6608.  
  6609. /**
  6610. * Return the _createList object of the L2PcInstance.<BR><BR>
  6611. */
  6612. public L2ManufactureList getCreateList()
  6613. {
  6614. return _createList;
  6615. }
  6616.  
  6617. /**
  6618. * Set the _createList object of the L2PcInstance.<BR><BR>
  6619. */
  6620. public void setCreateList(L2ManufactureList x)
  6621. {
  6622. _createList = x;
  6623. }
  6624.  
  6625. /**
  6626. * Return the _buyList object of the L2PcInstance.<BR><BR>
  6627. */
  6628. public TradeList getSellList()
  6629. {
  6630. if (_sellList == null) _sellList = new TradeList(this);
  6631. return _sellList;
  6632. }
  6633.  
  6634. /**
  6635. * Return the _buyList object of the L2PcInstance.<BR><BR>
  6636. */
  6637. public TradeList getBuyList()
  6638. {
  6639. if (_buyList == null) _buyList = new TradeList(this);
  6640. return _buyList;
  6641. }
  6642.  
  6643. /**
  6644. * Set the Private Store type of the L2PcInstance.<BR><BR>
  6645. *
  6646. * <B><U> Values </U> :</B><BR><BR>
  6647. * <li>0 : STORE_PRIVATE_NONE</li>
  6648. * <li>1 : STORE_PRIVATE_SELL</li>
  6649. * <li>2 : sellmanage</li><BR>
  6650. * <li>3 : STORE_PRIVATE_BUY</li><BR>
  6651. * <li>4 : buymanage</li><BR>
  6652. * <li>5 : STORE_PRIVATE_MANUFACTURE</li><BR>
  6653. *
  6654. */
  6655. public void setPrivateStoreType(int type)
  6656. {
  6657. _privatestore = type;
  6658. }
  6659.  
  6660. /**
  6661. * Return the Private Store type of the L2PcInstance.<BR><BR>
  6662. *
  6663. * <B><U> Values </U> :</B><BR><BR>
  6664. * <li>0 : STORE_PRIVATE_NONE</li>
  6665. * <li>1 : STORE_PRIVATE_SELL</li>
  6666. * <li>2 : sellmanage</li><BR>
  6667. * <li>3 : STORE_PRIVATE_BUY</li><BR>
  6668. * <li>4 : buymanage</li><BR>
  6669. * <li>5 : STORE_PRIVATE_MANUFACTURE</li><BR>
  6670. *
  6671. */
  6672. public int getPrivateStoreType()
  6673. {
  6674. return _privatestore;
  6675. }
  6676.  
  6677. /**
  6678. * Set the _skillLearningClassId object of the L2PcInstance.<BR><BR>
  6679. */
  6680. public void setSkillLearningClassId(ClassId classId)
  6681. {
  6682. _skillLearningClassId = classId;
  6683. }
  6684.  
  6685. /**
  6686. * Return the _skillLearningClassId object of the L2PcInstance.<BR><BR>
  6687. */
  6688. public ClassId getSkillLearningClassId()
  6689. {
  6690. return _skillLearningClassId;
  6691. }
  6692.  
  6693. /**
  6694. * Set the _clan object, _clanId, _clanLeader Flag and title of the L2PcInstance.<BR><BR>
  6695. */
  6696. public void setClan(L2Clan clan)
  6697. {
  6698. _clan = clan;
  6699. setTitle("");
  6700.  
  6701. if (clan == null)
  6702. {
  6703. _clanId = 0;
  6704. _clanPrivileges = 0;
  6705. _pledgeType = 0;
  6706. _powerGrade = 0;
  6707. _lvlJoinedAcademy = 0;
  6708. _apprentice = 0;
  6709. _sponsor = 0;
  6710. return;
  6711. }
  6712.  
  6713. if (!clan.isMember(getObjectId()))
  6714. {
  6715. // char has been kicked from clan
  6716. setClan(null);
  6717. return;
  6718. }
  6719.  
  6720. _clanId = clan.getClanId();
  6721. }
  6722.  
  6723. /**
  6724. * Return the _clan object of the L2PcInstance.<BR><BR>
  6725. */
  6726. public L2Clan getClan()
  6727. {
  6728. return _clan;
  6729. }
  6730.  
  6731. /**
  6732. * Return True if the L2PcInstance is the leader of its clan.<BR><BR>
  6733. */
  6734. public boolean isClanLeader()
  6735. {
  6736. if (getClan() == null)
  6737. {
  6738. return false;
  6739. }
  6740. else
  6741. {
  6742. return getObjectId() == getClan().getLeaderId();
  6743. }
  6744. }
  6745.  
  6746. /**
  6747. * Reduce the number of arrows/bolts owned by the L2PcInstance and send it Server->Client Packet InventoryUpdate or ItemList (to unequip if the last arrow was consummed).<BR><BR>
  6748. */
  6749. @Override
  6750. protected void reduceArrowCount(boolean bolts)
  6751. {
  6752. L2ItemInstance arrows = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
  6753.  
  6754. if (arrows == null)
  6755. {
  6756. getInventory().unEquipItemInSlot(Inventory.PAPERDOLL_LHAND);
  6757. if (bolts)
  6758. _boltItem = null;
  6759. else
  6760. _arrowItem = null;
  6761. sendPacket(new ItemList(this,false));
  6762. return;
  6763. }
  6764.  
  6765. // Adjust item quantity
  6766. if (arrows.getCount() > 1)
  6767. {
  6768. synchronized(arrows)
  6769. {
  6770. arrows.changeCountWithoutTrace(-1, this, null);
  6771. arrows.setLastChange(L2ItemInstance.MODIFIED);
  6772.  
  6773. // could do also without saving, but let's save approx 1 of 10
  6774. if(GameTimeController.getGameTicks() % 10 == 0)
  6775. arrows.updateDatabase();
  6776. _inventory.refreshWeight();
  6777. }
  6778. }
  6779. else
  6780. {
  6781. // Destroy entire item and save to database
  6782. _inventory.destroyItem("Consume", arrows, this, null);
  6783.  
  6784. getInventory().unEquipItemInSlot(Inventory.PAPERDOLL_LHAND);
  6785. if (bolts)
  6786. _boltItem = null;
  6787. else
  6788. _arrowItem = null;
  6789.  
  6790. if (Config.DEBUG) _log.fine("removed arrows count");
  6791. sendPacket(new ItemList(this,false));
  6792. return;
  6793. }
  6794.  
  6795. if (!Config.FORCE_INVENTORY_UPDATE)
  6796. {
  6797. InventoryUpdate iu = new InventoryUpdate();
  6798. iu.addModifiedItem(arrows);
  6799. sendPacket(iu);
  6800. }
  6801. else sendPacket(new ItemList(this, false));
  6802. }
  6803.  
  6804. /**
  6805. * Equip arrows needed in left hand and send a Server->Client packet ItemList to the L2PcINstance then return True.<BR><BR>
  6806. */
  6807. @Override
  6808. protected boolean checkAndEquipArrows()
  6809. {
  6810. // Check if nothing is equiped in left hand
  6811. if (getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND) == null)
  6812. {
  6813. // Get the L2ItemInstance of the arrows needed for this bow
  6814. _arrowItem = getInventory().findArrowForBow(getActiveWeaponItem());
  6815.  
  6816. if (_arrowItem != null)
  6817. {
  6818. // Equip arrows needed in left hand
  6819. getInventory().setPaperdollItem(Inventory.PAPERDOLL_LHAND, _arrowItem);
  6820.  
  6821. // Send a Server->Client packet ItemList to this L2PcINstance to update left hand equipement
  6822. ItemList il = new ItemList(this, false);
  6823. sendPacket(il);
  6824. }
  6825. }
  6826. else
  6827. {
  6828. // Get the L2ItemInstance of arrows equiped in left hand
  6829. _arrowItem = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
  6830. }
  6831.  
  6832. return _arrowItem != null;
  6833. }
  6834.  
  6835. /**
  6836. * Equip bolts needed in left hand and send a Server->Client packet ItemList to the L2PcINstance then return True.<BR><BR>
  6837. */
  6838. @Override
  6839. protected boolean checkAndEquipBolts()
  6840. {
  6841. // Check if nothing is equiped in left hand
  6842. if (getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND) == null)
  6843. {
  6844. // Get the L2ItemInstance of the arrows needed for this bow
  6845. _boltItem = getInventory().findBoltForCrossBow(getActiveWeaponItem());
  6846.  
  6847. if (_boltItem != null)
  6848. {
  6849. // Equip arrows needed in left hand
  6850. getInventory().setPaperdollItem(Inventory.PAPERDOLL_LHAND, _boltItem);
  6851.  
  6852. // Send a Server->Client packet ItemList to this L2PcINstance to update left hand equipement
  6853. ItemList il = new ItemList(this, false);
  6854. sendPacket(il);
  6855. }
  6856. }
  6857. else
  6858. {
  6859. // Get the L2ItemInstance of arrows equiped in left hand
  6860. _boltItem = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
  6861. }
  6862.  
  6863. return _boltItem != null;
  6864. }
  6865. /**
  6866. * Disarm the player's weapon.<BR><BR>
  6867. */
  6868. public boolean disarmWeapons()
  6869. {
  6870. // Don't allow disarming a cursed weapon
  6871. if (isCursedWeaponEquipped()) return false;
  6872.  
  6873. // Unequip the weapon
  6874. L2ItemInstance wpn = getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
  6875. if (wpn == null) wpn = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LRHAND);
  6876. if (wpn != null)
  6877. {
  6878. if (wpn.isWear())
  6879. return false;
  6880.  
  6881. L2ItemInstance[] unequiped = getInventory().unEquipItemInBodySlotAndRecord(wpn.getItem().getBodyPart());
  6882. InventoryUpdate iu = new InventoryUpdate();
  6883. for (L2ItemInstance itm: unequiped)
  6884. iu.addModifiedItem(itm);
  6885. sendPacket(iu);
  6886.  
  6887. abortAttack();
  6888. broadcastUserInfo();
  6889.  
  6890. // this can be 0 if the user pressed the right mousebutton twice very fast
  6891. if (unequiped.length > 0)
  6892. {
  6893. SystemMessage sm = null;
  6894. if (unequiped[0].getEnchantLevel() > 0)
  6895. {
  6896. sm = new SystemMessage(SystemMessageId.EQUIPMENT_S1_S2_REMOVED);
  6897. sm.addNumber(unequiped[0].getEnchantLevel());
  6898. sm.addItemName(unequiped[0]);
  6899. }
  6900. else
  6901. {
  6902. sm = new SystemMessage(SystemMessageId.S1_DISARMED);
  6903. sm.addItemName(unequiped[0]);
  6904. }
  6905. sendPacket(sm);
  6906. }
  6907. }
  6908. return true;
  6909. }
  6910.  
  6911. /**
  6912. * Disarm the player's shield.<BR><BR>
  6913. */
  6914. public boolean disarmShield()
  6915. {
  6916. L2ItemInstance sld = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
  6917. if (sld != null)
  6918. {
  6919. if (sld.isWear())
  6920. return false;
  6921.  
  6922. L2ItemInstance[] unequiped = getInventory().unEquipItemInBodySlotAndRecord(sld.getItem().getBodyPart());
  6923. InventoryUpdate iu = new InventoryUpdate();
  6924. for (L2ItemInstance itm: unequiped)
  6925. iu.addModifiedItem(itm);
  6926. sendPacket(iu);
  6927.  
  6928. abortAttack();
  6929. broadcastUserInfo();
  6930.  
  6931. // this can be 0 if the user pressed the right mousebutton twice very fast
  6932. if (unequiped.length > 0)
  6933. {
  6934. SystemMessage sm = null;
  6935. if (unequiped[0].getEnchantLevel() > 0)
  6936. {
  6937. sm = new SystemMessage(SystemMessageId.EQUIPMENT_S1_S2_REMOVED);
  6938. sm.addNumber(unequiped[0].getEnchantLevel());
  6939. sm.addItemName(unequiped[0]);
  6940. }
  6941. else
  6942. {
  6943. sm = new SystemMessage(SystemMessageId.S1_DISARMED);
  6944. sm.addItemName(unequiped[0]);
  6945. }
  6946. sendPacket(sm);
  6947. }
  6948. }
  6949. return true;
  6950. }
  6951.  
  6952. public boolean mount(L2Summon pet)
  6953. {
  6954. if (!disarmWeapons())
  6955. return false;
  6956. if (!disarmShield())
  6957. return false;
  6958. if (isTransformed())
  6959. return false;
  6960.  
  6961. for (L2Effect e : getAllEffects())
  6962. {
  6963. if (e != null && e.getSkill().isToggle())
  6964. e.exit();
  6965. }
  6966. Ride mount = new Ride(this, true, pet.getTemplate().npcId);
  6967. setMount(pet.getNpcId(), pet.getLevel(), mount.getMountType());
  6968. setMountObjectID(pet.getControlItemId());
  6969. clearPetData();
  6970. startFeed(pet.getNpcId());
  6971. broadcastPacket(mount);
  6972.  
  6973. // Notify self and others about speed change
  6974. broadcastUserInfo();
  6975.  
  6976. pet.unSummon(this);
  6977.  
  6978. return true;
  6979. }
  6980.  
  6981. public boolean mount(int npcId, int controlItemObjId,boolean useFood)
  6982. {
  6983. if (!disarmWeapons())
  6984. return false;
  6985. if (!disarmShield())
  6986. return false;
  6987. if (isTransformed())
  6988. return false;
  6989.  
  6990. for (L2Effect e : getAllEffects())
  6991. {
  6992. if (e != null && e.getSkill().isToggle())
  6993. e.exit();
  6994. }
  6995. Ride mount = new Ride(this, true, npcId);
  6996. if (setMount(npcId, getLevel(), mount.getMountType()))
  6997. {
  6998. clearPetData();
  6999. setMountObjectID(controlItemObjId);
  7000. broadcastPacket(mount);
  7001.  
  7002. // Notify self and others about speed change
  7003. broadcastUserInfo();
  7004. if (useFood)
  7005. startFeed(npcId);
  7006. return true;
  7007. }
  7008. return false;
  7009. }
  7010.  
  7011. public boolean mountPlayer(L2Summon pet)
  7012. {
  7013. if (pet != null && pet.isMountable() && !isMounted() && !isBetrayed())
  7014. {
  7015. if (isDead())
  7016. {
  7017. //A strider cannot be ridden when dead
  7018. sendPacket(ActionFailed.STATIC_PACKET);
  7019. sendPacket(new SystemMessage(SystemMessageId.STRIDER_CANT_BE_RIDDEN_WHILE_DEAD));
  7020. return false;
  7021. }
  7022. else if (pet.isDead())
  7023. {
  7024. //A dead strider cannot be ridden.
  7025. sendPacket(ActionFailed.STATIC_PACKET);
  7026. sendPacket(new SystemMessage(SystemMessageId.DEAD_STRIDER_CANT_BE_RIDDEN));
  7027. return false;
  7028. }
  7029. else if (pet.isInCombat() || pet.isRooted())
  7030. {
  7031. //A strider in battle cannot be ridden
  7032. sendPacket(ActionFailed.STATIC_PACKET);
  7033. sendPacket(new SystemMessage(SystemMessageId.STRIDER_IN_BATLLE_CANT_BE_RIDDEN));
  7034. return false;
  7035.  
  7036. }
  7037. else if (isInCombat())
  7038. {
  7039. //A strider cannot be ridden while in battle
  7040. sendPacket(ActionFailed.STATIC_PACKET);
  7041. sendPacket(new SystemMessage(SystemMessageId.STRIDER_CANT_BE_RIDDEN_WHILE_IN_BATTLE));
  7042. return false;
  7043. }
  7044. else if (isSitting())
  7045. {
  7046. //A strider can be ridden only when standing
  7047. sendPacket(ActionFailed.STATIC_PACKET);
  7048. sendPacket(new SystemMessage(SystemMessageId.STRIDER_CAN_BE_RIDDEN_ONLY_WHILE_STANDING));
  7049. return false;
  7050. }
  7051. else if (isFishing())
  7052. {
  7053. //You can't mount, dismount, break and drop items while fishing
  7054. sendPacket(ActionFailed.STATIC_PACKET);
  7055. sendPacket(new SystemMessage(SystemMessageId.CANNOT_DO_WHILE_FISHING_2));
  7056. return false;
  7057. }
  7058. else if (isTransformed() || isCursedWeaponEquipped())
  7059. {
  7060. // no message needed, player while transformed doesn't have mount action
  7061. sendPacket(ActionFailed.STATIC_PACKET);
  7062. return false;
  7063. }
  7064. else if (getInventory().getItemByItemId(9819) != null)
  7065. {
  7066. sendPacket(ActionFailed.STATIC_PACKET);
  7067. sendPacket(new SystemMessage(SystemMessageId.YOU_CANNOT_MOUNT_A_STEED_WHILE_HOLDING_A_FLAG)); // TODO: confirm this message
  7068. return false;
  7069. }
  7070. else if (pet.isHungry())
  7071. {
  7072. sendPacket(ActionFailed.STATIC_PACKET);
  7073. sendPacket(new SystemMessage(SystemMessageId.HUNGRY_STRIDER_NOT_MOUNT));
  7074. return false;
  7075. }
  7076. else if (!Util.checkIfInRange(200, this, pet, true))
  7077. {
  7078. sendPacket(ActionFailed.STATIC_PACKET);
  7079. sendPacket(new SystemMessage(SystemMessageId.TOO_FAR_AWAY_FROM_FENRIR_TO_MOUNT));
  7080. return false;
  7081. }
  7082. else if (!pet.isDead() && !isMounted())
  7083. {
  7084. mount(pet);
  7085. }
  7086. }
  7087. else if (isRentedPet())
  7088. {
  7089. stopRentPet();
  7090. }
  7091. else if (isMounted())
  7092. {
  7093. if (getMountType() == 2 && this.isInsideZone(L2Character.ZONE_NOLANDING))
  7094. {
  7095. sendPacket(ActionFailed.STATIC_PACKET);
  7096. sendPacket(new SystemMessage(SystemMessageId.NO_DISMOUNT_HERE));
  7097. return false;
  7098. }
  7099. else if (isHungry())
  7100. {
  7101. sendPacket(ActionFailed.STATIC_PACKET);
  7102. sendPacket(new SystemMessage(SystemMessageId.HUNGRY_STRIDER_NOT_MOUNT));
  7103. return false;
  7104. }
  7105. else
  7106. dismount();
  7107. }
  7108. return true;
  7109. }
  7110.  
  7111. public boolean dismount()
  7112. {
  7113. boolean wasFlying = isFlying();
  7114.  
  7115. sendPacket(new SetupGauge(3, 0, 0));
  7116. int petId = _mountNpcId;
  7117. if (setMount(0, 0, 0))
  7118. {
  7119. stopFeed();
  7120. clearPetData();
  7121. if (wasFlying)
  7122. removeSkill(SkillTable.getInstance().getInfo(4289, 1));
  7123. Ride dismount = new Ride(this, false, 0);
  7124. broadcastPacket(dismount);
  7125. setMountObjectID(0);
  7126. storePetFood(petId);
  7127. // Notify self and others about speed change
  7128. this.broadcastUserInfo();
  7129. return true;
  7130. }
  7131. return false;
  7132. }
  7133.  
  7134. /**
  7135. * Return True if the L2PcInstance use a dual weapon.<BR><BR>
  7136. */
  7137. @Override
  7138. public boolean isUsingDualWeapon()
  7139. {
  7140. L2Weapon weaponItem = getActiveWeaponItem();
  7141. if (weaponItem == null) return false;
  7142.  
  7143. if (weaponItem.getItemType() == L2WeaponType.DUAL)
  7144. return true;
  7145. else if (weaponItem.getItemType() == L2WeaponType.DUALFIST)
  7146. return true;
  7147. else if (weaponItem.getItemId() == 248) // orc fighter fists
  7148. return true;
  7149. else if (weaponItem.getItemId() == 252) // orc mage fists
  7150. return true;
  7151. else
  7152. return false;
  7153. }
  7154.  
  7155. public void setUptime(long time)
  7156. {
  7157. _uptime = time;
  7158. }
  7159.  
  7160. public long getUptime()
  7161. {
  7162. return System.currentTimeMillis()-_uptime;
  7163. }
  7164.  
  7165. /**
  7166. * Return True if the L2PcInstance is invulnerable.<BR><BR>
  7167. */
  7168. @Override
  7169. public boolean isInvul()
  7170. {
  7171. return _isInvul || _isTeleporting || _protectEndTime > GameTimeController.getGameTicks();
  7172. }
  7173.  
  7174. /**
  7175. * Return True if the L2PcInstance has a Party in progress.<BR><BR>
  7176. */
  7177. @Override
  7178. public boolean isInParty()
  7179. {
  7180. return _party != null;
  7181. }
  7182.  
  7183. /**
  7184. * Set the _party object of the L2PcInstance (without joining it).<BR><BR>
  7185. */
  7186. public void setParty(L2Party party)
  7187. {
  7188. _party = party;
  7189. }
  7190.  
  7191. /**
  7192. * Set the _party object of the L2PcInstance AND join it.<BR><BR>
  7193. */
  7194. public void joinParty(L2Party party)
  7195. {
  7196. if (party != null)
  7197. {
  7198. // First set the party otherwise this wouldn't be considered
  7199. // as in a party into the L2Character.updateEffectIcons() call.
  7200. _party = party;
  7201. party.addPartyMember(this);
  7202. }
  7203. }
  7204.  
  7205.  
  7206. /**
  7207. * Manage the Leave Party task of the L2PcInstance.<BR><BR>
  7208. */
  7209. public void leaveParty()
  7210. {
  7211. if (isInParty())
  7212. {
  7213. _party.removePartyMember(this);
  7214. _party = null;
  7215. }
  7216. }
  7217.  
  7218. /**
  7219. * Return the _party object of the L2PcInstance.<BR><BR>
  7220. */
  7221. @Override
  7222. public L2Party getParty()
  7223. {
  7224. return _party;
  7225. }
  7226.  
  7227. /**
  7228. * Return True if the L2PcInstance is a GM.<BR><BR>
  7229. */
  7230. public boolean isGM()
  7231. {
  7232. return getAccessLevel().isGm();
  7233. }
  7234.  
  7235. /**
  7236. * Set the _accessLevel of the L2PcInstance.<BR><BR>
  7237. */
  7238. public void setAccessLevel(int level)
  7239. {
  7240. if (level == AccessLevels._masterAccessLevelNum)
  7241. {
  7242. _log.warning( "Master access level set for character " + getName() + "! Just a warning to be careful ;)" );
  7243. _accessLevel = AccessLevels._masterAccessLevel;
  7244. }
  7245. else if (level == AccessLevels._userAccessLevelNum)
  7246. _accessLevel = AccessLevels._userAccessLevel;
  7247. else
  7248. {
  7249. L2AccessLevel accessLevel = AccessLevels.getInstance().getAccessLevel(level);
  7250.  
  7251. if (accessLevel == null)
  7252. {
  7253. if (level < 0)
  7254. {
  7255. AccessLevels.getInstance().addBanAccessLevel(level);
  7256. _accessLevel = AccessLevels.getInstance().getAccessLevel(level);
  7257. }
  7258. else
  7259. {
  7260. _log.warning( "Tryed to set unregistered access level " + level + " to character " + getName() + ". Setting access level without privileges!" );
  7261. _accessLevel = AccessLevels._userAccessLevel;
  7262. }
  7263. }
  7264. else
  7265. _accessLevel = accessLevel;
  7266. }
  7267.  
  7268. if (_accessLevel != AccessLevels._userAccessLevel)
  7269. {
  7270. getAppearance().setNameColor(_accessLevel.getNameColor());
  7271. getAppearance().setTitleColor(_accessLevel.getTitleColor());
  7272. broadcastUserInfo();
  7273. }
  7274. }
  7275.  
  7276. public void setAccountAccesslevel(int level)
  7277. {
  7278. LoginServerThread.getInstance().sendAccessLevel(getAccountName(),level);
  7279. }
  7280.  
  7281. /**
  7282. * Return the _accessLevel of the L2PcInstance.<BR><BR>
  7283. */
  7284. public L2AccessLevel getAccessLevel()
  7285. {
  7286. if (Config.EVERYBODY_HAS_ADMIN_RIGHTS)
  7287. return AccessLevels._masterAccessLevel;
  7288. else if ( _accessLevel == null ) /* This is here because inventory etc. is loaded before access level on login, so it is not null */
  7289. setAccessLevel(AccessLevels._userAccessLevelNum);
  7290.  
  7291. return _accessLevel;
  7292. }
  7293.  
  7294. @Override
  7295. public double getLevelMod()
  7296. {
  7297. return (100.0 - 11 + getLevel()) / 100.0;
  7298. }
  7299.  
  7300. /**
  7301. * 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>
  7302. */
  7303. public void updateAndBroadcastStatus(int broadcastType)
  7304. {
  7305. refreshOverloaded();
  7306. refreshExpertisePenalty();
  7307. // Send a Server->Client packet UserInfo to this L2PcInstance and CharInfo to all L2PcInstance in its _KnownPlayers (broadcast)
  7308. if (broadcastType == 1)
  7309. {
  7310. sendPacket(new UserInfo(this));
  7311. sendPacket(new ExBrExtraUserInfo(this));
  7312. }
  7313. if (broadcastType == 2) broadcastUserInfo();
  7314. }
  7315.  
  7316. /**
  7317. * Send a Server->Client StatusUpdate packet with Karma and PvP Flag to the L2PcInstance and all L2PcInstance to inform (broadcast).<BR><BR>
  7318. */
  7319. public void setKarmaFlag(int flag)
  7320. {
  7321. sendPacket(new UserInfo(this));
  7322. sendPacket(new ExBrExtraUserInfo(this));
  7323. Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
  7324. //synchronized (getKnownList().getKnownPlayers())
  7325. {
  7326. for (L2PcInstance player : plrs)
  7327. {
  7328. player.sendPacket(new RelationChanged(this, getRelation(player), isAutoAttackable(player)));
  7329. if (getPet() != null)
  7330. player.sendPacket(new RelationChanged(getPet(), getRelation(player), isAutoAttackable(player)));
  7331. }
  7332. }
  7333. }
  7334.  
  7335. /**
  7336. * Send a Server->Client StatusUpdate packet with Karma to the L2PcInstance and all L2PcInstance to inform (broadcast).<BR><BR>
  7337. */
  7338. public void broadcastKarma()
  7339. {
  7340. StatusUpdate su = new StatusUpdate(getObjectId());
  7341. su.addAttribute(StatusUpdate.KARMA, getKarma());
  7342. sendPacket(su);
  7343.  
  7344. Collection<L2PcInstance> plrs = getKnownList().getKnownPlayers().values();
  7345. //synchronized (getKnownList().getKnownPlayers())
  7346. {
  7347. for (L2PcInstance player : plrs)
  7348. {
  7349. player.sendPacket(new RelationChanged(this, getRelation(player), isAutoAttackable(player)));
  7350. if (getPet() != null)
  7351. player.sendPacket(new RelationChanged(getPet(), getRelation(player), isAutoAttackable(player)));
  7352. }
  7353. }
  7354. }
  7355.  
  7356. /**
  7357. * 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>
  7358. */
  7359. public void setOnlineStatus(boolean isOnline)
  7360. {
  7361. if (_isOnline != isOnline)
  7362. _isOnline = isOnline;
  7363.  
  7364. // Update the characters table of the database with online status and lastAccess (called when login and logout)
  7365. updateOnlineStatus();
  7366. }
  7367.  
  7368. public void setIsIn7sDungeon(boolean isIn7sDungeon)
  7369. {
  7370. _isIn7sDungeon = isIn7sDungeon;
  7371. }
  7372.  
  7373. /**
  7374. * Update the characters table of the database with online status and lastAccess of this L2PcInstance (called when login and logout).<BR><BR>
  7375. */
  7376. public void updateOnlineStatus()
  7377. {
  7378. Connection con = null;
  7379. try
  7380. {
  7381. con = L2DatabaseFactory.getInstance().getConnection();
  7382. PreparedStatement statement = con.prepareStatement("UPDATE characters SET online=?, lastAccess=? WHERE charId=?");
  7383. statement.setInt(1, isOnline());
  7384. statement.setLong(2, System.currentTimeMillis());
  7385. statement.setInt(3, getObjectId());
  7386. statement.execute();
  7387. statement.close();
  7388. }
  7389. catch (Exception e)
  7390. {
  7391. _log.log(Level.SEVERE, "Failed updating character online status.", e);
  7392. }
  7393. finally
  7394. {
  7395. try { con.close(); } catch (Exception e) {}
  7396. }
  7397. }
  7398.  
  7399. /**
  7400. * Create a new player in the characters table of the database.<BR><BR>
  7401. */
  7402. private boolean createDb()
  7403. {
  7404. Connection con = null;
  7405. try
  7406. {
  7407. con = L2DatabaseFactory.getInstance().getConnection();
  7408. PreparedStatement statement = con.prepareStatement(INSERT_CHARACTER);
  7409.  
  7410. statement.setString(1, _accountName);
  7411. statement.setInt(2, getObjectId());
  7412. statement.setString(3, getName());
  7413. statement.setInt(4, getLevel());
  7414. statement.setInt(5, getMaxHp());
  7415. statement.setDouble(6, getCurrentHp());
  7416. statement.setInt(7, getMaxCp());
  7417. statement.setDouble(8, getCurrentCp());
  7418. statement.setInt(9, getMaxMp());
  7419. statement.setDouble(10, getCurrentMp());
  7420. statement.setInt(11, getAppearance().getFace());
  7421. statement.setInt(12, getAppearance().getHairStyle());
  7422. statement.setInt(13, getAppearance().getHairColor());
  7423. statement.setInt(14, getAppearance().getSex()? 1 : 0);
  7424. statement.setLong(15, getExp());
  7425. statement.setInt(16, getSp());
  7426. statement.setInt(17, getKarma());
  7427. statement.setInt(18, getFame());
  7428. statement.setInt(19, getPvpKills());
  7429. statement.setInt(20, getPkKills());
  7430. statement.setInt(21, getClanId());
  7431. statement.setInt(22, getRace().ordinal());
  7432. statement.setInt(23, getClassId().getId());
  7433. statement.setLong(24, getDeleteTimer());
  7434. statement.setInt(25, hasDwarvenCraft() ? 1 : 0);
  7435. statement.setString(26, getTitle());
  7436. statement.setInt(27, getAccessLevel().getLevel());
  7437. statement.setInt(28, isOnline());
  7438. statement.setInt(29, isIn7sDungeon() ? 1 : 0);
  7439. statement.setInt(30, getClanPrivileges());
  7440. statement.setInt(31, getWantsPeace());
  7441. statement.setInt(32, getBaseClass());
  7442. statement.setInt(33, getNewbie());
  7443. statement.setInt(34, isNoble() ? 1 :0);
  7444. statement.setLong(35, 0);
  7445. statement.setLong(36,System.currentTimeMillis());
  7446.  
  7447. statement.executeUpdate();
  7448. statement.close();
  7449. }
  7450. catch (Exception e)
  7451. {
  7452. _log.severe("Could not insert char data: " + e);
  7453. return false;
  7454. }
  7455. finally
  7456. {
  7457. try { con.close(); } catch (Exception e) {}
  7458. }
  7459. return true;
  7460. }
  7461.  
  7462. /**
  7463. * Retrieve a L2PcInstance from the characters table of the database and add it in _allObjects of the L2world.<BR><BR>
  7464. *
  7465. * <B><U> Actions</U> :</B><BR><BR>
  7466. * <li>Retrieve the L2PcInstance from the characters table of the database </li>
  7467. * <li>Add the L2PcInstance object in _allObjects </li>
  7468. * <li>Set the x,y,z position of the L2PcInstance and make it invisible</li>
  7469. * <li>Update the overloaded status of the L2PcInstance</li><BR><BR>
  7470. *
  7471. * @param objectId Identifier of the object to initialized
  7472. *
  7473. * @return The L2PcInstance loaded from the database
  7474. *
  7475. */
  7476. private static L2PcInstance restore(int objectId)
  7477. {
  7478. L2PcInstance player = null;
  7479. Connection con = null;
  7480.  
  7481. try
  7482. {
  7483. // Retrieve the L2PcInstance from the characters table of the database
  7484. con = L2DatabaseFactory.getInstance().getConnection();
  7485.  
  7486. PreparedStatement statement = con.prepareStatement(RESTORE_CHARACTER);
  7487. statement.setInt(1, objectId);
  7488. ResultSet rset = statement.executeQuery();
  7489.  
  7490. double currentCp = 0;
  7491. double currentHp = 0;
  7492. double currentMp = 0;
  7493.  
  7494. while (rset.next())
  7495. {
  7496. final int activeClassId = rset.getInt("classid");
  7497. final boolean female = rset.getInt("sex")!=0;
  7498. final L2PcTemplate template = CharTemplateTable.getInstance().getTemplate(activeClassId);
  7499. PcAppearance app = new PcAppearance(rset.getByte("face"), rset.getByte("hairColor"), rset.getByte("hairStyle"), female);
  7500.  
  7501. player = new L2PcInstance(objectId, template, rset.getString("account_name"), app);
  7502. player.setName(rset.getString("char_name"));
  7503. player._lastAccess = rset.getLong("lastAccess");
  7504.  
  7505. player.getStat().setExp(rset.getLong("exp"));
  7506. player.setExpBeforeDeath(rset.getLong("expBeforeDeath"));
  7507. player.getStat().setLevel(rset.getByte("level"));
  7508. player.getStat().setSp(rset.getInt("sp"));
  7509.  
  7510. player.setWantsPeace(rset.getInt("wantspeace"));
  7511.  
  7512. player.setHeading(rset.getInt("heading"));
  7513.  
  7514. player.setKarma(rset.getInt("karma"));
  7515. player.setFame(rset.getInt("fame"));
  7516. player.setPvpKills(rset.getInt("pvpkills"));
  7517. player.setPkKills(rset.getInt("pkkills"));
  7518. player.setOnlineTime(rset.getLong("onlinetime"));
  7519. player.setNewbie(rset.getInt("newbie"));
  7520. player.setNoble(rset.getInt("nobless")==1);
  7521.  
  7522. player.setClanJoinExpiryTime(rset.getLong("clan_join_expiry_time"));
  7523. if (player.getClanJoinExpiryTime() < System.currentTimeMillis())
  7524. {
  7525. player.setClanJoinExpiryTime(0);
  7526. }
  7527. player.setClanCreateExpiryTime(rset.getLong("clan_create_expiry_time"));
  7528. if (player.getClanCreateExpiryTime() < System.currentTimeMillis())
  7529. {
  7530. player.setClanCreateExpiryTime(0);
  7531. }
  7532.  
  7533. int clanId = rset.getInt("clanid");
  7534. player.setPowerGrade((int)rset.getLong("power_grade"));
  7535. player.setPledgeType(rset.getInt("subpledge"));
  7536. player.setLastRecomUpdate(rset.getLong("last_recom_date"));
  7537. //player.setApprentice(rset.getInt("apprentice"));
  7538.  
  7539. if (clanId > 0)
  7540. {
  7541. player.setClan(ClanTable.getInstance().getClan(clanId));
  7542. }
  7543.  
  7544. if (player.getClan() != null)
  7545. {
  7546. if (player.getClan().getLeaderId() != player.getObjectId())
  7547. {
  7548. if (player.getPowerGrade() == 0)
  7549. {
  7550. player.setPowerGrade(5);
  7551. }
  7552. player.setClanPrivileges(player.getClan().getRankPrivs(player.getPowerGrade()));
  7553. }
  7554. else
  7555. {
  7556. player.setClanPrivileges(L2Clan.CP_ALL);
  7557. player.setPowerGrade(1);
  7558. }
  7559. }
  7560. else
  7561. {
  7562. player.setClanPrivileges(L2Clan.CP_NOTHING);
  7563. }
  7564.  
  7565. player.setDeleteTimer(rset.getLong("deletetime"));
  7566.  
  7567. player.setTitle(rset.getString("title"));
  7568. player.setAccessLevel(rset.getInt("accesslevel"));
  7569. player.setFistsWeaponItem(player.findFistsWeaponItem(activeClassId));
  7570. player.setUptime(System.currentTimeMillis());
  7571.  
  7572. currentHp = rset.getDouble("curHp");
  7573. currentCp = rset.getDouble("curCp");
  7574. currentMp = rset.getDouble("curMp");
  7575.  
  7576. //Check recs
  7577. player.checkRecom(rset.getInt("rec_have"),rset.getInt("rec_left"));
  7578.  
  7579. player._classIndex = 0;
  7580. try { player.setBaseClass(rset.getInt("base_class")); }
  7581. catch (Exception e) { player.setBaseClass(activeClassId); }
  7582.  
  7583. // Restore Subclass Data (cannot be done earlier in function)
  7584. if (restoreSubClassData(player))
  7585. {
  7586. if (activeClassId != player.getBaseClass())
  7587. {
  7588. for (SubClass subClass : player.getSubClasses().values())
  7589. if (subClass.getClassId() == activeClassId)
  7590. player._classIndex = subClass.getClassIndex();
  7591. }
  7592. }
  7593. if (player.getClassIndex() == 0 && activeClassId != player.getBaseClass())
  7594. {
  7595. // Subclass in use but doesn't exist in DB -
  7596. // a possible restart-while-modifysubclass cheat has been attempted.
  7597. // Switching to use base class
  7598. player.setClassId(player.getBaseClass());
  7599. _log.warning("Player "+player.getName()+" reverted to base class. Possibly has tried a relogin exploit while subclassing.");
  7600. }
  7601. else player._activeClass = activeClassId;
  7602.  
  7603. player.setApprentice(rset.getInt("apprentice"));
  7604. player.setSponsor(rset.getInt("sponsor"));
  7605. player.setLvlJoinedAcademy(rset.getInt("lvl_joined_academy"));
  7606. player.setIsIn7sDungeon(rset.getInt("isin7sdungeon") == 1);
  7607. player.setPunishLevel(rset.getInt("punish_level"));
  7608. if (player.getPunishLevel() != PunishLevel.NONE)
  7609. player.setPunishTimer(rset.getLong("punish_timer"));
  7610. else
  7611. player.setPunishTimer(0);
  7612.  
  7613. CursedWeaponsManager.getInstance().checkPlayer(player);
  7614.  
  7615. player.setAllianceWithVarkaKetra(rset.getInt("varka_ketra_ally"));
  7616.  
  7617. player.setDeathPenaltyBuffLevel(rset.getInt("death_penalty_level"));
  7618.  
  7619. player.setVitalityPoints(rset.getInt("vitality_points"), true);
  7620.  
  7621. // Add the L2PcInstance object in _allObjects
  7622. //L2World.getInstance().storeObject(player);
  7623.  
  7624. // Set the x,y,z position of the L2PcInstance and make it invisible
  7625. player.setXYZInvisible(rset.getInt("x"), rset.getInt("y"), rset.getInt("z"));
  7626.  
  7627. // Set Teleport Bookmark Slot
  7628. player.setBookMarkSlot(rset.getInt("BookmarkSlot"));
  7629.  
  7630. // Retrieve the name and ID of the other characters assigned to this account.
  7631. PreparedStatement stmt = con.prepareStatement("SELECT charId, char_name FROM characters WHERE account_name=? AND charId<>?");
  7632. stmt.setString(1, player._accountName);
  7633. stmt.setInt(2, objectId);
  7634. ResultSet chars = stmt.executeQuery();
  7635.  
  7636. while (chars.next())
  7637. {
  7638. Integer charId = chars.getInt("charId");
  7639. String charName = chars.getString("char_name");
  7640. player._chars.put(charId, charName);
  7641. }
  7642.  
  7643. chars.close();
  7644. stmt.close();
  7645. break;
  7646. }
  7647.  
  7648. rset.close();
  7649. statement.close();
  7650.  
  7651. // Retrieve from the database all secondary data of this L2PcInstance
  7652. // and reward expertise/lucky skills if necessary.
  7653. // Note that Clan, Noblesse and Hero skills are given separately and not here.
  7654. player.restoreCharData();
  7655. player.rewardSkills();
  7656.  
  7657. // buff and status icons
  7658. if (Config.STORE_SKILL_COOLTIME)
  7659. player.restoreEffects();
  7660.  
  7661. // Restore current Cp, HP and MP values
  7662. player.setCurrentCp(currentCp);
  7663. player.setCurrentHp(currentHp);
  7664. player.setCurrentMp(currentMp);
  7665.  
  7666. if (currentHp < 0.5) {
  7667. player.setIsDead(true);
  7668. player.stopHpMpRegeneration();
  7669. }
  7670.  
  7671. // Restore pet if exists in the world
  7672. player.setPet(L2World.getInstance().getPet(player.getObjectId()));
  7673. if(player.getPet() != null) player.getPet().setOwner(player);
  7674.  
  7675. // Update the overloaded status of the L2PcInstance
  7676. player.refreshOverloaded();
  7677. // Update the expertise status of the L2PcInstance
  7678. player.refreshExpertisePenalty();
  7679. }
  7680. catch (Exception e)
  7681. {
  7682. _log.log(Level.SEVERE, "Failed loading character.", e);
  7683. }
  7684. finally
  7685. {
  7686. try { con.close(); } catch (Exception e) {}
  7687. }
  7688.  
  7689. return player;
  7690. }
  7691.  
  7692. /**
  7693. * @return
  7694. */
  7695. public Forum getMail()
  7696. {
  7697. if (_forumMail == null)
  7698. {
  7699. setMail(ForumsBBSManager.getInstance().getForumByName("MailRoot").getChildByName(getName()));
  7700.  
  7701. if (_forumMail == null)
  7702. {
  7703. ForumsBBSManager.getInstance().createNewForum(getName(),ForumsBBSManager.getInstance().getForumByName("MailRoot"),Forum.MAIL,Forum.OWNERONLY,getObjectId());
  7704. setMail(ForumsBBSManager.getInstance().getForumByName("MailRoot").getChildByName(getName()));
  7705. }
  7706. }
  7707.  
  7708. return _forumMail;
  7709. }
  7710.  
  7711. /**
  7712. * @param forum
  7713. */
  7714. public void setMail(Forum forum)
  7715. {
  7716. _forumMail = forum;
  7717. }
  7718.  
  7719. /**
  7720. * @return
  7721. */
  7722. public Forum getMemo()
  7723. {
  7724. if (_forumMemo == null)
  7725. {
  7726. setMemo(ForumsBBSManager.getInstance().getForumByName("MemoRoot").getChildByName(_accountName));
  7727.  
  7728. if (_forumMemo == null)
  7729. {
  7730. ForumsBBSManager.getInstance().createNewForum(_accountName, ForumsBBSManager.getInstance().getForumByName("MemoRoot"), Forum.MEMO, Forum.OWNERONLY, getObjectId());
  7731. setMemo(ForumsBBSManager.getInstance().getForumByName("MemoRoot").getChildByName(_accountName));
  7732. }
  7733. }
  7734.  
  7735. return _forumMemo;
  7736. }
  7737.  
  7738. /**
  7739. * @param forum
  7740. */
  7741. public void setMemo(Forum forum)
  7742. {
  7743. _forumMemo = forum;
  7744. }
  7745.  
  7746. /**
  7747. * Restores sub-class data for the L2PcInstance, used to check the current
  7748. * class index for the character.
  7749. */
  7750. private static boolean restoreSubClassData(L2PcInstance player)
  7751. {
  7752. Connection con = null;
  7753.  
  7754. try
  7755. {
  7756. con = L2DatabaseFactory.getInstance().getConnection();
  7757. PreparedStatement statement = con.prepareStatement(RESTORE_CHAR_SUBCLASSES);
  7758. statement.setInt(1, player.getObjectId());
  7759.  
  7760. ResultSet rset = statement.executeQuery();
  7761.  
  7762. while (rset.next())
  7763. {
  7764. SubClass subClass = new SubClass();
  7765. subClass.setClassId(rset.getInt("class_id"));
  7766. subClass.setLevel(rset.getByte("level"));
  7767. subClass.setExp(rset.getLong("exp"));
  7768. subClass.setSp(rset.getInt("sp"));
  7769. subClass.setClassIndex(rset.getInt("class_index"));
  7770.  
  7771. // Enforce the correct indexing of _subClasses against their class indexes.
  7772. player.getSubClasses().put(subClass.getClassIndex(), subClass);
  7773. }
  7774.  
  7775. statement.close();
  7776. }
  7777. catch (Exception e) {
  7778. _log.warning("Could not restore classes for " + player.getName() + ": " + e);
  7779. e.printStackTrace();
  7780. }
  7781. finally {
  7782. try { con.close(); } catch (Exception e) {}
  7783. }
  7784.  
  7785. return true;
  7786. }
  7787.  
  7788. /**
  7789. * Restores secondary data for the L2PcInstance, based on the current class index.
  7790. */
  7791. private void restoreCharData()
  7792. {
  7793. // Retrieve from the database all skills of this L2PcInstance and add them to _skills.
  7794. restoreSkills();
  7795.  
  7796. // Retrieve from the database all macroses of this L2PcInstance and add them to _macroses.
  7797. _macroses.restore();
  7798.  
  7799. // Retrieve from the database all shortCuts of this L2PcInstance and add them to _shortCuts.
  7800. _shortCuts.restore();
  7801.  
  7802. // Retrieve from the database all henna of this L2PcInstance and add them to _henna.
  7803. restoreHenna();
  7804.  
  7805. // Retrieve from the database all teleport bookmark of this L2PcInstance and add them to _tpbookmark.
  7806. restoreTeleportBookmark();
  7807.  
  7808. // Retrieve from the database all recom data of this L2PcInstance and add to _recomChars.
  7809. if (Config.ALT_RECOMMEND) restoreRecom();
  7810.  
  7811. // Retrieve from the database the recipe book of this L2PcInstance.
  7812. restoreRecipeBook(true);
  7813. }
  7814.  
  7815. /**
  7816. * Restore recipe book data for this L2PcInstance.
  7817. */
  7818. private void restoreRecipeBook(boolean loadCommon)
  7819. {
  7820. Connection con = null;
  7821.  
  7822. try {
  7823. con = L2DatabaseFactory.getInstance().getConnection();
  7824. String sql = loadCommon ? "SELECT id, type, classIndex FROM character_recipebook WHERE charId=?" :
  7825. "SELECT id FROM character_recipebook WHERE charId=? AND classIndex=? AND type = 1";
  7826. PreparedStatement statement = con.prepareStatement(sql);
  7827. statement.setInt(1, getObjectId());
  7828. if (!loadCommon)
  7829. statement.setInt(2, _classIndex);
  7830. ResultSet rset = statement.executeQuery();
  7831.  
  7832. _dwarvenRecipeBook.clear();
  7833.  
  7834. L2RecipeList recipe;
  7835. while (rset.next()) {
  7836. recipe = RecipeController.getInstance().getRecipeList(rset.getInt("id"));
  7837.  
  7838. if (loadCommon)
  7839. {
  7840. if (rset.getInt(2) == 1)
  7841. {
  7842. if (rset.getInt(3) == _classIndex)
  7843. registerDwarvenRecipeList(recipe, false);
  7844. }
  7845. else
  7846. registerCommonRecipeList(recipe, false);
  7847. }
  7848. else
  7849. registerDwarvenRecipeList(recipe, false);
  7850. }
  7851.  
  7852. rset.close();
  7853. statement.close();
  7854. }
  7855. catch (Exception e)
  7856. {
  7857. if (_log.isLoggable(Level.SEVERE))
  7858. _log.warning("Could not restore recipe book data:" + e);
  7859. }
  7860. finally {
  7861. try { con.close(); } catch (Exception e) {}
  7862. }
  7863. }
  7864.  
  7865. /**
  7866. * Update L2PcInstance stats in the characters table of the database.<BR><BR>
  7867. */
  7868. public synchronized void store(boolean storeActiveEffects)
  7869. {
  7870. //update client coords, if these look like true
  7871. // if (isInsideRadius(getClientX(), getClientY(), 1000, true))
  7872. // setXYZ(getClientX(), getClientY(), getClientZ());
  7873.  
  7874. storeCharBase();
  7875. storeCharSub();
  7876. storeEffect(storeActiveEffects);
  7877. transformInsertInfo();
  7878. }
  7879.  
  7880. public void store()
  7881. {
  7882. store(true);
  7883. }
  7884.  
  7885. private void storeCharBase()
  7886. {
  7887. Connection con = null;
  7888.  
  7889. try
  7890. {
  7891. // Get the exp, level, and sp of base class to store in base table
  7892. int currentClassIndex = getClassIndex();
  7893. _classIndex = 0;
  7894. long exp = getStat().getExp();
  7895. int level = getStat().getLevel();
  7896. int sp = getStat().getSp();
  7897. _classIndex = currentClassIndex;
  7898.  
  7899. con = L2DatabaseFactory.getInstance().getConnection();
  7900. // Update base class
  7901. PreparedStatement statement = con.prepareStatement(UPDATE_CHARACTER);
  7902.  
  7903. statement.setInt(1, level);
  7904. statement.setInt(2, getMaxHp());
  7905. statement.setDouble(3, getCurrentHp());
  7906. statement.setInt(4, getMaxCp());
  7907. statement.setDouble(5, getCurrentCp());
  7908. statement.setInt(6, getMaxMp());
  7909. statement.setDouble(7, getCurrentMp());
  7910. statement.setInt(8, getAppearance().getFace());
  7911. statement.setInt(9, getAppearance().getHairStyle());
  7912. statement.setInt(10, getAppearance().getHairColor());
  7913. statement.setInt(11, getAppearance().getSex()? 1 : 0);
  7914. statement.setInt(12, getHeading());
  7915. statement.setInt(13, _observerMode ? _obsX : getX());
  7916. statement.setInt(14, _observerMode ? _obsY : getY());
  7917. statement.setInt(15, _observerMode ? _obsZ : getZ());
  7918. statement.setLong(16, exp);
  7919. statement.setLong(17, getExpBeforeDeath());
  7920. statement.setInt(18, sp);
  7921. statement.setInt(19, getKarma());
  7922. statement.setInt(20, getFame());
  7923. statement.setInt(21, getPvpKills());
  7924. statement.setInt(22, getPkKills());
  7925. statement.setInt(23, getRecomHave());
  7926. statement.setInt(24, getRecomLeft());
  7927. statement.setInt(25, getClanId());
  7928. statement.setInt(26, getRace().ordinal());
  7929. statement.setInt(27, getClassId().getId());
  7930. statement.setLong(28, getDeleteTimer());
  7931. statement.setString(29, getTitle());
  7932. statement.setInt(30, getAccessLevel().getLevel());
  7933. statement.setInt(31, isOnline());
  7934. statement.setInt(32, isIn7sDungeon() ? 1 : 0);
  7935. statement.setInt(33, getClanPrivileges());
  7936. statement.setInt(34, getWantsPeace());
  7937. statement.setInt(35, getBaseClass());
  7938.  
  7939. long totalOnlineTime = _onlineTime;
  7940.  
  7941. if (_onlineBeginTime > 0)
  7942. totalOnlineTime += (System.currentTimeMillis()-_onlineBeginTime)/1000;
  7943.  
  7944. statement.setLong(36, totalOnlineTime);
  7945. statement.setInt(37, getPunishLevel().value());
  7946. statement.setLong(38, getPunishTimer());
  7947. statement.setInt(39, getNewbie());
  7948. statement.setInt(40, isNoble() ? 1 : 0);
  7949. statement.setLong(41, getPowerGrade());
  7950. statement.setInt(42, getPledgeType());
  7951. statement.setLong(43,getLastRecomUpdate());
  7952. statement.setInt(44,getLvlJoinedAcademy());
  7953. statement.setLong(45,getApprentice());
  7954. statement.setLong(46,getSponsor());
  7955. statement.setInt(47, getAllianceWithVarkaKetra());
  7956. statement.setLong(48, getClanJoinExpiryTime());
  7957. statement.setLong(49, getClanCreateExpiryTime());
  7958. statement.setString(50, getName());
  7959. statement.setLong(51, getDeathPenaltyBuffLevel());
  7960. statement.setInt(52, getBookMarkSlot());
  7961. statement.setInt(53, getVitalityPoints());
  7962. statement.setInt(54, getObjectId());
  7963.  
  7964. statement.execute();
  7965. statement.close();
  7966. }
  7967. catch (Exception e) { _log.warning("Could not store char base data: "+ e); }
  7968. finally { try { con.close(); } catch (Exception e) {} }
  7969. }
  7970.  
  7971. private void storeCharSub()
  7972. {
  7973. Connection con = null;
  7974.  
  7975. try
  7976. {
  7977. con = L2DatabaseFactory.getInstance().getConnection();
  7978. PreparedStatement statement = con.prepareStatement(UPDATE_CHAR_SUBCLASS);
  7979.  
  7980. if (getTotalSubClasses() > 0)
  7981. {
  7982. for (SubClass subClass : getSubClasses().values())
  7983. {
  7984. statement.setLong(1, subClass.getExp());
  7985. statement.setInt(2, subClass.getSp());
  7986. statement.setInt(3, subClass.getLevel());
  7987. statement.setInt(4, subClass.getClassId());
  7988. statement.setInt(5, getObjectId());
  7989. statement.setInt(6, subClass.getClassIndex());
  7990.  
  7991. statement.execute();
  7992. }
  7993. statement.close();
  7994. }
  7995. }
  7996. catch (Exception e) {
  7997. _log.warning("Could not store sub class data for " + getName() + ": "+ e);
  7998. }
  7999. finally { try { con.close(); } catch (Exception e) {} }
  8000. }
  8001.  
  8002. private void storeEffect(boolean storeEffects)
  8003. {
  8004. if (!Config.STORE_SKILL_COOLTIME)
  8005. return;
  8006.  
  8007. Connection con = null;
  8008. try
  8009. {
  8010. con = L2DatabaseFactory.getInstance().getConnection();
  8011.  
  8012.  
  8013. // Delete all current stored effects for char to avoid dupe
  8014. PreparedStatement statement = con.prepareStatement(DELETE_SKILL_SAVE);
  8015.  
  8016. statement.setInt(1, getObjectId());
  8017. statement.setInt(2, getClassIndex());
  8018. statement.execute();
  8019. statement.close();
  8020.  
  8021. int buff_index = 0;
  8022.  
  8023. final List<Integer> storedSkills = new FastList<Integer>();
  8024.  
  8025. // Store all effect data along with calulated remaining
  8026. // reuse delays for matching skills. 'restore_type'= 0.
  8027. statement = con.prepareStatement(ADD_SKILL_SAVE);
  8028.  
  8029. if (storeEffects)
  8030. {
  8031. for (L2Effect effect : getAllEffects())
  8032. {
  8033. if (effect == null)
  8034. continue;
  8035.  
  8036. switch (effect.getEffectType())
  8037. {
  8038. case HEAL_OVER_TIME:
  8039. case COMBAT_POINT_HEAL_OVER_TIME:
  8040. // TODO: Fix me.
  8041. case HIDE:
  8042. continue;
  8043. }
  8044.  
  8045. L2Skill skill = effect.getSkill();
  8046. int skillId = skill.getId();
  8047.  
  8048. if (storedSkills.contains(skillId))
  8049. continue;
  8050.  
  8051. storedSkills.add(skillId);
  8052.  
  8053. if (effect != null && !effect.isHerbEffect() && effect.getInUse()
  8054. && !skill.isToggle())
  8055. {
  8056.  
  8057. statement.setInt(1, getObjectId());
  8058. statement.setInt(2, skillId);
  8059. statement.setInt(3, skill.getLevel());
  8060. statement.setInt(4, effect.getCount());
  8061. statement.setInt(5, effect.getTime());
  8062.  
  8063. if (_reuseTimeStamps.containsKey(skillId))
  8064. {
  8065. TimeStamp t = _reuseTimeStamps.get(skillId);
  8066. statement.setLong(6, t.hasNotPassed() ? t.getReuse() : 0);
  8067. statement.setDouble(7, t.hasNotPassed() ? t.getStamp() : 0);
  8068. }
  8069. else
  8070. {
  8071. statement.setLong(6, 0);
  8072. statement.setDouble(7, 0);
  8073. }
  8074.  
  8075. statement.setInt(8, 0);
  8076. statement.setInt(9, getClassIndex());
  8077. statement.setInt(10, ++buff_index);
  8078. statement.execute();
  8079. }
  8080. }
  8081. }
  8082.  
  8083. // Store the reuse delays of remaining skills which
  8084. // lost effect but still under reuse delay. 'restore_type' 1.
  8085. for (TimeStamp t : _reuseTimeStamps.values())
  8086. {
  8087. if (t.hasNotPassed())
  8088. {
  8089. int skillId = t.getSkill();
  8090. if (storedSkills.contains(skillId))
  8091. continue;
  8092. storedSkills.add(skillId);
  8093.  
  8094. statement.setInt(1, getObjectId());
  8095. statement.setInt(2, skillId);
  8096. statement.setInt(3, -1);
  8097. statement.setInt(4, -1);
  8098. statement.setInt(5, -1);
  8099. statement.setLong(6, t.getReuse());
  8100. statement.setDouble(7, t.getStamp());
  8101. statement.setInt(8, 1);
  8102. statement.setInt(9, getClassIndex());
  8103. statement.setInt(10, ++buff_index);
  8104. statement.execute();
  8105.  
  8106. }
  8107. }
  8108. statement.close();
  8109. }
  8110. catch (Exception e)
  8111. {
  8112. _log.log(Level.WARNING, "Could not store char effect data: ", e);
  8113. }
  8114. finally
  8115. {
  8116. try
  8117. {
  8118. con.close();
  8119. }
  8120. catch (Exception e)
  8121. {
  8122. }
  8123. }
  8124. }
  8125.  
  8126. /**
  8127. * Return True if the L2PcInstance is on line.<BR>
  8128. * <BR>
  8129. */
  8130. public int isOnline()
  8131. {
  8132. return (_isOnline ? 1 : 0);
  8133. }
  8134.  
  8135. public boolean isIn7sDungeon()
  8136. {
  8137. return _isIn7sDungeon;
  8138. }
  8139.  
  8140. /**
  8141. * 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>
  8142. *
  8143. * <B><U> Concept</U> :</B><BR><BR>
  8144. * All skills own by a L2PcInstance are identified in <B>_skills</B><BR><BR>
  8145. *
  8146. * <B><U> Actions</U> :</B><BR><BR>
  8147. * <li>Replace oldSkill by newSkill or Add the newSkill </li>
  8148. * <li>If an old skill has been replaced, remove all its Func objects of L2Character calculator set</li>
  8149. * <li>Add Func objects of newSkill to the calculator set of the L2Character </li><BR><BR>
  8150. *
  8151. * @param newSkill The L2Skill to add to the L2Character
  8152. *
  8153. * @return The L2Skill replaced or null if just added a new L2Skill
  8154. *
  8155. */
  8156. public L2Skill addSkill(L2Skill newSkill, boolean store)
  8157. {
  8158. // Add a skill to the L2PcInstance _skills and its Func objects to the calculator set of the L2PcInstance
  8159. L2Skill oldSkill = super.addSkill(newSkill);
  8160.  
  8161. // Add or update a L2PcInstance skill in the character_skills table of the database
  8162. if (store) storeSkill(newSkill, oldSkill, -1);
  8163.  
  8164. return oldSkill;
  8165. }
  8166.  
  8167. public L2Skill removeSkill(L2Skill skill, boolean store)
  8168. {
  8169. if (store)
  8170. return removeSkill(skill);
  8171. else
  8172. return super.removeSkill(skill, true);
  8173. }
  8174.  
  8175. public L2Skill removeSkill(L2Skill skill, boolean store, boolean cancelEffect)
  8176. {
  8177. if (store)
  8178. return removeSkill(skill);
  8179. else
  8180. return super.removeSkill(skill, cancelEffect);
  8181. }
  8182.  
  8183. /**
  8184. * 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>
  8185. *
  8186. * <B><U> Concept</U> :</B><BR><BR>
  8187. * All skills own by a L2Character are identified in <B>_skills</B><BR><BR>
  8188. *
  8189. * <B><U> Actions</U> :</B><BR><BR>
  8190. * <li>Remove the skill from the L2Character _skills </li>
  8191. * <li>Remove all its Func objects from the L2Character calculator set</li><BR><BR>
  8192. *
  8193. * <B><U> Overridden in </U> :</B><BR><BR>
  8194. * <li> L2PcInstance : Save update in the character_skills table of the database</li><BR><BR>
  8195. *
  8196. * @param skill The L2Skill to remove from the L2Character
  8197. *
  8198. * @return The L2Skill removed
  8199. *
  8200. */
  8201. @Override
  8202. public L2Skill removeSkill(L2Skill skill)
  8203. {
  8204. // Remove a skill from the L2Character and its Func objects from calculator set of the L2Character
  8205. L2Skill oldSkill = super.removeSkill(skill);
  8206.  
  8207. Connection con = null;
  8208.  
  8209. try
  8210. {
  8211. // Remove or update a L2PcInstance skill from the character_skills table of the database
  8212. con = L2DatabaseFactory.getInstance().getConnection();
  8213. PreparedStatement statement = con.prepareStatement(DELETE_SKILL_FROM_CHAR);
  8214.  
  8215. if (oldSkill != null)
  8216. {
  8217. statement.setInt(1, oldSkill.getId());
  8218. statement.setInt(2, getObjectId());
  8219. statement.setInt(3, getClassIndex());
  8220. statement.execute();
  8221. }
  8222. statement.close();
  8223. }
  8224. catch (Exception e)
  8225. {
  8226. _log.warning("Error could not delete skill: " + e);
  8227. }
  8228. finally
  8229. {
  8230. try { con.close(); } catch (Exception e) {}
  8231. }
  8232.  
  8233. if (this.transformId() > 0 || this.isCursedWeaponEquipped())
  8234. return oldSkill;
  8235.  
  8236. L2ShortCut[] allShortCuts = getAllShortCuts();
  8237.  
  8238. for (L2ShortCut sc : allShortCuts)
  8239. {
  8240. if (sc != null && skill != null && sc.getId() == skill.getId() && sc.getType() == L2ShortCut.TYPE_SKILL)
  8241. deleteShortCut(sc.getSlot(), sc.getPage());
  8242. }
  8243.  
  8244. return oldSkill;
  8245. }
  8246.  
  8247. /**
  8248. * Add or update a L2PcInstance skill in the character_skills table of the database.
  8249. * <BR><BR>
  8250. * If newClassIndex > -1, the skill will be stored with that class index, not the current one.
  8251. */
  8252. private void storeSkill(L2Skill newSkill, L2Skill oldSkill, int newClassIndex)
  8253. {
  8254. int classIndex = _classIndex;
  8255.  
  8256. if (newClassIndex > -1)
  8257. classIndex = newClassIndex;
  8258.  
  8259. Connection con = null;
  8260.  
  8261. try
  8262. {
  8263. con = L2DatabaseFactory.getInstance().getConnection();
  8264. PreparedStatement statement;
  8265.  
  8266. if (oldSkill != null && newSkill != null)
  8267. {
  8268. statement = con.prepareStatement(UPDATE_CHARACTER_SKILL_LEVEL);
  8269. statement.setInt(1, newSkill.getLevel());
  8270. statement.setInt(2, oldSkill.getId());
  8271. statement.setInt(3, getObjectId());
  8272. statement.setInt(4, classIndex);
  8273. statement.execute();
  8274. statement.close();
  8275. }
  8276. else if (newSkill != null)
  8277. {
  8278. statement = con.prepareStatement(ADD_NEW_SKILL);
  8279. statement.setInt(1, getObjectId());
  8280. statement.setInt(2, newSkill.getId());
  8281. statement.setInt(3, newSkill.getLevel());
  8282. statement.setInt(4, classIndex);
  8283. statement.execute();
  8284. statement.close();
  8285. }
  8286. else
  8287. {
  8288. _log.warning("could not store new skill. its NULL");
  8289. }
  8290. }
  8291. catch (Exception e)
  8292. {
  8293. _log.warning("Error could not store char skills: " + e);
  8294. }
  8295. finally
  8296. {
  8297. try { con.close(); } catch (Exception e) {}
  8298. }
  8299. }
  8300.  
  8301. /**
  8302. * Retrieve from the database all skills of this L2PcInstance and add them to _skills.<BR><BR>
  8303. */
  8304. private void restoreSkills()
  8305. {
  8306. Connection con = null;
  8307.  
  8308. try
  8309. {
  8310. // Retrieve all skills of this L2PcInstance from the database
  8311. con = L2DatabaseFactory.getInstance().getConnection();
  8312. PreparedStatement statement = con.prepareStatement(RESTORE_SKILLS_FOR_CHAR);
  8313.  
  8314. statement.setInt(1, getObjectId());
  8315. statement.setInt(2, getClassIndex());
  8316. ResultSet rset = statement.executeQuery();
  8317.  
  8318. // Go though the recordset of this SQL query
  8319. while (rset.next())
  8320. {
  8321. int id = rset.getInt("skill_id");
  8322. int level = rset.getInt("skill_level");
  8323.  
  8324. if (id > 9000 && id < 9007)
  8325. continue; // fake skills for base stats
  8326.  
  8327. // Create a L2Skill object for each record
  8328. L2Skill skill = SkillTable.getInstance().getInfo(id, level);
  8329.  
  8330. // Add the L2Skill object to the L2Character _skills and its Func objects to the calculator set of the L2Character
  8331. super.addSkill(skill);
  8332. }
  8333.  
  8334. rset.close();
  8335. statement.close();
  8336. }
  8337. catch (Exception e)
  8338. {
  8339. _log.warning("Could not restore character skills: " + e);
  8340. }
  8341. finally
  8342. {
  8343. try { con.close(); } catch (Exception e) {}
  8344. }
  8345. }
  8346.  
  8347. /**
  8348. * Retrieve from the database all skill effects of this L2PcInstance and add them to the player.<BR><BR>
  8349. */
  8350. public void restoreEffects()
  8351. {
  8352. Connection con = null;
  8353.  
  8354. try
  8355. {
  8356. con = L2DatabaseFactory.getInstance().getConnection();
  8357. PreparedStatement statement;
  8358. ResultSet rset;
  8359.  
  8360. /**
  8361. * Restore Type 0
  8362. * These skill were still in effect on the character
  8363. * upon logout. Some of which were self casted and
  8364. * might still have had a long reuse delay which also
  8365. * is restored.
  8366. */
  8367. statement = con.prepareStatement(RESTORE_SKILL_SAVE);
  8368. statement.setInt(1, getObjectId());
  8369. statement.setInt(2, getClassIndex());
  8370. statement.setInt(3, 0);
  8371. rset = statement.executeQuery();
  8372.  
  8373. while (rset.next())
  8374. {
  8375. int skillId = rset.getInt("skill_id");
  8376. int skillLvl = rset.getInt("skill_level");
  8377. int effectCount = rset.getInt("effect_count");
  8378. int effectCurTime = rset.getInt("effect_cur_time");
  8379. double reuseDelay = rset.getInt("reuse_delay");
  8380. double systime = rset.getDouble("systime");
  8381.  
  8382. double remainingTime = systime - System.currentTimeMillis();
  8383.  
  8384. // Just incase the admin minipulated this table incorrectly :x
  8385. if(skillId == -1 || effectCount == -1 || effectCurTime == -1 || reuseDelay < 0)
  8386. continue;
  8387.  
  8388. L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);
  8389. L2Effect[] effects = skill.getEffects(this, this);
  8390.  
  8391. if (remainingTime > 10)
  8392. {
  8393. disableSkill(skillId, (long)remainingTime);
  8394. addTimeStamp(new TimeStamp(skillId, (long)reuseDelay, (long)systime));
  8395. }
  8396.  
  8397. for (L2Effect effect : effects)
  8398. {
  8399. effect.setCount(effectCount);
  8400. effect.setFirstTime(effectCurTime);
  8401. }
  8402. }
  8403. rset.close();
  8404. statement.close();
  8405.  
  8406. /**
  8407. * Restore Type 1
  8408. * The remaning skills lost effect upon logout but
  8409. * were still under a high reuse delay.
  8410. */
  8411. statement = con.prepareStatement(RESTORE_SKILL_SAVE);
  8412. statement.setInt(1, getObjectId());
  8413. statement.setInt(2, getClassIndex());
  8414. statement.setInt(3, 1);
  8415. rset = statement.executeQuery();
  8416.  
  8417. while (rset.next())
  8418. {
  8419. int skillId = rset.getInt("skill_id");
  8420. double reuseDelay = rset.getDouble("reuse_delay");
  8421. double systime = rset.getDouble("systime");
  8422.  
  8423. double remainingTime = systime - System.currentTimeMillis();
  8424.  
  8425. if (remainingTime < 10)
  8426. continue;
  8427.  
  8428. disableSkill(skillId, (long)remainingTime);
  8429. addTimeStamp(new TimeStamp(skillId, (long)reuseDelay, (long)systime));
  8430. }
  8431. rset.close();
  8432. statement.close();
  8433.  
  8434. statement = con.prepareStatement(DELETE_SKILL_SAVE);
  8435. statement.setInt(1, getObjectId());
  8436. statement.setInt(2, getClassIndex());
  8437. statement.executeUpdate();
  8438. statement.close();
  8439. }
  8440. catch (Exception e) {
  8441. _log.warning("Could not restore active effect data: " + e);
  8442. }
  8443. finally {
  8444. try {con.close();} catch (Exception e) {}
  8445. }
  8446. }
  8447.  
  8448. /**
  8449. * Retrieve from the database all Henna of this L2PcInstance, add them to _henna and calculate stats of the L2PcInstance.<BR><BR>
  8450. */
  8451. private void restoreHenna()
  8452. {
  8453. Connection con = null;
  8454.  
  8455. try
  8456. {
  8457. con = L2DatabaseFactory.getInstance().getConnection();
  8458. PreparedStatement statement = con.prepareStatement(RESTORE_CHAR_HENNAS);
  8459. statement.setInt(1, getObjectId());
  8460. statement.setInt(2, getClassIndex());
  8461. ResultSet rset = statement.executeQuery();
  8462.  
  8463. for (int i=0;i<3;i++)
  8464. _henna[i]=null;
  8465.  
  8466. while (rset.next())
  8467. {
  8468. int slot = rset.getInt("slot");
  8469.  
  8470. if (slot<1 || slot>3)
  8471. continue;
  8472.  
  8473. int symbol_id = rset.getInt("symbol_id");
  8474.  
  8475. L2HennaInstance sym = null;
  8476.  
  8477. if (symbol_id != 0)
  8478. {
  8479. L2Henna tpl = HennaTable.getInstance().getTemplate(symbol_id);
  8480.  
  8481. if (tpl != null)
  8482. {
  8483. sym = new L2HennaInstance(tpl);
  8484. _henna[slot-1] = sym;
  8485. }
  8486. }
  8487. }
  8488.  
  8489. rset.close();
  8490. statement.close();
  8491. }
  8492. catch (Exception e)
  8493. {
  8494. _log.log(Level.SEVERE, "Failed restoing character hennas.", e);
  8495. }
  8496. finally
  8497. {
  8498. try { con.close(); } catch (Exception e) {}
  8499. }
  8500.  
  8501. // Calculate Henna modifiers of this L2PcInstance
  8502. recalcHennaStats();
  8503. }
  8504.  
  8505. /**
  8506. * Retrieve from the database all Recommendation data of this L2PcInstance, add to _recomChars and calculate stats of the L2PcInstance.<BR><BR>
  8507. */
  8508. private void restoreRecom()
  8509. {
  8510. Connection con = null;
  8511.  
  8512. try
  8513. {
  8514. con = L2DatabaseFactory.getInstance().getConnection();
  8515. PreparedStatement statement = con.prepareStatement(RESTORE_CHAR_RECOMS);
  8516. statement.setInt(1, getObjectId());
  8517. ResultSet rset = statement.executeQuery();
  8518. while (rset.next())
  8519. {
  8520. _recomChars.add(rset.getInt("target_id"));
  8521. }
  8522.  
  8523. rset.close();
  8524. statement.close();
  8525. }
  8526. catch (Exception e)
  8527. {
  8528. _log.log(Level.SEVERE, "Failed restoring character recommendations.", e);
  8529. }
  8530. finally
  8531. {
  8532. try { con.close(); } catch (Exception e) {}
  8533. }
  8534. }
  8535.  
  8536. /**
  8537. * Return the number of Henna empty slot of the L2PcInstance.<BR><BR>
  8538. */
  8539. public int getHennaEmptySlots()
  8540. {
  8541. int totalSlots = 0;
  8542. if (getClassId().level() == 1)
  8543. totalSlots = 2;
  8544. else
  8545. totalSlots = 3;
  8546.  
  8547. for (int i = 0; i < 3; i++)
  8548. {
  8549. if (_henna[i] != null)
  8550. totalSlots--;
  8551. }
  8552.  
  8553. if (totalSlots <= 0)
  8554. return 0;
  8555.  
  8556. return totalSlots;
  8557. }
  8558.  
  8559. /**
  8560. * 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>
  8561. */
  8562. public boolean removeHenna(int slot)
  8563. {
  8564. if (slot < 1 || slot > 3)
  8565. return false;
  8566.  
  8567. slot--;
  8568.  
  8569. if (_henna[slot] == null)
  8570. return false;
  8571.  
  8572. L2HennaInstance henna = _henna[slot];
  8573. _henna[slot] = null;
  8574.  
  8575. Connection con = null;
  8576.  
  8577. try
  8578. {
  8579. con = L2DatabaseFactory.getInstance().getConnection();
  8580. PreparedStatement statement = con.prepareStatement(DELETE_CHAR_HENNA);
  8581.  
  8582. statement.setInt(1, getObjectId());
  8583. statement.setInt(2, slot+1);
  8584. statement.setInt(3, getClassIndex());
  8585.  
  8586. statement.execute();
  8587. statement.close();
  8588. }
  8589. catch (Exception e)
  8590. {
  8591. _log.log(Level.SEVERE, "Failed remocing character henna.", e);
  8592. }
  8593. finally
  8594. {
  8595. try { con.close(); } catch (Exception e) {}
  8596. }
  8597.  
  8598. // Calculate Henna modifiers of this L2PcInstance
  8599. recalcHennaStats();
  8600.  
  8601. // Send Server->Client HennaInfo packet to this L2PcInstance
  8602. sendPacket(new HennaInfo(this));
  8603.  
  8604. // Send Server->Client UserInfo packet to this L2PcInstance
  8605. sendPacket(new UserInfo(this));
  8606. sendPacket(new ExBrExtraUserInfo(this));
  8607. // Add the recovered dyes to the player's inventory and notify them.
  8608. getInventory().addItem("Henna", henna.getItemIdDye(), henna.getAmountDyeRequire() / 2, this, null);
  8609.  
  8610. reduceAdena("Henna", henna.getPrice() / 5, this, false);
  8611.  
  8612. SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S);
  8613. sm.addItemName(henna.getItemIdDye());
  8614. sm.addItemNumber(henna.getAmountDyeRequire() / 2);
  8615. sendPacket(sm);
  8616.  
  8617. sendPacket(new SystemMessage(SystemMessageId.SYMBOL_DELETED));
  8618.  
  8619. return true;
  8620. }
  8621.  
  8622. /**
  8623. * 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>
  8624. */
  8625. public boolean addHenna(L2HennaInstance henna)
  8626. {
  8627. for (int i = 0; i < 3; i++)
  8628. {
  8629. if (_henna[i] == null)
  8630. {
  8631. _henna[i] = henna;
  8632.  
  8633. // Calculate Henna modifiers of this L2PcInstance
  8634. recalcHennaStats();
  8635.  
  8636. Connection con = null;
  8637.  
  8638. try
  8639. {
  8640. con = L2DatabaseFactory.getInstance().getConnection();
  8641. PreparedStatement statement = con.prepareStatement(ADD_CHAR_HENNA);
  8642.  
  8643. statement.setInt(1, getObjectId());
  8644. statement.setInt(2, henna.getSymbolId());
  8645. statement.setInt(3, i+1);
  8646. statement.setInt(4, getClassIndex());
  8647.  
  8648. statement.execute();
  8649. statement.close();
  8650. }
  8651. catch (Exception e)
  8652. {
  8653. _log.log(Level.SEVERE, "Failed saving character henna.", e);
  8654. }
  8655. finally
  8656. {
  8657. try { con.close(); } catch (Exception e) {}
  8658. }
  8659.  
  8660. // Send Server->Client HennaInfo packet to this L2PcInstance
  8661. sendPacket(new HennaInfo(this));
  8662.  
  8663. // Send Server->Client UserInfo packet to this L2PcInstance
  8664. sendPacket(new UserInfo(this));
  8665. sendPacket(new ExBrExtraUserInfo(this));
  8666.  
  8667. return true;
  8668. }
  8669. }
  8670. return false;
  8671. }
  8672.  
  8673. /**
  8674. * Calculate Henna modifiers of this L2PcInstance.<BR><BR>
  8675. */
  8676. private void recalcHennaStats()
  8677. {
  8678. _hennaINT = 0;
  8679. _hennaSTR = 0;
  8680. _hennaCON = 0;
  8681. _hennaMEN = 0;
  8682. _hennaWIT = 0;
  8683. _hennaDEX = 0;
  8684.  
  8685. for (int i=0;i<3;i++)
  8686. {
  8687. if (_henna[i]==null)continue;
  8688. _hennaINT += _henna[i].getStatINT();
  8689. _hennaSTR += _henna[i].getStatSTR();
  8690. _hennaMEN += _henna[i].getStatMEM();
  8691. _hennaCON += _henna[i].getStatCON();
  8692. _hennaWIT += _henna[i].getStatWIT();
  8693. _hennaDEX += _henna[i].getStatDEX();
  8694. }
  8695.  
  8696. if (_hennaINT>5)_hennaINT=5;
  8697. if (_hennaSTR>5)_hennaSTR=5;
  8698. if (_hennaMEN>5)_hennaMEN=5;
  8699. if (_hennaCON>5)_hennaCON=5;
  8700. if (_hennaWIT>5)_hennaWIT=5;
  8701. if (_hennaDEX>5)_hennaDEX=5;
  8702. }
  8703.  
  8704. /**
  8705. * Return the Henna of this L2PcInstance corresponding to the selected slot.<BR><BR>
  8706. */
  8707. public L2HennaInstance getHenna(int slot)
  8708. {
  8709. if (slot < 1 || slot > 3)
  8710. return null;
  8711.  
  8712. return _henna[slot - 1];
  8713. }
  8714.  
  8715. /**
  8716. * Return the INT Henna modifier of this L2PcInstance.<BR><BR>
  8717. */
  8718. public int getHennaStatINT()
  8719. {
  8720. return _hennaINT;
  8721. }
  8722.  
  8723. /**
  8724. * Return the STR Henna modifier of this L2PcInstance.<BR><BR>
  8725. */
  8726. public int getHennaStatSTR()
  8727. {
  8728. return _hennaSTR;
  8729. }
  8730.  
  8731. /**
  8732. * Return the CON Henna modifier of this L2PcInstance.<BR><BR>
  8733. */
  8734. public int getHennaStatCON()
  8735. {
  8736. return _hennaCON;
  8737. }
  8738.  
  8739. /**
  8740. * Return the MEN Henna modifier of this L2PcInstance.<BR><BR>
  8741. */
  8742. public int getHennaStatMEN()
  8743. {
  8744. return _hennaMEN;
  8745. }
  8746.  
  8747. /**
  8748. * Return the WIT Henna modifier of this L2PcInstance.<BR><BR>
  8749. */
  8750. public int getHennaStatWIT()
  8751. {
  8752. return _hennaWIT;
  8753. }
  8754.  
  8755. /**
  8756. * Return the DEX Henna modifier of this L2PcInstance.<BR><BR>
  8757. */
  8758. public int getHennaStatDEX()
  8759. {
  8760. return _hennaDEX;
  8761. }
  8762.  
  8763. /**
  8764. * Return True if the L2PcInstance is autoAttackable.<BR><BR>
  8765. *
  8766. * <B><U> Actions</U> :</B><BR><BR>
  8767. * <li>Check if the attacker isn't the L2PcInstance Pet </li>
  8768. * <li>Check if the attacker is L2MonsterInstance</li>
  8769. * <li>If the attacker is a L2PcInstance, check if it is not in the same party </li>
  8770. * <li>Check if the L2PcInstance has Karma </li>
  8771. * <li>If the attacker is a L2PcInstance, check if it is not in the same siege clan (Attacker, Defender) </li><BR><BR>
  8772. *
  8773. */
  8774. @Override
  8775. public boolean isAutoAttackable(L2Character attacker)
  8776. {
  8777. // Check if the attacker isn't the L2PcInstance Pet
  8778. if (attacker == this || attacker == getPet())
  8779. return false;
  8780.  
  8781. // TODO: check for friendly mobs
  8782. // Check if the attacker is a L2MonsterInstance
  8783. if (attacker instanceof L2MonsterInstance)
  8784. return true;
  8785.  
  8786. // Check if the attacker is not in the same party
  8787. if (getParty() != null && getParty().getPartyMembers().contains(attacker))
  8788. return false;
  8789.  
  8790. // Check if the attacker is in olympia and olympia start
  8791. if (attacker instanceof L2PcInstance && ((L2PcInstance)attacker).isInOlympiadMode() ){
  8792. if (isInOlympiadMode() && isOlympiadStart() && ((L2PcInstance)attacker).getOlympiadGameId()==getOlympiadGameId())
  8793. return true;
  8794. else
  8795. return false;
  8796. }
  8797.  
  8798. // Check if the attacker is in TvT and TvT is started
  8799. if (TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(getObjectId()))
  8800. return true;
  8801.  
  8802. // Check if the attacker is not in the same clan
  8803. if (getClan() != null && attacker != null && getClan().isMember(attacker.getObjectId()))
  8804. return false;
  8805.  
  8806. if(attacker instanceof L2Playable && isInsideZone(ZONE_PEACE))
  8807. return false;
  8808.  
  8809. // Check if the L2PcInstance has Karma
  8810. if (getKarma() > 0 || getPvpFlag() > 0)
  8811. return true;
  8812.  
  8813. // Check if the attacker is a L2PcInstance
  8814. if (attacker instanceof L2PcInstance)
  8815. {
  8816. // is AutoAttackable if both players are in the same duel and the duel is still going on
  8817. if ( getDuelState() == Duel.DUELSTATE_DUELLING
  8818. && getDuelId() == ((L2PcInstance)attacker).getDuelId() )
  8819. return true;
  8820. // Check if the L2PcInstance is in an arena or a siege area
  8821. if (isInsideZone(ZONE_PVP) && ((L2PcInstance)attacker).isInsideZone(ZONE_PVP))
  8822. return true;
  8823.  
  8824. if (getClan() != null)
  8825. {
  8826. Siege siege = SiegeManager.getInstance().getSiege(getX(), getY(), getZ());
  8827. if (siege != null)
  8828. {
  8829. // Check if a siege is in progress and if attacker and the L2PcInstance aren't in the Defender clan
  8830. if (siege.checkIsDefender(((L2PcInstance)attacker).getClan()) &&
  8831. siege.checkIsDefender(getClan()))
  8832. return false;
  8833.  
  8834. // Check if a siege is in progress and if attacker and the L2PcInstance aren't in the Attacker clan
  8835. if (siege.checkIsAttacker(((L2PcInstance)attacker).getClan()) &&
  8836. siege.checkIsAttacker(getClan()))
  8837. return false;
  8838. }
  8839.  
  8840. // Check if clan is at war
  8841. if (getClan() != null && ((L2PcInstance)attacker).getClan() != null
  8842. && (getClan().isAtWarWith(((L2PcInstance)attacker).getClanId())
  8843. && ((L2PcInstance)attacker).getClan().isAtWarWith(getClanId())
  8844. && getWantsPeace() == 0
  8845. && ((L2PcInstance)attacker).getWantsPeace() == 0
  8846. && !isAcademyMember()))
  8847. return true;
  8848. }
  8849. }
  8850. else if (attacker instanceof L2SiegeGuardInstance || attacker instanceof L2FortSiegeGuardInstance)
  8851. {
  8852. if (getClan() != null)
  8853. {
  8854. Siege siege = SiegeManager.getInstance().getSiege(this);
  8855. return (siege != null && siege.checkIsAttacker(getClan()));
  8856. }
  8857. }
  8858.  
  8859. return false;
  8860. }
  8861.  
  8862.  
  8863. /**
  8864. * Check if the active L2Skill can be casted.<BR><BR>
  8865. *
  8866. * <B><U> Actions</U> :</B><BR><BR>
  8867. * <li>Check if the skill isn't toggle and is offensive </li>
  8868. * <li>Check if the target is in the skill cast range </li>
  8869. * <li>Check if the skill is Spoil type and if the target isn't already spoiled </li>
  8870. * <li>Check if the caster owns enought consummed Item, enough HP and MP to cast the skill </li>
  8871. * <li>Check if the caster isn't sitting </li>
  8872. * <li>Check if all skills are enabled and this skill is enabled </li><BR><BR>
  8873. * <li>Check if the caster own the weapon needed </li><BR><BR>
  8874. * <li>Check if the skill is active </li><BR><BR>
  8875. * <li>Check if all casting conditions are completed</li><BR><BR>
  8876. * <li>Notify the AI with AI_INTENTION_CAST and target</li><BR><BR>
  8877. *
  8878. * @param skill The L2Skill to use
  8879. * @param forceUse used to force ATTACK on players
  8880. * @param dontMove used to prevent movement, if not in range
  8881. *
  8882. */
  8883. public void useMagic(L2Skill skill, boolean forceUse, boolean dontMove)
  8884. {
  8885. // Check if the skill is active
  8886. if (skill.isPassive())
  8887. {
  8888. // just ignore the passive skill request. why does the client send it anyway ??
  8889. // Send a Server->Client packet ActionFailed to the L2PcInstance
  8890. sendPacket(ActionFailed.STATIC_PACKET);
  8891. return;
  8892. }
  8893.  
  8894. //************************************* Check Casting in Progress *******************************************
  8895.  
  8896. // If a skill is currently being used, queue this one if this is not the same
  8897. if (isCastingNow())
  8898. {
  8899. SkillDat currentSkill = getCurrentSkill();
  8900. // Check if new skill different from current skill in progress
  8901. if (currentSkill != null && skill.getId() == currentSkill.getSkillId())
  8902. {
  8903. sendPacket(ActionFailed.STATIC_PACKET);
  8904. return;
  8905. }
  8906.  
  8907. if (Config.DEBUG && getQueuedSkill() != null)
  8908. _log.info(getQueuedSkill().getSkill().getName() + " is already queued for " + getName() + ".");
  8909.  
  8910. // Create a new SkillDat object and queue it in the player _queuedSkill
  8911. setQueuedSkill(skill, forceUse, dontMove);
  8912. sendPacket(ActionFailed.STATIC_PACKET);
  8913. return;
  8914. }
  8915. setIsCastingNow(true);
  8916. // Create a new SkillDat object and set the player _currentSkill
  8917. // This is used mainly to save & queue the button presses, since L2Character has
  8918. // _lastSkillCast which could otherwise replace it
  8919. setCurrentSkill(skill, forceUse, dontMove);
  8920.  
  8921. if (getQueuedSkill() != null) // wiping out previous values, after casting has been aborted
  8922. setQueuedSkill(null, false, false);
  8923.  
  8924. if (!checkUseMagicConditions(skill, forceUse, dontMove))
  8925. {
  8926. setIsCastingNow(false);
  8927. return;
  8928. }
  8929.  
  8930. // Check if the target is correct and Notify the AI with AI_INTENTION_CAST and target
  8931. L2Object target = null;
  8932.  
  8933. switch (skill.getTargetType())
  8934. {
  8935. case TARGET_AURA: // AURA, SELF should be cast even if no target has been found
  8936. case TARGET_FRONT_AURA:
  8937. case TARGET_BEHIND_AURA:
  8938. case TARGET_GROUND:
  8939. case TARGET_SELF:
  8940. target = this;
  8941. break;
  8942. default:
  8943.  
  8944. // Get the first target of the list
  8945. target = skill.getFirstOfTargetList(this);
  8946. break;
  8947. }
  8948.  
  8949. // Notify the AI with AI_INTENTION_CAST and target
  8950. getAI().setIntention(CtrlIntention.AI_INTENTION_CAST, skill, target);
  8951. }
  8952.  
  8953. private boolean checkUseMagicConditions(L2Skill skill, boolean forceUse, boolean dontMove)
  8954. {
  8955. L2SkillType sklType = skill.getSkillType();
  8956.  
  8957. //************************************* Check Player State *******************************************
  8958.  
  8959. // Abnormal effects(ex : Stun, Sleep...) are checked in L2Character useMagic()
  8960.  
  8961. if (isOutOfControl())
  8962. {
  8963. sendPacket(ActionFailed.STATIC_PACKET);
  8964. return false;
  8965. }
  8966.  
  8967. // Check if the player is dead
  8968. if (isDead())
  8969. {
  8970. abortCast();
  8971. // Send a Server->Client packet ActionFailed to the L2PcInstance
  8972. sendPacket(ActionFailed.STATIC_PACKET);
  8973. return false;
  8974. }
  8975.  
  8976. if (isFishing() && (sklType != L2SkillType.PUMPING &&
  8977. sklType != L2SkillType.REELING && sklType != L2SkillType.FISHING))
  8978. {
  8979. //Only fishing skills are available
  8980. sendPacket(new SystemMessage(SystemMessageId.ONLY_FISHING_SKILLS_NOW));
  8981. return false;
  8982. }
  8983.  
  8984. if (inObserverMode())
  8985. {
  8986. sendPacket(new SystemMessage(SystemMessageId.OBSERVERS_CANNOT_PARTICIPATE));
  8987. abortCast();
  8988. sendPacket(ActionFailed.STATIC_PACKET);
  8989. return false;
  8990. }
  8991.  
  8992. // Check if the caster is sitting
  8993. if (isSitting())
  8994. {
  8995. // Send a System Message to the caster
  8996. sendPacket(new SystemMessage(SystemMessageId.CANT_MOVE_SITTING));
  8997.  
  8998. // Send a Server->Client packet ActionFailed to the L2PcInstance
  8999. sendPacket(ActionFailed.STATIC_PACKET);
  9000. return false;
  9001. }
  9002.  
  9003. // Check if the skill type is TOGGLE
  9004. if (skill.isToggle())
  9005. {
  9006. // Get effects of the skill
  9007. L2Effect effect = getFirstEffect(skill);
  9008.  
  9009. if (effect != null)
  9010. {
  9011. effect.exit();
  9012.  
  9013. // Send a Server->Client packet ActionFailed to the L2PcInstance
  9014. sendPacket(ActionFailed.STATIC_PACKET);
  9015. return false;
  9016. }
  9017. }
  9018.  
  9019. // Check if the player uses "Fake Death" skill
  9020. // Note: do not check this before TOGGLE reset
  9021. if (isFakeDeath())
  9022. {
  9023. // Send a Server->Client packet ActionFailed to the L2PcInstance
  9024. sendPacket(ActionFailed.STATIC_PACKET);
  9025. return false;
  9026. }
  9027.  
  9028. //************************************* Check Target *******************************************
  9029. // Create and set a L2Object containing the target of the skill
  9030. L2Object target = null;
  9031. SkillTargetType sklTargetType = skill.getTargetType();
  9032. Point3D worldPosition = getCurrentSkillWorldPosition();
  9033.  
  9034. if (sklTargetType == SkillTargetType.TARGET_GROUND && worldPosition == null)
  9035. {
  9036. _log.info("WorldPosition is null for skill: "+skill.getName() + ", player: " + getName() + ".");
  9037. sendPacket(ActionFailed.STATIC_PACKET);
  9038. return false;
  9039. }
  9040.  
  9041. switch (sklTargetType)
  9042. {
  9043. // Target the player if skill type is AURA, PARTY, CLAN or SELF
  9044. case TARGET_AURA:
  9045. case TARGET_FRONT_AURA:
  9046. case TARGET_BEHIND_AURA:
  9047. case TARGET_PARTY:
  9048. case TARGET_ALLY:
  9049. case TARGET_CLAN:
  9050. case TARGET_PARTY_CLAN:
  9051. case TARGET_GROUND:
  9052. case TARGET_SELF:
  9053. target = this;
  9054. break;
  9055. case TARGET_PET:
  9056. case TARGET_SUMMON:
  9057. target = getPet();
  9058. break;
  9059. default:
  9060. target = getTarget();
  9061. break;
  9062. }
  9063.  
  9064. // Check the validity of the target
  9065. if (target == null)
  9066. {
  9067. sendPacket(ActionFailed.STATIC_PACKET);
  9068. return false;
  9069. }
  9070.  
  9071. // skills can be used on Walls and Doors only during siege
  9072. if(target instanceof L2DoorInstance )
  9073. {
  9074. boolean isCastle = (((L2DoorInstance) target).getCastle() != null
  9075. && ((L2DoorInstance) target).getCastle().getCastleId() > 0
  9076. && ((L2DoorInstance) target).getCastle().getSiege().getIsInProgress());
  9077. boolean isFort = (((L2DoorInstance) target).getFort() != null
  9078. && ((L2DoorInstance) target).getFort().getFortId() > 0
  9079. && ((L2DoorInstance) target).getFort().getSiege().getIsInProgress()
  9080. && !((L2DoorInstance) target).getIsCommanderDoor());
  9081. if ((!isCastle && !isFort)&&(((L2DoorInstance) target).isUnlockable() && skill.getSkillType() != L2SkillType.UNLOCK))
  9082. return false;
  9083. }
  9084.  
  9085. // Are the target and the player in the same duel?
  9086. if (isInDuel())
  9087. {
  9088. if (!(target instanceof L2PcInstance && ((L2PcInstance)target).getDuelId() == getDuelId()))
  9089. {
  9090. sendMessage("You cannot do this while duelling.");
  9091. sendPacket(ActionFailed.STATIC_PACKET);
  9092. return false;
  9093. }
  9094. }
  9095.  
  9096. //************************************* Check skill availability *******************************************
  9097.  
  9098. // Check if it's ok to summon
  9099. // siege golem (13), Wild Hog Cannon (299), Swoop Cannon (448)
  9100. if ((skill.getId() == 13 || skill.getId() == 299 || skill.getId() == 448)
  9101. && ((!SiegeManager.getInstance().checkIfOkToSummon(this, false)
  9102. && !FortSiegeManager.getInstance().checkIfOkToSummon(this, false))||(SevenSigns.getInstance().CheckSummonConditions(this))))
  9103. return false;
  9104.  
  9105. // Check if this skill is enabled (ex : reuse time)
  9106. if (isSkillDisabled(skill.getId()))
  9107. {
  9108. SystemMessage sm = null;
  9109. FastMap<Integer, TimeStamp> timeStamp = getReuseTimeStamp();
  9110.  
  9111. if (timeStamp != null && timeStamp.containsKey(skill.getId()))
  9112. {
  9113. int remainingTime = (int)(_reuseTimeStamps.get(skill.getId()).getRemaining()/1000);
  9114. int hours = remainingTime/3600;
  9115. int minutes = (remainingTime%3600)/60;
  9116. int seconds = (remainingTime%60);
  9117. if (hours > 0)
  9118. {
  9119. sm = new SystemMessage(SystemMessageId.S2_HOURS_S3_MINUTES_S4_SECONDS_REMAINING_FOR_REUSE_S1);
  9120. sm.addSkillName(skill);
  9121. sm.addNumber(hours);
  9122. sm.addNumber(minutes);
  9123. }
  9124. else if (minutes > 0)
  9125. {
  9126. sm = new SystemMessage(SystemMessageId.S2_MINUTES_S3_SECONDS_REMAINING_FOR_REUSE_S1);
  9127. sm.addSkillName(skill);
  9128. sm.addNumber(minutes);
  9129. }
  9130. else
  9131. {
  9132. sm = new SystemMessage(SystemMessageId.S2_SECONDS_REMAINING_FOR_REUSE_S1);
  9133. sm.addSkillName(skill);
  9134. }
  9135.  
  9136. sm.addNumber(seconds);
  9137. }
  9138. else
  9139. {
  9140. sm = new SystemMessage(SystemMessageId.S1_PREPARED_FOR_REUSE);
  9141. sm.addSkillName(skill);
  9142. }
  9143.  
  9144. sendPacket(sm);
  9145. return false;
  9146. }
  9147.  
  9148. //************************************* Check Consumables *******************************************
  9149.  
  9150. // Check if spell consumes a Soul
  9151. if (skill.getSoulConsumeCount() > 0)
  9152. {
  9153. if (getSouls() < skill.getSoulConsumeCount())
  9154. {
  9155. sendPacket(new SystemMessage(SystemMessageId.THERE_IS_NOT_ENOUGH_SOUL));
  9156. return false;
  9157. }
  9158. }
  9159. //************************************* Check casting conditions *******************************************
  9160.  
  9161. // Check if all casting conditions are completed
  9162. if (!skill.checkCondition(this, target, false))
  9163. {
  9164. // Send a Server->Client packet ActionFailed to the L2PcInstance
  9165. sendPacket(ActionFailed.STATIC_PACKET);
  9166. return false;
  9167. }
  9168.  
  9169. //************************************* Check Skill Type *******************************************
  9170.  
  9171. // Check if this is offensive magic skill
  9172. if (skill.isOffensive())
  9173. {
  9174. if ((isInsidePeaceZone(this, target)) && !getAccessLevel().allowPeaceAttack())
  9175. {
  9176. // If L2Character or target is in a peace zone, send a system message TARGET_IN_PEACEZONE a Server->Client packet ActionFailed
  9177. sendPacket(new SystemMessage(SystemMessageId.TARGET_IN_PEACEZONE));
  9178. sendPacket(ActionFailed.STATIC_PACKET);
  9179. return false;
  9180. }
  9181.  
  9182. if (isInOlympiadMode() && !isOlympiadStart()){
  9183. // if L2PcInstance is in Olympia and the match isn't already start, send a Server->Client packet ActionFailed
  9184. sendPacket(ActionFailed.STATIC_PACKET);
  9185. return false;
  9186. }
  9187.  
  9188. // Check if the target is attackable
  9189. if (!target.isAttackable() && !getAccessLevel().allowPeaceAttack())
  9190. {
  9191. // If target is not attackable, send a Server->Client packet ActionFailed
  9192. sendPacket(ActionFailed.STATIC_PACKET);
  9193. return false;
  9194. }
  9195.  
  9196. // Check if a Forced ATTACK is in progress on non-attackable target
  9197. if (!target.isAutoAttackable(this) && !forceUse)
  9198. {
  9199. switch (sklTargetType)
  9200. {
  9201. case TARGET_AURA:
  9202. case TARGET_FRONT_AURA:
  9203. case TARGET_BEHIND_AURA:
  9204. case TARGET_CLAN:
  9205. case TARGET_PARTY_CLAN:
  9206. case TARGET_ALLY:
  9207. case TARGET_PARTY:
  9208. case TARGET_SELF:
  9209. case TARGET_GROUND:
  9210. break;
  9211. default: // Send a Server->Client packet ActionFailed to the L2PcInstance
  9212. sendPacket(ActionFailed.STATIC_PACKET);
  9213. return false;
  9214. }
  9215. }
  9216.  
  9217. // Check if the target is in the skill cast range
  9218. if (dontMove)
  9219. {
  9220. // Calculate the distance between the L2PcInstance and the target
  9221. if (sklTargetType == SkillTargetType.TARGET_GROUND)
  9222. {
  9223. if (!isInsideRadius(worldPosition.getX(), worldPosition.getY(), worldPosition.getZ(), skill.getCastRange()+getTemplate().collisionRadius, false, false))
  9224. {
  9225. // Send a System Message to the caster
  9226. sendPacket(new SystemMessage(SystemMessageId.TARGET_TOO_FAR));
  9227.  
  9228. // Send a Server->Client packet ActionFailed to the L2PcInstance
  9229. sendPacket(ActionFailed.STATIC_PACKET);
  9230. return false;
  9231. }
  9232. }
  9233. else if (skill.getCastRange() > 0 && !isInsideRadius(target, skill.getCastRange()+getTemplate().collisionRadius, false, false))
  9234. {
  9235. // Send a System Message to the caster
  9236. sendPacket(new SystemMessage(SystemMessageId.TARGET_TOO_FAR));
  9237.  
  9238. // Send a Server->Client packet ActionFailed to the L2PcInstance
  9239. sendPacket(ActionFailed.STATIC_PACKET);
  9240. return false;
  9241. }
  9242. }
  9243. }
  9244.  
  9245. if(skill.getSkillType() == L2SkillType.INSTANT_JUMP)
  9246. {
  9247. // You cannot jump while rooted right ;)
  9248. if(this.isRooted())
  9249. {
  9250. // Sends message that skill cannot be used...
  9251. SystemMessage sm = new SystemMessage(SystemMessageId.S1_CANNOT_BE_USED);
  9252. sm.addSkillName(skill.getId());
  9253. sendPacket(sm);
  9254.  
  9255. // Send a Server->Client packet ActionFailed to the L2PcInstance
  9256. sendPacket(ActionFailed.STATIC_PACKET);
  9257.  
  9258. return false;
  9259. }
  9260. // And this skill cannot be used in peace zone, not even on NPCs!
  9261. if(this.isInsideZone(L2Character.ZONE_PEACE))
  9262. {
  9263. //Sends a sys msg to client
  9264. sendPacket(new SystemMessage(SystemMessageId.TARGET_IN_PEACEZONE));
  9265.  
  9266. // Send a Server->Client packet ActionFailed to the L2PcInstance
  9267. sendPacket(ActionFailed.STATIC_PACKET);
  9268.  
  9269. return false;
  9270. }
  9271.  
  9272. }
  9273. // Check if the skill is defensive
  9274. if (!skill.isOffensive() && target instanceof L2MonsterInstance && !forceUse && !skill.isNeutral())
  9275. {
  9276. // check if the target is a monster and if force attack is set.. if not then we don't want to cast.
  9277. switch (sklTargetType)
  9278. {
  9279. case TARGET_PET:
  9280. case TARGET_SUMMON:
  9281. case TARGET_AURA:
  9282. case TARGET_FRONT_AURA:
  9283. case TARGET_BEHIND_AURA:
  9284. case TARGET_CLAN:
  9285. case TARGET_PARTY_CLAN:
  9286. case TARGET_SELF:
  9287. case TARGET_PARTY:
  9288. case TARGET_ALLY:
  9289. case TARGET_CORPSE_MOB:
  9290. case TARGET_AREA_CORPSE_MOB:
  9291. case TARGET_GROUND:
  9292. break;
  9293. default:
  9294. {
  9295. switch (sklType)
  9296. {
  9297. case BEAST_FEED:
  9298. case DELUXE_KEY_UNLOCK:
  9299. case UNLOCK:
  9300. break;
  9301. default:
  9302. sendPacket(ActionFailed.STATIC_PACKET);
  9303. return false;
  9304. }
  9305. break;
  9306. }
  9307. }
  9308. }
  9309.  
  9310. // Check if the skill is Spoil type and if the target isn't already spoiled
  9311. if (sklType == L2SkillType.SPOIL)
  9312. {
  9313. if (!(target instanceof L2MonsterInstance))
  9314. {
  9315. // Send a System Message to the L2PcInstance
  9316. sendPacket(new SystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  9317.  
  9318. // Send a Server->Client packet ActionFailed to the L2PcInstance
  9319. sendPacket(ActionFailed.STATIC_PACKET);
  9320. return false;
  9321. }
  9322. }
  9323.  
  9324. // Check if the skill is Sweep type and if conditions not apply
  9325. if (sklType == L2SkillType.SWEEP && target instanceof L2Attackable)
  9326. {
  9327. int spoilerId = ((L2Attackable) target).getIsSpoiledBy();
  9328.  
  9329. if (((L2Attackable) target).isDead())
  9330. {
  9331. if (!((L2Attackable) target).isSpoil())
  9332. {
  9333. // Send a System Message to the L2PcInstance
  9334. sendPacket(new SystemMessage(SystemMessageId.SWEEPER_FAILED_TARGET_NOT_SPOILED));
  9335.  
  9336. // Send a Server->Client packet ActionFailed to the L2PcInstance
  9337. sendPacket(ActionFailed.STATIC_PACKET);
  9338. return false;
  9339. }
  9340.  
  9341. if (getObjectId() != spoilerId && !isInLooterParty(spoilerId))
  9342. {
  9343. // Send a System Message to the L2PcInstance
  9344. sendPacket(new SystemMessage(SystemMessageId.SWEEP_NOT_ALLOWED));
  9345.  
  9346. // Send a Server->Client packet ActionFailed to the L2PcInstance
  9347. sendPacket(ActionFailed.STATIC_PACKET);
  9348. return false;
  9349. }
  9350. }
  9351. }
  9352.  
  9353. // Check if the skill is Drain Soul (Soul Crystals) and if the target is a MOB
  9354. if (sklType == L2SkillType.DRAIN_SOUL)
  9355. {
  9356. if (!(target instanceof L2MonsterInstance))
  9357. {
  9358. // Send a System Message to the L2PcInstance
  9359. sendPacket(new SystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  9360.  
  9361. // Send a Server->Client packet ActionFailed to the L2PcInstance
  9362. sendPacket(ActionFailed.STATIC_PACKET);
  9363. return false;
  9364. }
  9365. }
  9366.  
  9367. // Check if this is a Pvp skill and target isn't a non-flagged/non-karma player
  9368. switch (sklTargetType)
  9369. {
  9370. case TARGET_PARTY:
  9371. case TARGET_ALLY: // For such skills, checkPvpSkill() is called from L2Skill.getTargetList()
  9372. case TARGET_CLAN: // For such skills, checkPvpSkill() is called from L2Skill.getTargetList()
  9373. case TARGET_PARTY_CLAN: // For such skills, checkPvpSkill() is called from L2Skill.getTargetList()
  9374. case TARGET_AURA:
  9375. case TARGET_FRONT_AURA:
  9376. case TARGET_BEHIND_AURA:
  9377. case TARGET_GROUND:
  9378. case TARGET_SELF:
  9379. break;
  9380. default:
  9381. if (!checkPvpSkill(target, skill) && !getAccessLevel().allowPeaceAttack())
  9382. {
  9383. // Send a System Message to the L2PcInstance
  9384. sendPacket(new SystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
  9385.  
  9386. // Send a Server->Client packet ActionFailed to the L2PcInstance
  9387. sendPacket(ActionFailed.STATIC_PACKET);
  9388. return false;
  9389. }
  9390. }
  9391.  
  9392. if ((sklTargetType == SkillTargetType.TARGET_HOLY && !checkIfOkToCastSealOfRule(CastleManager.getInstance().getCastle(this), false))
  9393. || (sklTargetType == SkillTargetType.TARGET_FLAGPOLE && !checkIfOkToCastFlagDisplay(FortManager.getInstance().getFort(this), false, skill, getTarget()))
  9394. || (sklType == L2SkillType.SIEGEFLAG && !L2SkillSiegeFlag.checkIfOkToPlaceFlag(this, false))
  9395. || (sklType == L2SkillType.STRSIEGEASSAULT && !checkIfOkToUseStriderSiegeAssault(false)))
  9396. {
  9397. sendPacket(ActionFailed.STATIC_PACKET);
  9398. abortCast();
  9399. return false;
  9400. }
  9401.  
  9402. // GeoData Los Check here
  9403. if (skill.getCastRange() > 0)
  9404. {
  9405. if (sklTargetType == SkillTargetType.TARGET_GROUND)
  9406. {
  9407. if (!GeoData.getInstance().canSeeTarget(this, worldPosition))
  9408. {
  9409. sendPacket(new SystemMessage(SystemMessageId.CANT_SEE_TARGET));
  9410. sendPacket(ActionFailed.STATIC_PACKET);
  9411. return false;
  9412. }
  9413. }
  9414. else if (!GeoData.getInstance().canSeeTarget(this, target))
  9415. {
  9416. sendPacket(new SystemMessage(SystemMessageId.CANT_SEE_TARGET));
  9417. sendPacket(ActionFailed.STATIC_PACKET);
  9418. return false;
  9419. }
  9420. }
  9421. // finally, after passing all conditions
  9422. return true;
  9423. }
  9424.  
  9425. public boolean checkIfOkToUseStriderSiegeAssault(boolean isCheckOnly)
  9426. {
  9427. Castle castle = CastleManager.getInstance().getCastle(this);
  9428. Fort fort = FortManager.getInstance().getFort(this);
  9429.  
  9430. if ((castle == null) && (fort == null))
  9431. return false;
  9432.  
  9433. if (castle != null)
  9434. return checkIfOkToUseStriderSiegeAssault(castle, isCheckOnly);
  9435. else
  9436. return checkIfOkToUseStriderSiegeAssault(fort, isCheckOnly);
  9437.  
  9438. }
  9439.  
  9440. public boolean checkIfOkToUseStriderSiegeAssault(Castle castle, boolean isCheckOnly)
  9441. {
  9442. String text = "";
  9443.  
  9444. if (castle == null || castle.getCastleId() <= 0)
  9445. text = "You must be on castle ground to use strider siege assault";
  9446. else if (!castle.getSiege().getIsInProgress())
  9447. text = "You can only use strider siege assault during a siege.";
  9448. else if (!(getTarget() instanceof L2DoorInstance))
  9449. text = "You can only use strider siege assault on doors and walls.";
  9450. else if (!isRidingStrider())
  9451. text = "You can only use strider siege assault when on strider.";
  9452. else
  9453. return true;
  9454.  
  9455. if (!isCheckOnly)
  9456. sendMessage(text);
  9457.  
  9458. return false;
  9459. }
  9460.  
  9461. public boolean checkIfOkToUseStriderSiegeAssault(Fort fort, boolean isCheckOnly)
  9462. {
  9463. String text = "";
  9464.  
  9465. if (fort == null || fort.getFortId() <= 0)
  9466. text = "You must be on fort ground to use strider siege assault";
  9467. else if (!fort.getSiege().getIsInProgress())
  9468. text = "You can only use strider siege assault during a siege.";
  9469. else if (!(getTarget() instanceof L2DoorInstance))
  9470. text = "You can only use strider siege assault on doors and walls.";
  9471. else if (!isRidingStrider())
  9472. text = "You can only use strider siege assault when on strider.";
  9473. else
  9474. return true;
  9475.  
  9476. if (!isCheckOnly)
  9477. sendMessage(text);
  9478.  
  9479. return false;
  9480. }
  9481.  
  9482. public boolean checkIfOkToCastSealOfRule(Castle castle, boolean isCheckOnly)
  9483. {
  9484. String text = "";
  9485.  
  9486. if (castle == null || castle.getCastleId() <= 0)
  9487. text = "You must be on castle ground to use this skill";
  9488. else if (!(getTarget() instanceof L2ArtefactInstance))
  9489. text = "You can only use this skill on an artifact";
  9490. else if (!castle.getSiege().getIsInProgress())
  9491. text = "You can only use this skill during a siege.";
  9492. else if (!Util.checkIfInRange(200, this, getTarget(), true))
  9493. text = "You are not in range of the artifact.";
  9494. else if (castle.getSiege().getAttackerClan(getClan()) == null)
  9495. text = "You must be an attacker to use this skill";
  9496. else
  9497. {
  9498. if (!isCheckOnly)
  9499. {
  9500. SystemMessage sm = new SystemMessage(SystemMessageId.OPPONENT_STARTED_ENGRAVING);
  9501. castle.getSiege().announceToPlayer(sm, false);
  9502. }
  9503. return true;
  9504. }
  9505.  
  9506. if (!isCheckOnly)
  9507. sendMessage(text);
  9508.  
  9509. return false;
  9510. }
  9511.  
  9512. public boolean checkIfOkToCastFlagDisplay(Fort fort, boolean isCheckOnly, L2Skill skill,
  9513. L2Object target)
  9514. {
  9515. SystemMessage sm;
  9516. if (fort == null || fort.getFortId() <= 0)
  9517. {
  9518. sm = new SystemMessage(SystemMessageId.S1_CANNOT_BE_USED);
  9519. sm.addSkillName(skill);
  9520. }
  9521. else if (!fort.getSiege().getIsInProgress())
  9522. {
  9523. sm = new SystemMessage(SystemMessageId.S1_CANNOT_BE_USED);
  9524. sm.addSkillName(skill);
  9525. }
  9526. else if (!Util.checkIfInRange(200, this, getTarget(), true))
  9527. {
  9528. sm = new SystemMessage(SystemMessageId.DIST_TOO_FAR_CASTING_STOPPED);
  9529. }
  9530. else if (fort.getSiege().getAttackerClan(getClan()) == null)
  9531. {
  9532. sm = new SystemMessage(SystemMessageId.S1_CANNOT_BE_USED);
  9533. sm.addSkillName(skill);
  9534. }
  9535. else
  9536. {
  9537. if (!isCheckOnly)
  9538. fort.getSiege().announceToPlayer(new SystemMessage(SystemMessageId.S1_TRYING_RAISE_FLAG), getClan().getName());
  9539. return true;
  9540. }
  9541.  
  9542. if (!isCheckOnly)
  9543. sendPacket(sm);
  9544.  
  9545. return false;
  9546. }
  9547.  
  9548. public boolean isInLooterParty(int LooterId)
  9549. {
  9550. L2PcInstance looter = (L2PcInstance)L2World.getInstance().findObject(LooterId);
  9551.  
  9552. // if L2PcInstance is in a CommandChannel
  9553. if (isInParty() && getParty().isInCommandChannel() && looter != null)
  9554. return getParty().getCommandChannel().getMembers().contains(looter);
  9555.  
  9556. if (isInParty() && looter != null)
  9557. return getParty().getPartyMembers().contains(looter);
  9558.  
  9559. return false;
  9560. }
  9561.  
  9562. /**
  9563. * Check if the requested casting is a Pc->Pc skill cast and if it's a valid pvp condition
  9564. * @param target L2Object instance containing the target
  9565. * @param skill L2Skill instance with the skill being casted
  9566. * @return False if the skill is a pvpSkill and target is not a valid pvp target
  9567. */
  9568. public boolean checkPvpSkill(L2Object target, L2Skill skill)
  9569. {
  9570. return checkPvpSkill(target, skill, false);
  9571. }
  9572.  
  9573. /**
  9574. * Check if the requested casting is a Pc->Pc skill cast and if it's a valid pvp condition
  9575. * @param target L2Object instance containing the target
  9576. * @param skill L2Skill instance with the skill being casted
  9577. * @param srcIsSummon is L2Summon - caster?
  9578. * @return False if the skill is a pvpSkill and target is not a valid pvp target
  9579. */
  9580. public boolean checkPvpSkill(L2Object target, L2Skill skill, boolean srcIsSummon)
  9581. {
  9582. // check for PC->PC Pvp status
  9583. if (
  9584. target != null && // target not null and
  9585. target != this && // target is not self and
  9586. target instanceof L2PcInstance && // target is L2PcInstance and
  9587. !(isInDuel() && ((L2PcInstance)target).getDuelId() == getDuelId()) && // self is not in a duel and attacking opponent
  9588. !isInsideZone(ZONE_PVP) && // Pc is not in PvP zone
  9589. !((L2PcInstance)target).isInsideZone(ZONE_PVP) // target is not in PvP zone
  9590. )
  9591. {
  9592. if(skill.isPvpSkill()) // pvp skill
  9593. {
  9594. if(getClan() != null && ((L2PcInstance)target).getClan() != null)
  9595. {
  9596. if(getClan().isAtWarWith(((L2PcInstance)target).getClan().getClanId()) && ((L2PcInstance)target).getClan().isAtWarWith(getClan().getClanId()))
  9597. return true; // in clan war player can attack whites even with sleep etc.
  9598. }
  9599. if (
  9600. ((L2PcInstance)target).getPvpFlag() == 0 && // target's pvp flag is not set and
  9601. ((L2PcInstance)target).getKarma() == 0 // target has no karma
  9602. )
  9603. return false;
  9604. }
  9605. else if ((getCurrentSkill() != null && !getCurrentSkill().isCtrlPressed() && skill.isOffensive() && !srcIsSummon)
  9606. || (getCurrentPetSkill() != null && !getCurrentPetSkill().isCtrlPressed() && skill.isOffensive() && srcIsSummon))
  9607. {
  9608. if(getClan() != null && ((L2PcInstance)target).getClan() != null)
  9609. {
  9610. if(getClan().isAtWarWith(((L2PcInstance)target).getClan().getClanId()) && ((L2PcInstance)target).getClan().isAtWarWith(getClan().getClanId()))
  9611. return true; // in clan war player can attack whites even without ctrl
  9612. }
  9613. if (
  9614. ((L2PcInstance)target).getPvpFlag() == 0 && // target's pvp flag is not set and
  9615. ((L2PcInstance)target).getKarma() == 0 // target has no karma
  9616. )
  9617. return false;
  9618. }
  9619. }
  9620.  
  9621. return true;
  9622. }
  9623.  
  9624. /**
  9625. * Return True if the L2PcInstance is a Mage.<BR><BR>
  9626. */
  9627. public boolean isMageClass()
  9628. {
  9629. return getClassId().isMage();
  9630. }
  9631.  
  9632.  
  9633. public boolean isMounted()
  9634. {
  9635. return _mountType > 0;
  9636. }
  9637.  
  9638. /**
  9639. * Set the type of Pet mounted (0 : none, 1 : Stridder, 2 : Wyvern) and send a Server->Client packet InventoryUpdate to the L2PcInstance.<BR><BR>
  9640. */
  9641. public boolean checkLandingState()
  9642. {
  9643. // Check if char is in a no landing zone
  9644. if (isInsideZone(ZONE_NOLANDING))
  9645. return true;
  9646. else
  9647. // if this is a castle that is currently being sieged, and the rider is NOT a castle owner
  9648. // he cannot land.
  9649. // castle owner is the leader of the clan that owns the castle where the pc is
  9650. if (isInsideZone(ZONE_SIEGE) && !(getClan()!= null &&
  9651. CastleManager.getInstance().getCastle(this) == CastleManager.getInstance().getCastleByOwner(getClan()) &&
  9652. this == getClan().getLeader().getPlayerInstance()))
  9653. return true;
  9654.  
  9655. return false;
  9656. }
  9657.  
  9658. // returns false if the change of mount type fails.
  9659. public boolean setMount(int npcId, int npcLevel, int mountType)
  9660. {
  9661. switch(mountType)
  9662. {
  9663. case 0:
  9664. setIsFlying(false);
  9665. /* not used any more
  9666. setIsRidingFenrirWolf(false);
  9667. setIsRidingWFenrirWolf(false);
  9668. setIsRidingGreatSnowWolf(false);*/
  9669. setIsRidingStrider(false);
  9670. break; //Dismounted
  9671. case 1:
  9672. setIsRidingStrider(true);
  9673. if(isNoble())
  9674. {
  9675. L2Skill striderAssaultSkill = SkillTable.getInstance().getInfo(325, 1);
  9676. addSkill(striderAssaultSkill, false); // not saved to DB
  9677. }
  9678. break;
  9679. case 2:
  9680. setIsFlying(true);
  9681. break; //Flying Wyvern
  9682. case 3:
  9683. /* not used any more
  9684. switch (npcId)
  9685. {
  9686. case 16041:
  9687. setIsRidingFenrirWolf(true);
  9688. break;
  9689. case 16042:
  9690. setIsRidingWFenrirWolf(true);
  9691. break;
  9692. case 16037:
  9693. setIsRidingGreatSnowWolf(true);
  9694. break;
  9695. }*/
  9696. break;
  9697. }
  9698.  
  9699. _mountType = mountType;
  9700. _mountNpcId = npcId;
  9701. _mountLevel = npcLevel;
  9702.  
  9703. return true;
  9704. }
  9705.  
  9706. /**
  9707. * Return the type of Pet mounted (0 : none, 1 : Strider, 2 : Wyvern, 3: Wolf).<BR><BR>
  9708. */
  9709. public int getMountType()
  9710. {
  9711. return _mountType;
  9712. }
  9713.  
  9714. @Override
  9715. public final void stopAllEffects()
  9716. {
  9717. super.stopAllEffects();
  9718. updateAndBroadcastStatus(2);
  9719. }
  9720.  
  9721. @Override
  9722. public final void stopAllEffectsExceptThoseThatLastThroughDeath()
  9723. {
  9724. super.stopAllEffectsExceptThoseThatLastThroughDeath();
  9725. updateAndBroadcastStatus(2);
  9726. }
  9727. /**
  9728. * Send a Server->Client packet UserInfo to this L2PcInstance and CharInfo to all L2PcInstance in its _KnownPlayers.<BR><BR>
  9729. *
  9730. * <B><U> Concept</U> :</B><BR><BR>
  9731. * Others L2PcInstance in the detection area of the L2PcInstance are identified in <B>_knownPlayers</B>.
  9732. * 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>
  9733. *
  9734. * <B><U> Actions</U> :</B><BR><BR>
  9735. * <li>Send a Server->Client packet UserInfo to this L2PcInstance (Public and Private Data)</li>
  9736. * <li>Send a Server->Client packet CharInfo to all L2PcInstance in _KnownPlayers of the L2PcInstance (Public data only)</li><BR><BR>
  9737. *
  9738. * <FONT COLOR=#FF0000><B> <U>Caution</U> : DON'T SEND UserInfo packet to other players instead of CharInfo packet.
  9739. * Indeed, UserInfo packet contains PRIVATE DATA as MaxHP, STR, DEX...</B></FONT><BR><BR>
  9740. *
  9741. */
  9742. @Override
  9743. public void updateAbnormalEffect()
  9744. {
  9745. broadcastUserInfo();
  9746. }
  9747.  
  9748. /**
  9749. * Disable the Inventory and create a new task to enable it after 1.5s.<BR><BR>
  9750. */
  9751. public void tempInventoryDisable()
  9752. {
  9753. _inventoryDisable = true;
  9754.  
  9755. ThreadPoolManager.getInstance().scheduleGeneral(new InventoryEnable(), 1500);
  9756. }
  9757.  
  9758. public boolean isBot()
  9759. {
  9760. return botCheck;
  9761. }
  9762.  
  9763. public void setBot(boolean bot)
  9764. {
  9765. botCheck = bot;
  9766. }
  9767.  
  9768. /**
  9769. * Return True if the Inventory is disabled.<BR><BR>
  9770. */
  9771. public boolean isInventoryDisabled()
  9772. {
  9773. return _inventoryDisable;
  9774. }
  9775.  
  9776. class InventoryEnable implements Runnable
  9777. {
  9778. public void run()
  9779. {
  9780. _inventoryDisable = false;
  9781. }
  9782. }
  9783.  
  9784. public Map<Integer, L2CubicInstance> getCubics()
  9785. {
  9786. return _cubics;
  9787. }
  9788.  
  9789. /**
  9790. * Add a L2CubicInstance to the L2PcInstance _cubics.<BR><BR>
  9791. */
  9792. public void addCubic(int id, int level, double matk, int activationtime, int activationchance, int totalLifetime, boolean givenByOther)
  9793. {
  9794. if (Config.DEBUG)
  9795. _log.info("L2PcInstance(" + getName() + "): addCubic(" + id + "|" + level + "|" + matk + ")");
  9796. L2CubicInstance cubic = new L2CubicInstance(this, id, level, (int) matk, activationtime, activationchance, totalLifetime, givenByOther);
  9797.  
  9798. _cubics.put(id, cubic);
  9799. }
  9800.  
  9801. /**
  9802. * Remove a L2CubicInstance from the L2PcInstance _cubics.<BR><BR>
  9803. */
  9804. public void delCubic(int id)
  9805. {
  9806. _cubics.remove(id);
  9807. }
  9808.  
  9809. /**
  9810. * Return the L2CubicInstance corresponding to the Identifier of the L2PcInstance _cubics.<BR><BR>
  9811. */
  9812. public L2CubicInstance getCubic(int id)
  9813. {
  9814. return _cubics.get(id);
  9815. }
  9816.  
  9817. @Override
  9818. public String toString()
  9819. {
  9820. return "player "+getName();
  9821. }
  9822.  
  9823. /**
  9824. * Return the modifier corresponding to the Enchant Effect of the Active Weapon (Min : 127).<BR><BR>
  9825. */
  9826. public int getEnchantEffect()
  9827. {
  9828. L2ItemInstance wpn = getActiveWeaponInstance();
  9829.  
  9830. if (wpn == null)
  9831. return 0;
  9832.  
  9833. return Math.min(127, wpn.getEnchantLevel());
  9834. }
  9835.  
  9836. /**
  9837. * Set the _lastFolkNpc of the L2PcInstance corresponding to the last Folk wich one the player talked.<BR><BR>
  9838. */
  9839. public void setLastFolkNPC(L2Npc folkNpc)
  9840. {
  9841. _lastFolkNpc = folkNpc;
  9842. }
  9843.  
  9844. /**
  9845. * Return the _lastFolkNpc of the L2PcInstance corresponding to the last Folk wich one the player talked.<BR><BR>
  9846. */
  9847. public L2Npc getLastFolkNPC()
  9848. {
  9849. return _lastFolkNpc;
  9850. }
  9851.  
  9852. /**
  9853. * Return True if L2PcInstance is a participant in the Festival of Darkness.<BR><BR>
  9854. */
  9855. public boolean isFestivalParticipant()
  9856. {
  9857. return SevenSignsFestival.getInstance().isParticipant(this);
  9858. }
  9859.  
  9860. public void addAutoSoulShot(int itemId)
  9861. {
  9862. _activeSoulShots.put(itemId, itemId);
  9863. }
  9864.  
  9865. public void removeAutoSoulShot(int itemId)
  9866. {
  9867. _activeSoulShots.remove(itemId);
  9868. }
  9869.  
  9870. public Map<Integer, Integer> getAutoSoulShot()
  9871. {
  9872. return _activeSoulShots;
  9873. }
  9874.  
  9875. public void rechargeAutoSoulShot(boolean physical, boolean magic, boolean summon)
  9876. {
  9877. L2ItemInstance item;
  9878. IItemHandler handler;
  9879.  
  9880. if (_activeSoulShots == null || _activeSoulShots.isEmpty())
  9881. return;
  9882.  
  9883. try
  9884. {
  9885. Collection<Integer> vals = _activeSoulShots.values();
  9886.  
  9887. for (int itemId : vals)
  9888. {
  9889. item = getInventory().getItemByItemId(itemId);
  9890.  
  9891. if (item != null)
  9892. {
  9893. if (magic)
  9894. {
  9895. if (!summon)
  9896. {
  9897. switch(itemId)
  9898. {
  9899. case 2509: case 2510: case 2511: case 2512:
  9900. case 2513: case 2514: case 3947:
  9901. case 3948: case 3949: case 3950:
  9902. case 3951: case 3952: case 5790:
  9903. case 22072: case 22073: case 22074:
  9904. case 22075: case 22076: case 22077:
  9905. case 22078: case 22079: case 22080:
  9906. case 22081:
  9907. handler = ItemHandler.getInstance().getItemHandler(item.getEtcItem());
  9908.  
  9909. if (handler != null)
  9910. handler.useItem(this, item);
  9911.  
  9912. break;
  9913. }
  9914. }
  9915. else
  9916. {
  9917. switch(itemId)
  9918. {
  9919. case 6646: case 6647:
  9920. case 20333: case 20334:
  9921. handler = ItemHandler.getInstance().getItemHandler(item.getEtcItem());
  9922.  
  9923. if (handler != null)
  9924. handler.useItem(this, item);
  9925. break;
  9926. }
  9927. }
  9928. }
  9929.  
  9930. if (physical)
  9931. {
  9932. if (!summon)
  9933. {
  9934. switch(itemId)
  9935. {
  9936. case 1463: case 1464: case 1465:
  9937. case 1466: case 1467: case 1835:
  9938. case 5789: case 22082: case 22083:
  9939. case 22084: case 22085: case 22086:
  9940.  
  9941. handler = ItemHandler.getInstance().getItemHandler(item.getEtcItem());
  9942.  
  9943. if (handler != null)
  9944. handler.useItem(this, item);
  9945.  
  9946. break;
  9947. }
  9948. }
  9949. else
  9950. {
  9951. if (itemId == 6645 || itemId == 20332)
  9952. {
  9953. handler = ItemHandler.getInstance().getItemHandler(item.getEtcItem());
  9954.  
  9955. if (handler != null)
  9956. handler.useItem(this, item);
  9957. }
  9958. }
  9959. }
  9960. }
  9961. else
  9962. {
  9963. removeAutoSoulShot(itemId);
  9964. }
  9965. }
  9966. }
  9967. catch (NullPointerException npe)
  9968. {
  9969.  
  9970. }
  9971. }
  9972.  
  9973. private ScheduledFuture<?> _taskWarnUserTakeBreak;
  9974.  
  9975. class WarnUserTakeBreak implements Runnable
  9976. {
  9977. public void run()
  9978. {
  9979. if (L2PcInstance.this.isOnline() == 1)
  9980. {
  9981. SystemMessage msg = new SystemMessage(SystemMessageId.PLAYING_FOR_LONG_TIME);
  9982. L2PcInstance.this.sendPacket(msg);
  9983. }
  9984. else
  9985. stopWarnUserTakeBreak();
  9986. }
  9987. }
  9988.  
  9989. class RentPetTask implements Runnable
  9990. {
  9991. public void run()
  9992. {
  9993. stopRentPet();
  9994. }
  9995. }
  9996.  
  9997. class WaterTask implements Runnable
  9998. {
  9999. public void run()
  10000. {
  10001. double reduceHp = getMaxHp()/100.0;
  10002.  
  10003. if (reduceHp < 1)
  10004. reduceHp = 1;
  10005.  
  10006. reduceCurrentHp(reduceHp,L2PcInstance.this,false, false, null);
  10007. //reduced hp, becouse not rest
  10008. SystemMessage sm = new SystemMessage(SystemMessageId.DROWN_DAMAGE_S1);
  10009. sm.addNumber((int)reduceHp);
  10010. sendPacket(sm);
  10011.  
  10012. }
  10013. }
  10014.  
  10015. class LookingForFishTask implements Runnable
  10016. {
  10017. boolean _isNoob, _isUpperGrade;
  10018. int _fishType, _fishGutsCheck, _gutsCheckTime;
  10019. long _endTaskTime;
  10020.  
  10021. protected LookingForFishTask(int fishWaitTime, int fishGutsCheck, int fishType, boolean isNoob, boolean isUpperGrade)
  10022. {
  10023. _fishGutsCheck = fishGutsCheck;
  10024. _endTaskTime = System.currentTimeMillis() + fishWaitTime + 10000;
  10025. _fishType = fishType;
  10026. _isNoob = isNoob;
  10027. _isUpperGrade = isUpperGrade;
  10028. }
  10029.  
  10030. public void run()
  10031. {
  10032. if (System.currentTimeMillis() >= _endTaskTime) {
  10033. endFishing(false);
  10034. return;
  10035. }
  10036. if (_fishType == -1)
  10037. return;
  10038. int check = Rnd.get(1000);
  10039. if(_fishGutsCheck > check)
  10040. {
  10041. stopLookingForFishTask();
  10042. startFishCombat(_isNoob, _isUpperGrade);
  10043. }
  10044. }
  10045.  
  10046. }
  10047.  
  10048. public int getClanPrivileges()
  10049. {
  10050. return _clanPrivileges;
  10051. }
  10052.  
  10053. public void setClanPrivileges(int n)
  10054. {
  10055. _clanPrivileges = n;
  10056. }
  10057.  
  10058. // baron etc
  10059. public void setPledgeClass(int classId)
  10060. {
  10061. _pledgeClass = classId;
  10062. checkItemRestriction();
  10063. }
  10064.  
  10065. public int getPledgeClass()
  10066. {
  10067. return _pledgeClass;
  10068. }
  10069.  
  10070. public void setPledgeType(int typeId)
  10071. {
  10072. _pledgeType = typeId;
  10073. }
  10074.  
  10075. public int getPledgeType()
  10076. {
  10077. return _pledgeType;
  10078. }
  10079.  
  10080. public int getApprentice()
  10081. {
  10082. return _apprentice;
  10083. }
  10084.  
  10085. public void setApprentice(int apprentice_id)
  10086. {
  10087. _apprentice = apprentice_id;
  10088. }
  10089.  
  10090. public int getSponsor()
  10091. {
  10092. return _sponsor;
  10093. }
  10094.  
  10095. public void setSponsor(int sponsor_id)
  10096. {
  10097. _sponsor = sponsor_id;
  10098. }
  10099.  
  10100. public int getBookMarkSlot()
  10101. {
  10102. return _bookmarkslot;
  10103. }
  10104.  
  10105. public void setBookMarkSlot(int slot)
  10106. {
  10107. _bookmarkslot = slot;
  10108. sendPacket(new ExGetBookMarkInfoPacket(this));
  10109. }
  10110.  
  10111. @Override
  10112. public void sendMessage(String message)
  10113. {
  10114. sendPacket(SystemMessage.sendString(message));
  10115. }
  10116.  
  10117. public void enterObserverMode(int x, int y, int z)
  10118. {
  10119. _obsX = getX();
  10120. _obsY = getY();
  10121. _obsZ = getZ();
  10122.  
  10123. setTarget(null);
  10124. stopMove(null);
  10125. setIsParalyzed(true);
  10126. setIsInvul(true);
  10127. getAppearance().setInvisible();
  10128. sendPacket(new GMHide(1));
  10129. sendPacket(new ObservationMode(x, y, z));
  10130. setXYZ(x, y, z);
  10131.  
  10132. _observerMode = true;
  10133. broadcastUserInfo();
  10134. }
  10135.  
  10136. public void enterOlympiadObserverMode(int x, int y, int z, int id, boolean storeCoords)
  10137. {
  10138. if (getPet() != null)
  10139. getPet().unSummon(this);
  10140.  
  10141. if (!getCubics().isEmpty())
  10142. {
  10143. for (L2CubicInstance cubic : getCubics().values())
  10144. {
  10145. cubic.stopAction();
  10146. cubic.cancelDisappear();
  10147. }
  10148.  
  10149. getCubics().clear();
  10150. }
  10151.  
  10152. if (getParty() != null)
  10153. getParty().removePartyMember(this);
  10154.  
  10155. _olympiadGameId = id;
  10156. if (isSitting())
  10157. standUp();
  10158. if (storeCoords)
  10159. {
  10160. _obsX = getX();
  10161. _obsY = getY();
  10162. _obsZ = getZ();
  10163. }
  10164. setTarget(null);
  10165. setIsInvul(true);
  10166. getAppearance().setInvisible();
  10167. sendPacket(new GMHide(1));
  10168. teleToLocation(x, y, z, false);
  10169. sendPacket(new ExOlympiadMode(3));
  10170. _observerMode = true;
  10171. broadcastUserInfo();
  10172. }
  10173.  
  10174. public void leaveObserverMode()
  10175. {
  10176. setTarget(null);
  10177. setXYZ(_obsX, _obsY, _obsZ);
  10178. setIsParalyzed(false);
  10179. sendPacket(new GMHide(0));
  10180. if (!AdminCommandAccessRights.getInstance().hasAccess("admin_invis", getAccessLevel()))
  10181. getAppearance().setVisible();
  10182. if (!AdminCommandAccessRights.getInstance().hasAccess("admin_invul", getAccessLevel()))
  10183. setIsInvul(false);
  10184. if (getAI() != null)
  10185. getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  10186.  
  10187. _observerMode = false;
  10188. sendPacket(new ObservationReturn(this));
  10189. broadcastUserInfo();
  10190. }
  10191.  
  10192. public void leaveOlympiadObserverMode()
  10193. {
  10194. setTarget(null);
  10195. sendPacket(new ExOlympiadMode(0));
  10196. teleToLocation(_obsX, _obsY, _obsZ, true);
  10197. sendPacket(new GMHide(0));
  10198. if (!AdminCommandAccessRights.getInstance().hasAccess("admin_invis", getAccessLevel()))
  10199. getAppearance().setVisible();
  10200. if (!AdminCommandAccessRights.getInstance().hasAccess("admin_invul", getAccessLevel()))
  10201. setIsInvul(false);
  10202. if (getAI() != null)
  10203. getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
  10204.  
  10205. Olympiad.removeSpectator(_olympiadGameId, this);
  10206. _olympiadGameId = -1;
  10207. _observerMode = false;
  10208. broadcastUserInfo();
  10209. }
  10210.  
  10211. public void setOlympiadSide(int i)
  10212. {
  10213. _olympiadSide = i;
  10214. }
  10215.  
  10216. public int getOlympiadSide()
  10217. {
  10218. return _olympiadSide;
  10219. }
  10220.  
  10221. public void setOlympiadGameId(int id)
  10222. {
  10223. _olympiadGameId = id;
  10224. }
  10225.  
  10226. public int getOlympiadGameId()
  10227. {
  10228. return _olympiadGameId;
  10229. }
  10230.  
  10231. public int getObsX()
  10232. {
  10233. return _obsX;
  10234. }
  10235.  
  10236. public int getObsY()
  10237. {
  10238. return _obsY;
  10239. }
  10240.  
  10241. public int getObsZ()
  10242. {
  10243. return _obsZ;
  10244. }
  10245.  
  10246. public boolean inObserverMode()
  10247. {
  10248. return _observerMode;
  10249. }
  10250.  
  10251. public int getTeleMode()
  10252. {
  10253. return _telemode;
  10254. }
  10255.  
  10256. public void setTeleMode(int mode)
  10257. {
  10258. _telemode = mode;
  10259. }
  10260.  
  10261. public void setLoto(int i, int val)
  10262. {
  10263. _loto[i] = val;
  10264. }
  10265.  
  10266. public int getLoto(int i)
  10267. {
  10268. return _loto[i];
  10269. }
  10270.  
  10271. public void setRace(int i, int val)
  10272. {
  10273. _race[i] = val;
  10274. }
  10275.  
  10276. public int getRace(int i)
  10277. {
  10278. return _race[i];
  10279. }
  10280.  
  10281. public boolean getMessageRefusal()
  10282. {
  10283. return _messageRefusal;
  10284. }
  10285.  
  10286. public void setMessageRefusal(boolean mode)
  10287. {
  10288. _messageRefusal = mode;
  10289. sendPacket(new EtcStatusUpdate(this));
  10290. }
  10291.  
  10292. public void setDietMode(boolean mode)
  10293. {
  10294. _dietMode = mode;
  10295. }
  10296.  
  10297. public boolean getDietMode()
  10298. {
  10299. return _dietMode;
  10300. }
  10301.  
  10302. public void setTradeRefusal(boolean mode)
  10303. {
  10304. _tradeRefusal = mode;
  10305. }
  10306.  
  10307. public boolean getTradeRefusal()
  10308. {
  10309. return _tradeRefusal;
  10310. }
  10311.  
  10312. public void setExchangeRefusal(boolean mode)
  10313. {
  10314. _exchangeRefusal = mode;
  10315. }
  10316.  
  10317. public boolean getExchangeRefusal()
  10318. {
  10319. return _exchangeRefusal;
  10320. }
  10321.  
  10322. public boolean getGainXpSpEnable()
  10323. {
  10324. return _gainXpSpEnable;
  10325. }
  10326.  
  10327. public void setGainXpSpEnable(boolean value)
  10328. {
  10329. _gainXpSpEnable = value;
  10330. }
  10331.  
  10332. public BlockList getBlockList()
  10333. {
  10334. return _blockList;
  10335. }
  10336.  
  10337. public void setHero(boolean hero)
  10338. {
  10339. if (hero && _baseClass == _activeClass)
  10340. {
  10341. for (L2Skill s : HeroSkillTable.getHeroSkills())
  10342. addSkill(s, false); //Dont Save Hero skills to database
  10343. }
  10344. else
  10345. {
  10346. for (L2Skill s : HeroSkillTable.getHeroSkills())
  10347. super.removeSkill(s); //Just Remove skills from nonHero characters
  10348. }
  10349. _hero = hero;
  10350.  
  10351. sendSkillList();
  10352. }
  10353.  
  10354. public void setIsInOlympiadMode(boolean b)
  10355. {
  10356. _inOlympiadMode = b;
  10357. }
  10358.  
  10359. public void setIsOlympiadStart(boolean b)
  10360. {
  10361. _OlympiadStart = b;
  10362. }
  10363.  
  10364. public boolean isOlympiadStart(){
  10365. return _OlympiadStart;
  10366. }
  10367.  
  10368. public boolean isHero()
  10369. {
  10370. return _hero;
  10371. }
  10372.  
  10373. public boolean isInOlympiadMode()
  10374. {
  10375. return _inOlympiadMode;
  10376. }
  10377.  
  10378. public boolean isInDuel()
  10379. {
  10380. return _isInDuel;
  10381. }
  10382.  
  10383. public int getDuelId()
  10384. {
  10385. return _duelId;
  10386. }
  10387.  
  10388. public void setDuelState(int mode)
  10389. {
  10390. _duelState = mode;
  10391. }
  10392.  
  10393. public int getDuelState()
  10394. {
  10395. return _duelState;
  10396. }
  10397.  
  10398. /**
  10399. * Sets up the duel state using a non 0 duelId.
  10400. * @param duelId 0=not in a duel
  10401. */
  10402. public void setIsInDuel(int duelId)
  10403. {
  10404. if (duelId > 0)
  10405. {
  10406. _isInDuel = true;
  10407. _duelState = Duel.DUELSTATE_DUELLING;
  10408. _duelId = duelId;
  10409. }
  10410. else
  10411. {
  10412. if (_duelState == Duel.DUELSTATE_DEAD)
  10413. {
  10414. enableAllSkills();
  10415. getStatus().startHpMpRegeneration();
  10416. }
  10417. _isInDuel = false;
  10418. _duelState = Duel.DUELSTATE_NODUEL;
  10419. _duelId = 0;
  10420. }
  10421. }
  10422.  
  10423. /**
  10424. * This returns a SystemMessage stating why
  10425. * the player is not available for duelling.
  10426. * @return S1_CANNOT_DUEL... message
  10427. */
  10428. public SystemMessage getNoDuelReason()
  10429. {
  10430. SystemMessage sm = new SystemMessage(_noDuelReason);
  10431. sm.addPcName(this);
  10432. _noDuelReason = SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL;
  10433. return sm;
  10434. }
  10435.  
  10436. /**
  10437. * Checks if this player might join / start a duel.
  10438. * To get the reason use getNoDuelReason() after calling this function.
  10439. * @return true if the player might join/start a duel.
  10440. */
  10441. public boolean canDuel()
  10442. {
  10443. if (isInCombat() || getPunishLevel() == PunishLevel.JAIL) { _noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_CURRENTLY_ENGAGED_IN_BATTLE; return false; }
  10444. if (isDead() || isAlikeDead() || (getCurrentHp() < getMaxHp()/2 || getCurrentMp() < getMaxMp()/2)) { _noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_HP_OR_MP_IS_BELOW_50_PERCENT; return false; }
  10445. if (isInDuel()) { _noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_ALREADY_ENGAGED_IN_A_DUEL; return false;}
  10446. if (isInOlympiadMode()) { _noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_PARTICIPATING_IN_THE_OLYMPIAD; return false; }
  10447. if (isCursedWeaponEquipped()) { _noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_IN_A_CHAOTIC_STATE; return false; }
  10448. if (getPrivateStoreType() != STORE_PRIVATE_NONE) { _noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_CURRENTLY_ENGAGED_IN_A_PRIVATE_STORE_OR_MANUFACTURE; return false; }
  10449. if (isMounted() || isInBoat()) { _noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_CURRENTLY_RIDING_A_BOAT_WYVERN_OR_STRIDER; return false; }
  10450. if (isFishing()) { _noDuelReason = SystemMessageId.C1_CANNOT_DUEL_BECAUSE_C1_IS_CURRENTLY_FISHING; return false; }
  10451. if (isInsideZone(ZONE_PVP) || isInsideZone(ZONE_PEACE) || isInsideZone(ZONE_SIEGE))
  10452. {
  10453. _noDuelReason = SystemMessageId.C1_CANNOT_MAKE_A_CHALLANGE_TO_A_DUEL_BECAUSE_C1_IS_CURRENTLY_IN_A_DUEL_PROHIBITED_AREA;
  10454. return false;
  10455. }
  10456. return true;
  10457. }
  10458.  
  10459. public boolean isNoble()
  10460. {
  10461. return _noble;
  10462. }
  10463.  
  10464. public void setNoble(boolean val)
  10465. {
  10466. if (val)
  10467. for (L2Skill s : NobleSkillTable.getInstance().getNobleSkills())
  10468. addSkill(s, false); //Dont Save Noble skills to Sql
  10469. else
  10470. for (L2Skill s : NobleSkillTable.getInstance().getNobleSkills())
  10471. super.removeSkill(s); //Just Remove skills without deleting from Sql
  10472. _noble = val;
  10473.  
  10474. sendSkillList();
  10475. }
  10476.  
  10477. public void setLvlJoinedAcademy(int lvl)
  10478. {
  10479. _lvlJoinedAcademy = lvl;
  10480. }
  10481.  
  10482. public int getLvlJoinedAcademy()
  10483. {
  10484. return _lvlJoinedAcademy;
  10485. }
  10486.  
  10487. public boolean isAcademyMember()
  10488. {
  10489. return _lvlJoinedAcademy > 0;
  10490. }
  10491.  
  10492. public void setTeam(int team)
  10493. {
  10494. _team = team;
  10495. if (getPet() != null)
  10496. getPet().broadcastStatusUpdate();
  10497. }
  10498.  
  10499. public int getTeam()
  10500. {
  10501. return _team;
  10502. }
  10503.  
  10504. public void setWantsPeace(int wantsPeace)
  10505. {
  10506. _wantsPeace = wantsPeace;
  10507. }
  10508.  
  10509. public int getWantsPeace()
  10510. {
  10511. return _wantsPeace;
  10512. }
  10513.  
  10514. public boolean isFishing()
  10515. {
  10516. return _fishing;
  10517. }
  10518.  
  10519. public void setFishing(boolean fishing)
  10520. {
  10521. _fishing = fishing;
  10522. }
  10523.  
  10524. public void setAllianceWithVarkaKetra(int sideAndLvlOfAlliance)
  10525. {
  10526. // [-5,-1] varka, 0 neutral, [1,5] ketra
  10527. _alliedVarkaKetra = sideAndLvlOfAlliance;
  10528. }
  10529.  
  10530. public int getAllianceWithVarkaKetra()
  10531. {
  10532. return _alliedVarkaKetra;
  10533. }
  10534.  
  10535. public boolean isAlliedWithVarka()
  10536. {
  10537. return (_alliedVarkaKetra < 0);
  10538. }
  10539.  
  10540. public boolean isAlliedWithKetra()
  10541. {
  10542. return (_alliedVarkaKetra > 0);
  10543. }
  10544. public void sendSkillList()
  10545. {
  10546. sendSkillList(this);
  10547. }
  10548.  
  10549. public void sendSkillList(L2PcInstance player)
  10550. {
  10551. SkillList sl = new SkillList();
  10552. if(player != null)
  10553. {
  10554. for (L2Skill s : player.getAllSkills())
  10555. {
  10556. if (s == null)
  10557. continue;
  10558. if (s.getId() > 9000 && s.getId() < 9007)
  10559. continue; // Fake skills to change base stats
  10560. if (_transformation != null && (!this.containsAllowedTransformSkill(s.getId()) && !s.allowOnTransform()))
  10561. continue;
  10562.  
  10563. sl.addSkill(s.getId(), s.getLevel(), s.isPassive());
  10564. }
  10565. }
  10566. sendPacket(sl);
  10567. }
  10568.  
  10569. /**
  10570. * 1. Add the specified class ID as a subclass (up to the maximum number of <b>three</b>)
  10571. * for this character.<BR>
  10572. * 2. This method no longer changes the active _classIndex of the player. This is only
  10573. * done by the calling of setActiveClass() method as that should be the only way to do so.
  10574. *
  10575. * @param int classId
  10576. * @param int classIndex
  10577. * @return boolean subclassAdded
  10578. */
  10579. public boolean addSubClass(int classId, int classIndex)
  10580. {
  10581. if (!_subclassLock.tryLock())
  10582. return false;
  10583.  
  10584. try
  10585. {
  10586. if (getTotalSubClasses() == Config.MAX_SUBCLASS || classIndex == 0)
  10587. return false;
  10588.  
  10589. if (getSubClasses().containsKey(classIndex))
  10590. return false;
  10591.  
  10592. // Note: Never change _classIndex in any method other than setActiveClass().
  10593.  
  10594. SubClass newClass = new SubClass();
  10595. newClass.setClassId(classId);
  10596. newClass.setClassIndex(classIndex);
  10597.  
  10598. Connection con = null;
  10599. PreparedStatement statement = null;
  10600.  
  10601. try
  10602. {
  10603. // Store the basic info about this new sub-class.
  10604. con = L2DatabaseFactory.getInstance().getConnection();
  10605. statement = con.prepareStatement(ADD_CHAR_SUBCLASS);
  10606.  
  10607. statement.setInt(1, getObjectId());
  10608. statement.setInt(2, newClass.getClassId());
  10609. statement.setLong(3, newClass.getExp());
  10610. statement.setInt(4, newClass.getSp());
  10611. statement.setInt(5, newClass.getLevel());
  10612. statement.setInt(6, newClass.getClassIndex()); // <-- Added
  10613.  
  10614. statement.execute();
  10615. }
  10616. catch (Exception e) {
  10617. _log.warning("WARNING: Could not add character sub class for " + getName() + ": " + e);
  10618. return false;
  10619. }
  10620. finally
  10621. {
  10622. try
  10623. {
  10624. statement.close();
  10625. }
  10626. catch (Exception e)
  10627. {
  10628. }
  10629. try
  10630. {
  10631. con.close();
  10632. }
  10633. catch (Exception e)
  10634. {
  10635. }
  10636. }
  10637.  
  10638. // Commit after database INSERT incase exception is thrown.
  10639. getSubClasses().put(newClass.getClassIndex(), newClass);
  10640.  
  10641. if (Config.DEBUG)
  10642. _log.info(getName() + " added class ID " + classId + " as a sub class at index " + classIndex + ".");
  10643.  
  10644. ClassId subTemplate = ClassId.values()[classId];
  10645. Collection<L2SkillLearn> skillTree = SkillTreeTable.getInstance().getAllowedSkills(subTemplate);
  10646.  
  10647. if (skillTree == null)
  10648. return true;
  10649.  
  10650. Map<Integer, L2Skill> prevSkillList = new FastMap<Integer, L2Skill>();
  10651.  
  10652. for (L2SkillLearn skillInfo : skillTree)
  10653. {
  10654. if (skillInfo.getMinLevel() <= 40)
  10655. {
  10656. L2Skill prevSkill = prevSkillList.get(skillInfo.getId());
  10657. L2Skill newSkill = SkillTable.getInstance().getInfo(skillInfo.getId(), skillInfo.getLevel());
  10658.  
  10659. if (prevSkill != null && (prevSkill.getLevel() > newSkill.getLevel()))
  10660. continue;
  10661.  
  10662. prevSkillList.put(newSkill.getId(), newSkill);
  10663. storeSkill(newSkill, prevSkill, classIndex);
  10664. }
  10665. }
  10666.  
  10667. if (Config.DEBUG)
  10668. _log.info(getName() + " was given " + getAllSkills().length + " skills for their new sub class.");
  10669.  
  10670. return true;
  10671. }
  10672. finally
  10673. {
  10674. _subclassLock.unlock();
  10675. }
  10676. }
  10677.  
  10678. /**
  10679. * 1. Completely erase all existance of the subClass linked to the classIndex.<BR>
  10680. * 2. Send over the newClassId to addSubClass()to create a new instance on this classIndex.<BR>
  10681. * 3. Upon Exception, revert the player to their BaseClass to avoid further problems.<BR>
  10682. *
  10683. * @param int classIndex
  10684. * @param int newClassId
  10685. * @return boolean subclassAdded
  10686. */
  10687. public boolean modifySubClass(int classIndex, int newClassId)
  10688. {
  10689. if (!_subclassLock.tryLock())
  10690. return false;
  10691.  
  10692. try
  10693. {
  10694. int oldClassId = getSubClasses().get(classIndex).getClassId();
  10695.  
  10696. if (Config.DEBUG)
  10697. _log.info(getName() + " has requested to modify sub class index " + classIndex + " from class ID " + oldClassId + " to " + newClassId + ".");
  10698.  
  10699. Connection con = null;
  10700. PreparedStatement statement = null;
  10701.  
  10702. try
  10703. {
  10704. con = L2DatabaseFactory.getInstance().getConnection();
  10705.  
  10706. // Remove all henna info stored for this sub-class.
  10707. statement = con.prepareStatement(DELETE_CHAR_HENNAS);
  10708. statement.setInt(1, getObjectId());
  10709. statement.setInt(2, classIndex);
  10710. statement.execute();
  10711. statement.close();
  10712.  
  10713. // Remove all shortcuts info stored for this sub-class.
  10714. statement = con.prepareStatement(DELETE_CHAR_SHORTCUTS);
  10715. statement.setInt(1, getObjectId());
  10716. statement.setInt(2, classIndex);
  10717. statement.execute();
  10718. statement.close();
  10719.  
  10720. // Remove all effects info stored for this sub-class.
  10721. statement = con.prepareStatement(DELETE_SKILL_SAVE);
  10722. statement.setInt(1, getObjectId());
  10723. statement.setInt(2, classIndex);
  10724. statement.execute();
  10725. statement.close();
  10726.  
  10727. // Remove all skill info stored for this sub-class.
  10728. statement = con.prepareStatement(DELETE_CHAR_SKILLS);
  10729. statement.setInt(1, getObjectId());
  10730. statement.setInt(2, classIndex);
  10731. statement.execute();
  10732. statement.close();
  10733.  
  10734. // Remove all basic info stored about this sub-class.
  10735. statement = con.prepareStatement(DELETE_CHAR_SUBCLASS);
  10736. statement.setInt(1, getObjectId());
  10737. statement.setInt(2, classIndex);
  10738. statement.execute();
  10739. statement.close();
  10740. }
  10741. catch (Exception e)
  10742. {
  10743. _log.warning("Could not modify sub class for " + getName() + " to class index " + classIndex + ": " + e);
  10744.  
  10745. // This must be done in order to maintain data consistency.
  10746. getSubClasses().remove(classIndex);
  10747. return false;
  10748. }
  10749. finally
  10750. {
  10751. try
  10752. {
  10753. statement.close();
  10754. }
  10755. catch (Exception e)
  10756. {
  10757. }
  10758. try
  10759. {
  10760. con.close();
  10761. }
  10762. catch (Exception e)
  10763. {
  10764. }
  10765. }
  10766.  
  10767. getSubClasses().remove(classIndex);
  10768. }
  10769. finally
  10770. {
  10771. _subclassLock.unlock();
  10772. }
  10773.  
  10774. return addSubClass(newClassId, classIndex);
  10775. }
  10776.  
  10777. public boolean isSubClassActive()
  10778. {
  10779. return _classIndex > 0;
  10780. }
  10781.  
  10782. public Map<Integer, SubClass> getSubClasses()
  10783. {
  10784. if (_subClasses == null)
  10785. _subClasses = new FastMap<Integer, SubClass>();
  10786.  
  10787. return _subClasses;
  10788. }
  10789.  
  10790. public int getTotalSubClasses()
  10791. {
  10792. return getSubClasses().size();
  10793. }
  10794.  
  10795. public int getBaseClass()
  10796. {
  10797. return _baseClass;
  10798. }
  10799.  
  10800. public int getActiveClass()
  10801. {
  10802. return _activeClass;
  10803. }
  10804.  
  10805. public int getClassIndex()
  10806. {
  10807. return _classIndex;
  10808. }
  10809.  
  10810. private void setClassTemplate(int classId)
  10811. {
  10812. _activeClass = classId;
  10813.  
  10814. L2PcTemplate t = CharTemplateTable.getInstance().getTemplate(classId);
  10815.  
  10816. if (t == null)
  10817. {
  10818. _log.severe("Missing template for classId: "+classId);
  10819. throw new Error();
  10820. }
  10821.  
  10822. // Set the template of the L2PcInstance
  10823. setTemplate(t);
  10824. }
  10825.  
  10826. /**
  10827. * Changes the character's class based on the given class index.
  10828. * <BR><BR>
  10829. * An index of zero specifies the character's original (base) class,
  10830. * while indexes 1-3 specifies the character's sub-classes respectively.
  10831. * <br><br>
  10832. * <font color="00FF00"/>WARNING: Use only on subclase change</font>
  10833. *
  10834. * @param classIndex
  10835. */
  10836. public boolean setActiveClass(int classIndex)
  10837. {
  10838. if (!_subclassLock.tryLock())
  10839. return false;
  10840.  
  10841. try
  10842. {
  10843. // Cannot switch or change subclasses while transformed
  10844. if (_transformation != null)
  10845. return false;
  10846.  
  10847. // Remove active item skills before saving char to database
  10848. // because next time when choosing this class, weared items can
  10849. // be different
  10850. for (L2ItemInstance temp : getInventory().getAugmentedItems())
  10851. if (temp != null && temp.isEquipped()) temp.getAugmentation().removeBonus(this);
  10852.  
  10853. // Delete a force buff upon class change.
  10854. if(_fusionSkill != null)
  10855. abortCast();
  10856.  
  10857. // Stop casting for any player that may be casting a force buff on this l2pcinstance.
  10858. for(L2Character character : getKnownList().getKnownCharacters())
  10859. {
  10860. if(character.getFusionSkill() != null && character.getFusionSkill().getTarget() == this)
  10861. character.abortCast();
  10862. }
  10863.  
  10864. /*
  10865. * 1. Call store() before modifying _classIndex to avoid skill effects rollover.
  10866. * 2. Register the correct _classId against applied 'classIndex'.
  10867. */
  10868. store(Config.SUBCLASS_STORE_SKILL_COOLTIME);
  10869. _reuseTimeStamps.clear();
  10870.  
  10871. // clear charges
  10872. _charges.set(0);
  10873. stopChargeTask();
  10874.  
  10875. if (classIndex == 0)
  10876. {
  10877. setClassTemplate(getBaseClass());
  10878. }
  10879. else
  10880. {
  10881. try {
  10882. setClassTemplate(getSubClasses().get(classIndex).getClassId());
  10883. }
  10884. catch (Exception e) {
  10885. _log.info("Could not switch " + getName() + "'s sub class to class index " + classIndex + ": " + e);
  10886. return false;
  10887. }
  10888. }
  10889. _classIndex = classIndex;
  10890.  
  10891. if(isInParty())
  10892. getParty().recalculatePartyLevel();
  10893.  
  10894.  
  10895. /*
  10896. * Update the character's change in class status.
  10897. *
  10898. * 1. Remove any active cubics from the player.
  10899. * 2. Renovate the characters table in the database with the new class info, storing also buff/effect data.
  10900. * 3. Remove all existing skills.
  10901. * 4. Restore all the learned skills for the current class from the database.
  10902. * 5. Restore effect/buff data for the new class.
  10903. * 6. Restore henna data for the class, applying the new stat modifiers while removing existing ones.
  10904. * 7. Reset HP/MP/CP stats and send Server->Client character status packet to reflect changes.
  10905. * 8. Restore shortcut data related to this class.
  10906. * 9. Resend a class change animation effect to broadcast to all nearby players.
  10907. * 10.Unsummon any active servitor from the player.
  10908. */
  10909.  
  10910. if (getPet() instanceof L2SummonInstance)
  10911. getPet().unSummon(this);
  10912.  
  10913. if (!getCubics().isEmpty())
  10914. {
  10915. for (L2CubicInstance cubic : getCubics().values())
  10916. {
  10917. cubic.stopAction();
  10918. cubic.cancelDisappear();
  10919. }
  10920.  
  10921. getCubics().clear();
  10922. }
  10923.  
  10924. for (L2Skill oldSkill : getAllSkills())
  10925. super.removeSkill(oldSkill);
  10926.  
  10927. stopAllEffectsExceptThoseThatLastThroughDeath();
  10928.  
  10929. restoreRecipeBook(false);
  10930.  
  10931. // Restore any Death Penalty Buff
  10932. restoreDeathPenaltyBuffLevel();
  10933.  
  10934. restoreSkills();
  10935. regiveTemporarySkills();
  10936. rewardSkills();
  10937. // Prevents some issues when changing between subclases that shares skills
  10938. if(_disabledSkills != null && !_disabledSkills.isEmpty())
  10939. _disabledSkills.clear();
  10940. restoreEffects();
  10941. updateEffectIcons();
  10942. sendPacket(new EtcStatusUpdate(this));
  10943.  
  10944. //if player has quest 422: Repent Your Sins, remove it
  10945. QuestState st = getQuestState("422_RepentYourSins");
  10946.  
  10947. if (st != null)
  10948. {
  10949. st.exitQuest(true);
  10950. }
  10951.  
  10952. for (int i = 0; i < 3; i++)
  10953. _henna[i] = null;
  10954.  
  10955. restoreHenna();
  10956. sendPacket(new HennaInfo(this));
  10957.  
  10958. if (getCurrentHp() > getMaxHp())
  10959. setCurrentHp(getMaxHp());
  10960. if (getCurrentMp() > getMaxMp())
  10961. setCurrentMp(getMaxMp());
  10962. if (getCurrentCp() > getMaxCp())
  10963. setCurrentCp(getMaxCp());
  10964. refreshOverloaded();
  10965. refreshExpertisePenalty();
  10966. broadcastUserInfo();
  10967.  
  10968. // Clear resurrect xp calculation
  10969. setExpBeforeDeath(0);
  10970.  
  10971. //_macroses.restore();
  10972. //_macroses.sendUpdate();
  10973. _shortCuts.restore();
  10974. sendPacket(new ShortCutInit(this));
  10975.  
  10976. broadcastPacket(new SocialAction(getObjectId(), SocialAction.LEVEL_UP));
  10977. sendPacket(new SkillCoolTime(this));
  10978. sendPacket(new ExStorageMaxCount(this));
  10979.  
  10980. //decayMe();
  10981. //spawnMe(getX(), getY(), getZ());
  10982.  
  10983. return true;
  10984. }
  10985. finally
  10986. {
  10987. _subclassLock.unlock();
  10988. }
  10989. }
  10990.  
  10991. public boolean isLocked()
  10992. {
  10993. return _subclassLock.isLocked();
  10994. }
  10995.  
  10996. public void stopWarnUserTakeBreak()
  10997. {
  10998. if (_taskWarnUserTakeBreak != null)
  10999. {
  11000. _taskWarnUserTakeBreak.cancel(true);
  11001. _taskWarnUserTakeBreak = null;
  11002. }
  11003. }
  11004.  
  11005. public void startWarnUserTakeBreak()
  11006. {
  11007. if (_taskWarnUserTakeBreak == null)
  11008. _taskWarnUserTakeBreak = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new WarnUserTakeBreak(), 7200000, 7200000);
  11009. }
  11010.  
  11011. public void stopRentPet()
  11012. {
  11013. if (_taskRentPet != null)
  11014. {
  11015. // if the rent of a wyvern expires while over a flying zone, tp to down before unmounting
  11016. if (checkLandingState() && getMountType()==2)
  11017. teleToLocation(MapRegionTable.TeleportWhereType.Town);
  11018.  
  11019. if (this.dismount()) // this should always be true now, since we teleported already
  11020. {
  11021. _taskRentPet.cancel(true);
  11022. _taskRentPet = null;
  11023. }
  11024. }
  11025. }
  11026.  
  11027. public void startRentPet(int seconds)
  11028. {
  11029. if (_taskRentPet == null)
  11030. _taskRentPet = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new RentPetTask(), seconds * 1000L, seconds * 1000L);
  11031. }
  11032.  
  11033. public boolean isRentedPet()
  11034. {
  11035. if (_taskRentPet != null)
  11036. return true;
  11037.  
  11038. return false;
  11039. }
  11040.  
  11041. public void stopWaterTask()
  11042. {
  11043. if (_taskWater != null)
  11044. {
  11045. _taskWater.cancel(false);
  11046.  
  11047. _taskWater = null;
  11048. sendPacket(new SetupGauge(2, 0));
  11049. }
  11050. }
  11051.  
  11052. public void startWaterTask()
  11053. {
  11054. if (!isDead() && _taskWater == null)
  11055. {
  11056. int timeinwater = (int)calcStat(Stats.BREATH, 60000, this, null);
  11057.  
  11058. sendPacket(new SetupGauge(2, timeinwater));
  11059. _taskWater = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new WaterTask(), timeinwater, 1000);
  11060. }
  11061. }
  11062.  
  11063. public boolean isInWater()
  11064. {
  11065. if (_taskWater != null)
  11066. return true;
  11067.  
  11068. return false;
  11069. }
  11070.  
  11071. public void checkWaterState()
  11072. {
  11073. if (isInsideZone(ZONE_WATER))
  11074. startWaterTask();
  11075. else
  11076. stopWaterTask();
  11077. }
  11078.  
  11079. public void onPlayerEnter()
  11080. {
  11081. startWarnUserTakeBreak();
  11082.  
  11083. if (SevenSigns.getInstance().isSealValidationPeriod() || SevenSigns.getInstance().isCompResultsPeriod())
  11084. {
  11085. if (!isGM() && isIn7sDungeon() && SevenSigns.getInstance().getPlayerCabal(this) != SevenSigns.getInstance().getCabalHighestScore())
  11086. {
  11087. teleToLocation(MapRegionTable.TeleportWhereType.Town);
  11088. setIsIn7sDungeon(false);
  11089. sendMessage("You have been teleported to the nearest town due to the beginning of the Seal Validation period.");
  11090. }
  11091. }
  11092. else
  11093. {
  11094. if (!isGM() && isIn7sDungeon() && SevenSigns.getInstance().getPlayerCabal(this) == SevenSigns.CABAL_NULL)
  11095. {
  11096. teleToLocation(MapRegionTable.TeleportWhereType.Town);
  11097. setIsIn7sDungeon(false);
  11098. sendMessage("You have been teleported to the nearest town because you have not signed for any cabal.");
  11099. }
  11100. }
  11101.  
  11102. // jail task
  11103. updatePunishState();
  11104.  
  11105. if (_isInvul)
  11106. sendMessage("Entering world in Invulnerable mode.");
  11107. if (getAppearance().getInvisible())
  11108. sendMessage("Entering world in Invisible mode.");
  11109. if (getMessageRefusal())
  11110. sendMessage("Entering world in Message Refusal mode.");
  11111.  
  11112. revalidateZone(true);
  11113. }
  11114.  
  11115. public long getLastAccess()
  11116. {
  11117. return _lastAccess;
  11118. }
  11119.  
  11120. private void checkRecom(int recsHave, int recsLeft)
  11121. {
  11122. Calendar check = Calendar.getInstance();
  11123. check.setTimeInMillis(_lastRecomUpdate);
  11124. check.add(Calendar.DAY_OF_MONTH,1);
  11125.  
  11126. Calendar min = Calendar.getInstance();
  11127.  
  11128. _recomHave = recsHave;
  11129. _recomLeft = recsLeft;
  11130.  
  11131. if (getStat().getLevel() < 10 || check.after(min) )
  11132. return;
  11133.  
  11134. restartRecom();
  11135. }
  11136.  
  11137. public void restartRecom()
  11138. {
  11139. if (Config.ALT_RECOMMEND)
  11140. {
  11141. Connection con = null;
  11142. try
  11143. {
  11144. con = L2DatabaseFactory.getInstance().getConnection();
  11145. PreparedStatement statement = con.prepareStatement(DELETE_CHAR_RECOMS);
  11146. statement.setInt(1, getObjectId());
  11147.  
  11148. statement.execute();
  11149. statement.close();
  11150.  
  11151. _recomChars.clear();
  11152. }
  11153. catch (Exception e)
  11154. {
  11155. _log.log(Level.SEVERE, "Failed cleaning character recommendations.", e);
  11156. }
  11157. finally
  11158. {
  11159. try { con.close(); } catch (Exception e) {}
  11160. }
  11161. }
  11162.  
  11163. if (getStat().getLevel() < 20)
  11164. {
  11165. _recomLeft = 3;
  11166. _recomHave--;
  11167. }
  11168. else if (getStat().getLevel() < 40)
  11169. {
  11170. _recomLeft = 6;
  11171. _recomHave -= 2;
  11172. }
  11173. else
  11174. {
  11175. _recomLeft = 9;
  11176. _recomHave -= 3;
  11177. }
  11178. if (_recomHave < 0) _recomHave = 0;
  11179.  
  11180. // If we have to update last update time, but it's now before 13, we should set it to yesterday
  11181. Calendar update = Calendar.getInstance();
  11182. if(update.get(Calendar.HOUR_OF_DAY) < 13) update.add(Calendar.DAY_OF_MONTH,-1);
  11183. update.set(Calendar.HOUR_OF_DAY,13);
  11184. _lastRecomUpdate = update.getTimeInMillis();
  11185. }
  11186.  
  11187.  
  11188. @Override
  11189. public void doRevive()
  11190. {
  11191. super.doRevive();
  11192. stopEffects(L2EffectType.CHARMOFCOURAGE);
  11193. updateEffectIcons();
  11194. sendPacket(new EtcStatusUpdate(this));
  11195. _reviveRequested = 0;
  11196. _revivePower = 0;
  11197.  
  11198. if (isMounted())
  11199. startFeed(_mountNpcId);
  11200. if (isInParty() && getParty().isInDimensionalRift())
  11201. {
  11202. if (!DimensionalRiftManager.getInstance().checkIfInPeaceZone(getX(), getY(), getZ()))
  11203. getParty().getDimensionalRift().memberRessurected(this);
  11204. }
  11205. }
  11206.  
  11207. @Override
  11208. public void doRevive(double revivePower)
  11209. {
  11210. // Restore the player's lost experience,
  11211. // depending on the % return of the skill used (based on its power).
  11212. restoreExp(revivePower);
  11213. doRevive();
  11214. }
  11215.  
  11216. public void reviveRequest(L2PcInstance Reviver, L2Skill skill, boolean Pet)
  11217. {
  11218. if (_reviveRequested == 1)
  11219. {
  11220. if (_revivePet == Pet)
  11221. {
  11222. Reviver.sendPacket(new SystemMessage(SystemMessageId.RES_HAS_ALREADY_BEEN_PROPOSED)); // Resurrection is already been proposed.
  11223. }
  11224. else
  11225. {
  11226. if (Pet)
  11227. Reviver.sendPacket(new SystemMessage(SystemMessageId.CANNOT_RES_PET2)); // A pet cannot be resurrected while it's owner is in the process of resurrecting.
  11228. else
  11229. Reviver.sendPacket(new SystemMessage(SystemMessageId.MASTER_CANNOT_RES)); // While a pet is attempting to resurrect, it cannot help in resurrecting its master.
  11230. }
  11231. return;
  11232. }
  11233. if((Pet && getPet() != null && getPet().isDead()) || (!Pet && isDead()))
  11234. {
  11235. _reviveRequested = 1;
  11236. int restoreExp = 0;
  11237. if (isPhoenixBlessed())
  11238. _revivePower=100;
  11239. else if (getCharmOfCourage())
  11240. _revivePower=0;
  11241. else
  11242. _revivePower = Formulas.calculateSkillResurrectRestorePercent(skill.getPower(), Reviver.getWIT());
  11243.  
  11244. restoreExp = (int)Math.round((getExpBeforeDeath() - getExp()) * _revivePower / 100);
  11245.  
  11246. _revivePet = Pet;
  11247.  
  11248. if (getCharmOfCourage())
  11249. {
  11250. ConfirmDlg dlg = new ConfirmDlg(SystemMessageId.RESURRECT_USING_CHARM_OF_COURAGE.getId());
  11251. dlg.addTime(60000);
  11252. sendPacket(dlg);
  11253. return;
  11254. }
  11255. ConfirmDlg dlg = new ConfirmDlg(SystemMessageId.RESSURECTION_REQUEST_BY_C1_FOR_S2_XP.getId());
  11256. dlg.addPcName(Reviver);
  11257. dlg.addString(String.valueOf(restoreExp));
  11258. sendPacket(dlg);
  11259. }
  11260. }
  11261.  
  11262. public void reviveAnswer(int answer)
  11263. {
  11264. if (_reviveRequested != 1 || (!isDead() && !_revivePet) || (_revivePet && getPet() != null && !getPet().isDead()))
  11265. return;
  11266. //If character refuses a PhoenixBless autoress, cancel all buffs he had
  11267. if (answer == 0 && isPhoenixBlessed())
  11268. {
  11269. stopPhoenixBlessing(null);
  11270. stopAllEffectsExceptThoseThatLastThroughDeath();
  11271. }
  11272. if (answer == 1)
  11273. {
  11274. if (!_revivePet)
  11275. {
  11276. if (_revivePower != 0)
  11277. doRevive(_revivePower);
  11278. else
  11279. doRevive();
  11280. }
  11281. else if (getPet() != null)
  11282. {
  11283. if (_revivePower != 0)
  11284. getPet().doRevive(_revivePower);
  11285. else
  11286. getPet().doRevive();
  11287. }
  11288. }
  11289. _reviveRequested = 0;
  11290. _revivePower = 0;
  11291. }
  11292.  
  11293. public boolean isReviveRequested()
  11294. {
  11295. return (_reviveRequested == 1);
  11296. }
  11297.  
  11298. public boolean isRevivingPet()
  11299. {
  11300. return _revivePet;
  11301. }
  11302.  
  11303. public void removeReviving()
  11304. {
  11305. _reviveRequested = 0;
  11306. _revivePower = 0;
  11307. }
  11308.  
  11309. public void onActionRequest()
  11310. {
  11311. setProtection(false);
  11312. }
  11313.  
  11314. /**
  11315. * @param expertiseIndex The expertiseIndex to set.
  11316. */
  11317. public void setExpertiseIndex(int expertiseIndex)
  11318. {
  11319. _expertiseIndex = expertiseIndex;
  11320. }
  11321.  
  11322. /**
  11323. * @return Returns the expertiseIndex.
  11324. */
  11325. public int getExpertiseIndex()
  11326. {
  11327. return _expertiseIndex;
  11328. }
  11329.  
  11330. @Override
  11331. public final void onTeleported()
  11332. {
  11333. super.onTeleported();
  11334.  
  11335. // Force a revalidation
  11336. revalidateZone(true);
  11337.  
  11338. if ((Config.PLAYER_SPAWN_PROTECTION > 0) && !isInOlympiadMode())
  11339. setProtection(true);
  11340.  
  11341. // Trained beast is after teleport lost
  11342. if (getTrainedBeast() != null)
  11343. {
  11344. getTrainedBeast().decayMe();
  11345. setTrainedBeast(null);
  11346. }
  11347.  
  11348. // Modify the position of the pet if necessary
  11349. if (getPet() != null)
  11350. {
  11351. getPet().setFollowStatus(false);
  11352. getPet().teleToLocation(getPosition().getX(), getPosition().getY(), getPosition().getZ(), false);
  11353. ((L2SummonAI)getPet().getAI()).setStartFollowController(true);
  11354. getPet().setFollowStatus(true);
  11355. getPet().updateAndBroadcastStatus(0);
  11356. }
  11357.  
  11358. TvTEvent.onTeleported(this);
  11359. }
  11360.  
  11361. @Override
  11362. public void setIsTeleporting(boolean teleport)
  11363. {
  11364. super.setIsTeleporting(teleport);
  11365. if (teleport)
  11366. {
  11367. if (_teleportWatchdog == null && Config.TELEPORT_WATCHDOG_TIMEOUT > 0)
  11368. _teleportWatchdog = ThreadPoolManager.getInstance().scheduleGeneral(new TeleportWatchdog(this), Config.TELEPORT_WATCHDOG_TIMEOUT * 1000);
  11369. }
  11370. else
  11371. {
  11372. if (_teleportWatchdog != null)
  11373. {
  11374. _teleportWatchdog.cancel(false);
  11375. _teleportWatchdog = null;
  11376. }
  11377. }
  11378. }
  11379.  
  11380. class TeleportWatchdog implements Runnable
  11381. {
  11382. private final L2PcInstance _player;
  11383.  
  11384. TeleportWatchdog(L2PcInstance player)
  11385. {
  11386. _player = player;
  11387. }
  11388.  
  11389. public void run()
  11390. {
  11391. if (_player == null || !_player.isTeleporting())
  11392. return;
  11393.  
  11394. if (Config.DEBUG)
  11395. _log.warning("Player " + _player.getName() + " teleport timeout expired");
  11396. _player.onTeleported();
  11397. }
  11398. }
  11399.  
  11400. public void setLastPartyPosition(int x, int y, int z)
  11401. {
  11402. _lastPartyPosition.setXYZ(x,y,z);
  11403. }
  11404.  
  11405. public int getLastPartyPositionDistance(int x, int y, int z)
  11406. {
  11407. double dx = (x - _lastPartyPosition.getX());
  11408. double dy = (y - _lastPartyPosition.getY());
  11409. double dz = (z - _lastPartyPosition.getZ());
  11410.  
  11411. return (int)Math.sqrt(dx*dx + dy*dy + dz*dz);
  11412. }
  11413.  
  11414. public void setLastServerPosition(int x, int y, int z)
  11415. {
  11416. _lastServerPosition.setXYZ(x,y,z);
  11417. }
  11418.  
  11419. public Point3D getLastServerPosition()
  11420. {
  11421. return _lastServerPosition;
  11422. }
  11423.  
  11424. public boolean checkLastServerPosition(int x, int y, int z)
  11425. {
  11426. return _lastServerPosition.equals(x,y,z);
  11427. }
  11428.  
  11429. public int getLastServerDistance(int x, int y, int z)
  11430. {
  11431. double dx = (x - _lastServerPosition.getX());
  11432. double dy = (y - _lastServerPosition.getY());
  11433. double dz = (z - _lastServerPosition.getZ());
  11434.  
  11435. return (int)Math.sqrt(dx*dx + dy*dy + dz*dz);
  11436. }
  11437.  
  11438. @Override
  11439. public void addExpAndSp(long addToExp, int addToSp)
  11440. {
  11441. getStat().addExpAndSp(addToExp, addToSp, false);
  11442. }
  11443.  
  11444. public void addExpAndSp(long addToExp, int addToSp, boolean useVitality)
  11445. {
  11446. getStat().addExpAndSp(addToExp, addToSp, useVitality);
  11447. }
  11448.  
  11449. public void removeExpAndSp(long removeExp, int removeSp)
  11450. {
  11451. getStat().removeExpAndSp(removeExp, removeSp, true);
  11452. }
  11453.  
  11454. public void removeExpAndSp(long removeExp, int removeSp, boolean sendMessage)
  11455. {
  11456. getStat().removeExpAndSp(removeExp, removeSp, sendMessage);
  11457. }
  11458.  
  11459. @Override
  11460. public void reduceCurrentHp(double i, L2Character attacker, L2Skill skill)
  11461. {
  11462. getStatus().reduceHp(i, attacker);
  11463.  
  11464. // notify the tamed beast of attacks
  11465. if (getTrainedBeast() != null )
  11466. getTrainedBeast().onOwnerGotAttacked(attacker);
  11467. }
  11468. @Override
  11469. public void reduceCurrentHp(double value, L2Character attacker, boolean awake, boolean isDOT, L2Skill skill)
  11470. {
  11471. getStatus().reduceHp(value, attacker, awake, isDOT, false);
  11472.  
  11473. // notify the tamed beast of attacks
  11474. if (getTrainedBeast() != null )
  11475. getTrainedBeast().onOwnerGotAttacked(attacker);
  11476. }
  11477.  
  11478. public void broadcastSnoop(int type, String name, String _text)
  11479. {
  11480. if(!_snoopListener.isEmpty())
  11481. {
  11482. Snoop sn = new Snoop(getObjectId(),getName(),type,name,_text);
  11483.  
  11484. for (L2PcInstance pci : _snoopListener)
  11485. if (pci != null)
  11486. pci.sendPacket(sn);
  11487. }
  11488. }
  11489.  
  11490. public void addSnooper(L2PcInstance pci )
  11491. {
  11492. if(!_snoopListener.contains(pci))
  11493. _snoopListener.add(pci);
  11494. }
  11495.  
  11496. public void removeSnooper(L2PcInstance pci )
  11497. {
  11498. _snoopListener.remove(pci);
  11499. }
  11500.  
  11501. public void addSnooped(L2PcInstance pci )
  11502. {
  11503. if(!_snoopedPlayer.contains(pci))
  11504. _snoopedPlayer.add(pci);
  11505. }
  11506.  
  11507. public void removeSnooped(L2PcInstance pci )
  11508. {
  11509. _snoopedPlayer.remove(pci);
  11510. }
  11511.  
  11512. public synchronized void addBypass(String bypass)
  11513. {
  11514. if (bypass == null) return;
  11515. _validBypass.add(bypass);
  11516. //_log.warning("[BypassAdd]"+getName()+" '"+bypass+"'");
  11517. }
  11518.  
  11519. public synchronized void addBypass2(String bypass)
  11520. {
  11521. if (bypass == null) return;
  11522. _validBypass2.add(bypass);
  11523. //_log.warning("[BypassAdd]"+getName()+" '"+bypass+"'");
  11524. }
  11525.  
  11526. public synchronized boolean validateBypass(String cmd)
  11527. {
  11528. if (!Config.BYPASS_VALIDATION)
  11529. return true;
  11530.  
  11531. for (String bp : _validBypass)
  11532. {
  11533. if (bp == null) continue;
  11534.  
  11535. //_log.warning("[BypassValidation]"+getName()+" '"+bp+"'");
  11536. if (bp.equals(cmd))
  11537. return true;
  11538. }
  11539.  
  11540. for (String bp : _validBypass2)
  11541. {
  11542. if (bp == null) continue;
  11543.  
  11544. //_log.warning("[BypassValidation]"+getName()+" '"+bp+"'");
  11545. if (cmd.startsWith(bp))
  11546. return true;
  11547. }
  11548. _log.warning("[L2PcInstance] player ["+getName()+"] sent invalid bypass '"+cmd+"', ban this player!");
  11549. return false;
  11550. }
  11551.  
  11552. /**
  11553. * Performs following tests:<br>
  11554. * <li> Inventory contains item
  11555. * <li> Item owner id == this.owner id
  11556. * <li> It isnt pet control item while mounting pet or pet summoned
  11557. * <li> It isnt active enchant item
  11558. * <li> It isnt cursed weapon/item
  11559. * <li> It isnt wear item
  11560. * <br>
  11561. *
  11562. * @param objectId: item object id
  11563. * @param action: just for login porpouse
  11564. * @return
  11565. */
  11566. public boolean validateItemManipulation(int objectId, String action)
  11567. {
  11568. L2ItemInstance item = getInventory().getItemByObjectId(objectId);
  11569.  
  11570. if (item == null || item.getOwnerId() != getObjectId())
  11571. {
  11572. _log.finest(getObjectId()+": player tried to " + action + " item he is not owner of");
  11573. return false;
  11574. }
  11575.  
  11576. // Pet is summoned and not the item that summoned the pet AND not the buggle from strider you're mounting
  11577. if (getPet() != null && getPet().getControlItemId() == objectId || getMountObjectID() == objectId)
  11578. {
  11579. if (Config.DEBUG)
  11580. _log.finest(getObjectId()+": player tried to " + action + " item controling pet");
  11581.  
  11582. return false;
  11583. }
  11584.  
  11585. if(getActiveEnchantItem() != null && getActiveEnchantItem().getObjectId() == objectId)
  11586. {
  11587. if (Config.DEBUG)
  11588. _log.finest(getObjectId()+":player tried to " + action + " an enchant scroll he was using");
  11589.  
  11590. return false;
  11591. }
  11592.  
  11593. if (CursedWeaponsManager.getInstance().isCursed(item.getItemId()))
  11594. {
  11595. // can not trade a cursed weapon
  11596. return false;
  11597. }
  11598.  
  11599. if (item.isWear())
  11600. {
  11601. // cannot drop/trade wear-items
  11602. return false;
  11603. }
  11604.  
  11605. return true;
  11606. }
  11607.  
  11608. public synchronized void clearBypass()
  11609. {
  11610. _validBypass.clear();
  11611. _validBypass2.clear();
  11612. }
  11613.  
  11614. /**
  11615. * @return Returns the inBoat.
  11616. */
  11617. public boolean isInBoat()
  11618. {
  11619. return _inBoat;
  11620. }
  11621.  
  11622. /**
  11623. * @param inBoat The inBoat to set.
  11624. */
  11625. public void setInBoat(boolean inBoat)
  11626. {
  11627. _inBoat = inBoat;
  11628. }
  11629.  
  11630. /**
  11631. * @return
  11632. */
  11633. public L2BoatInstance getBoat()
  11634. {
  11635. return _boat;
  11636. }
  11637.  
  11638. /**
  11639. * @param boat
  11640. */
  11641. public void setBoat(L2BoatInstance boat)
  11642. {
  11643. _boat = boat;
  11644. }
  11645.  
  11646. /**
  11647. * @return Returns the inAirShip.
  11648. */
  11649. public boolean isInAirShip()
  11650. {
  11651. return _inAirShip;
  11652. }
  11653.  
  11654. /**
  11655. * @param inAirShip The inAirShip to set.
  11656. */
  11657. public void setInAirShip(boolean inAirShip)
  11658. {
  11659. _inAirShip = inAirShip;
  11660. }
  11661.  
  11662. /**
  11663. * @return
  11664. */
  11665. public L2AirShipInstance getAirShip()
  11666. {
  11667. return _airShip;
  11668. }
  11669.  
  11670. /**
  11671. * @param airShip
  11672. */
  11673. public void setAirShip(L2AirShipInstance airShip)
  11674. {
  11675. if (airShip != null)
  11676. setInAirShip(true);
  11677. else
  11678. setInAirShip(false);
  11679. _airShip = airShip;
  11680. }
  11681.  
  11682. public void setInCrystallize(boolean inCrystallize)
  11683. {
  11684. _inCrystallize = inCrystallize;
  11685. }
  11686.  
  11687. public boolean isInCrystallize()
  11688. {
  11689. return _inCrystallize;
  11690. }
  11691.  
  11692. /**
  11693. * @return
  11694. */
  11695. public Point3D getInBoatPosition()
  11696. {
  11697. return _inBoatPosition;
  11698. }
  11699.  
  11700. public void setInBoatPosition(Point3D pt)
  11701. {
  11702. _inBoatPosition = pt;
  11703. }
  11704.  
  11705. /**
  11706. * @return
  11707. */
  11708. public Point3D getInAirShipPosition()
  11709. {
  11710. return _inAirShipPosition;
  11711. }
  11712.  
  11713. public void setInAirShipPosition(Point3D pt)
  11714. {
  11715. _inAirShipPosition = pt;
  11716. }
  11717.  
  11718. /**
  11719. * Manage the delete task of a L2PcInstance (Leave Party, Unsummon pet, Save its inventory in the database, Remove it from the world...).<BR><BR>
  11720. *
  11721. * <B><U> Actions</U> :</B><BR><BR>
  11722. * <li>If the L2PcInstance is in observer mode, set its position to its position before entering in observer mode </li>
  11723. * <li>Set the online Flag to True or False and update the characters table of the database with online status and lastAccess </li>
  11724. * <li>Stop the HP/MP/CP Regeneration task </li>
  11725. * <li>Cancel Crafting, Attak or Cast </li>
  11726. * <li>Remove the L2PcInstance from the world </li>
  11727. * <li>Stop Party and Unsummon Pet </li>
  11728. * <li>Update database with items in its inventory and remove them from the world </li>
  11729. * <li>Remove all L2Object from _knownObjects and _knownPlayer of the L2Character then cancel Attak or Cast and notify AI </li>
  11730. * <li>Close the connection with the client </li><BR><BR>
  11731. *
  11732. */
  11733. public void deleteMe()
  11734. {
  11735. // Check if the L2PcInstance is in observer mode to set its position to its position before entering in observer mode
  11736. if (inObserverMode())
  11737. setXYZ(_obsX, _obsY, _obsZ);
  11738. else if (isInAirShip())
  11739. getAirShip().oustPlayer(this);
  11740.  
  11741. // 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)
  11742. try
  11743. {
  11744. setOnlineStatus(false);
  11745. }
  11746. catch (Exception e)
  11747. {
  11748. _log.log(Level.SEVERE, "deleteMe()", e);
  11749. }
  11750.  
  11751. // Stop the HP/MP/CP Regeneration task (scheduled tasks)
  11752. try
  11753. {
  11754. stopAllTimers();
  11755. }
  11756. catch (Exception e)
  11757. {
  11758. _log.log(Level.SEVERE, "deleteMe()", e);
  11759. }
  11760.  
  11761. try
  11762. {
  11763. setIsTeleporting(false);
  11764. }
  11765. catch (Exception e)
  11766. {
  11767. _log.log(Level.SEVERE, "deleteMe()", e);
  11768. }
  11769.  
  11770. // Stop crafting, if in progress
  11771. try
  11772. {
  11773. RecipeController.getInstance().requestMakeItemAbort(this);
  11774. }
  11775. catch (Exception e)
  11776. {
  11777. _log.log(Level.SEVERE, "deleteMe()", e);
  11778. }
  11779.  
  11780. // Cancel Attak or Cast
  11781. try
  11782. {
  11783. setTarget(null);
  11784. }
  11785. catch (Exception e)
  11786. {
  11787. _log.log(Level.SEVERE, "deleteMe()", e);
  11788. }
  11789.  
  11790. try
  11791. {
  11792. if (_fusionSkill != null)
  11793. abortCast();
  11794.  
  11795. for (L2Character character : getKnownList().getKnownCharacters())
  11796. if (character.getFusionSkill() != null && character.getFusionSkill().getTarget() == this)
  11797. character.abortCast();
  11798. }
  11799. catch (Exception e)
  11800. {
  11801. _log.log(Level.SEVERE, "deleteMe()", e);
  11802. }
  11803.  
  11804. try
  11805. {
  11806. for (L2Effect effect : getAllEffects())
  11807. {
  11808. switch (effect.getEffectType())
  11809. {
  11810. case SIGNET_GROUND:
  11811. case SIGNET_EFFECT:
  11812. effect.exit();
  11813. break;
  11814. }
  11815. }
  11816. }
  11817. catch (Exception e)
  11818. {
  11819. _log.log(Level.SEVERE, "deleteMe()", e);
  11820. }
  11821.  
  11822. // Remove from world regions zones
  11823. L2WorldRegion oldRegion = getWorldRegion();
  11824.  
  11825. // Remove the L2PcInstance from the world
  11826. if (isVisible())
  11827. try
  11828. {
  11829. decayMe();
  11830. }
  11831. catch (Exception e)
  11832. {
  11833. _log.log(Level.SEVERE, "deleteMe()", e);
  11834. }
  11835.  
  11836. if (oldRegion != null)
  11837. oldRegion.removeFromZones(this);
  11838.  
  11839. // If a Party is in progress, leave it (and festival party)
  11840. if (isInParty())
  11841. try
  11842. {
  11843. leaveParty();
  11844. }
  11845. catch (Exception e)
  11846. {
  11847. _log.log(Level.SEVERE, "deleteMe()", e);
  11848. }
  11849.  
  11850. if (Olympiad.getInstance().isRegistered(this) || getOlympiadGameId() != -1) // handle removal from olympiad game
  11851. Olympiad.getInstance().removeDisconnectedCompetitor(this);
  11852.  
  11853. // If the L2PcInstance has Pet, unsummon it
  11854. if (getPet() != null)
  11855. {
  11856. try
  11857. {
  11858. getPet().unSummon(this);
  11859. // dead pet wasnt unsummoned, broadcast npcinfo changes (pet will be without owner name - means owner offline)
  11860. if (getPet() != null)
  11861. getPet().broadcastNpcInfo(0);
  11862. }
  11863. catch (Exception e)
  11864. {
  11865. _log.log(Level.SEVERE, "deleteMe()", e);
  11866. }// returns pet to control item
  11867. }
  11868.  
  11869. if (getClanId() != 0 && getClan() != null)
  11870. {
  11871. // set the status for pledge member list to OFFLINE
  11872. try
  11873. {
  11874. L2ClanMember clanMember = getClan().getClanMember(getName());
  11875. if (clanMember != null)
  11876. clanMember.setPlayerInstance(null);
  11877.  
  11878. }
  11879. catch (Exception e)
  11880. {
  11881. _log.log(Level.SEVERE, "deleteMe()", e);
  11882. }
  11883. }
  11884.  
  11885. if (getActiveRequester() != null)
  11886. {
  11887. // deals with sudden exit in the middle of transaction
  11888. setActiveRequester(null);
  11889. }
  11890.  
  11891. // If the L2PcInstance is a GM, remove it from the GM List
  11892. if (isGM())
  11893. {
  11894. try
  11895. {
  11896. GmListTable.getInstance().deleteGm(this);
  11897. }
  11898. catch (Exception e)
  11899. {
  11900. _log.log(Level.SEVERE, "deleteMe()", e);
  11901. }
  11902. }
  11903.  
  11904. // remove player from instance and set spawn location if any
  11905. try
  11906. {
  11907. final int instanceId = getInstanceId();
  11908. if (instanceId != 0)
  11909. {
  11910. final Instance inst = InstanceManager.getInstance().getInstance(instanceId);
  11911. if (inst != null)
  11912. {
  11913. inst.removePlayer(getObjectId());
  11914. final int[] spawn = inst.getSpawnLoc();
  11915. if (spawn[0] != 0 && spawn[1] != 0 && spawn[2] != 0)
  11916. {
  11917. final int x = spawn[0] + Rnd.get(-30, 30);
  11918. final int y = spawn[1] + Rnd.get(-30, 30);
  11919. setXYZ(x, y, spawn[2]);
  11920. if (getPet() != null) // dead pet
  11921. {
  11922. getPet().teleToLocation(x, y, spawn[2]);
  11923. getPet().setInstanceId(0);
  11924. }
  11925. }
  11926. }
  11927. }
  11928. }
  11929. catch (Exception e)
  11930. {
  11931. _log.log(Level.SEVERE, "deleteMe()", e);
  11932. }
  11933.  
  11934. // TvT Event removal
  11935. try
  11936. {
  11937. TvTEvent.onLogout(this);
  11938. }
  11939. catch (Exception e)
  11940. {
  11941. _log.log(Level.SEVERE, "deleteMe()", e);
  11942. }
  11943.  
  11944. // Update database with items in its inventory and remove them from the world
  11945. try
  11946. {
  11947. getInventory().deleteMe();
  11948. }
  11949. catch (Exception e)
  11950. {
  11951. _log.log(Level.SEVERE, "deleteMe()", e);
  11952. }
  11953.  
  11954. // Update database with items in its warehouse and remove them from the world
  11955. try
  11956. {
  11957. clearWarehouse();
  11958. }
  11959. catch (Exception e)
  11960. {
  11961. _log.log(Level.SEVERE, "deleteMe()", e);
  11962. }
  11963. if (Config.WAREHOUSE_CACHE)
  11964. WarehouseCacheManager.getInstance().remCacheTask(this);
  11965.  
  11966. // Update database with items in its freight and remove them from the world
  11967. try
  11968. {
  11969. clearFreight();
  11970. }
  11971. catch (Exception e)
  11972. {
  11973. _log.log(Level.SEVERE, "deleteMe()", e);
  11974. }
  11975.  
  11976. try
  11977. {
  11978. clearDepositedFreight();
  11979. }
  11980. catch (Exception e)
  11981. {
  11982. _log.log(Level.SEVERE, "deleteMe()", e);
  11983. }
  11984.  
  11985. // Remove all L2Object from _knownObjects and _knownPlayer of the L2Character then cancel Attak or Cast and notify AI
  11986. try
  11987. {
  11988. getKnownList().removeAllKnownObjects();
  11989. }
  11990. catch (Exception e)
  11991. {
  11992. _log.log(Level.SEVERE, "deleteMe()", e);
  11993. }
  11994.  
  11995. // Close the connection with the client
  11996. closeNetConnection();
  11997.  
  11998. if (getClanId() > 0)
  11999. getClan().broadcastToOtherOnlineMembers(new PledgeShowMemberListUpdate(this), this);
  12000. //ClanTable.getInstance().getClan(getClanId()).broadcastToOnlineMembers(new PledgeShowMemberListAdd(this));
  12001.  
  12002. for (L2PcInstance player : _snoopedPlayer)
  12003. player.removeSnooper(this);
  12004.  
  12005. for (L2PcInstance player : _snoopListener)
  12006. player.removeSnooped(this);
  12007.  
  12008. if (_chanceSkills != null)
  12009. {
  12010. _chanceSkills.setOwner(null);
  12011. _chanceSkills = null;
  12012. }
  12013.  
  12014. // Remove L2Object object from _allObjects of L2World
  12015. L2World.getInstance().removeObject(this);
  12016. L2World.getInstance().removeFromAllPlayers(this); // force remove in case of crash during teleport
  12017. }
  12018.  
  12019. private FishData _fish;
  12020.  
  12021. /* startFishing() was stripped of any pre-fishing related checks, namely the fishing zone check.
  12022. * Also worthy of note is the fact the code to find the hook landing position was also striped. The
  12023. * stripped code was moved into fishing.java. In my opinion it makes more sense for it to be there
  12024. * since all other skill related checks were also there. Last but not least, moving the zone check
  12025. * there, fixed a bug where baits would always be consumed no matter if fishing actualy took place.
  12026. * startFishing() now takes up 3 arguments, wich are acurately described as being the hook landing
  12027. * coordinates.
  12028. */
  12029. public void startFishing(int _x, int _y, int _z)
  12030. {
  12031. stopMove(null);
  12032. setIsImmobilized(true);
  12033. _fishing = true;
  12034. _fishx = _x;
  12035. _fishy = _y;
  12036. _fishz = _z;
  12037. broadcastUserInfo();
  12038. //Starts fishing
  12039. int lvl = GetRandomFishLvl();
  12040. int group = GetRandomGroup();
  12041. int type = GetRandomFishType(group);
  12042. List<FishData> fishs = FishTable.getInstance().getfish(lvl, type, group);
  12043. if (fishs == null || fishs.isEmpty())
  12044. {
  12045. sendMessage("Error - Fishes are not definied");
  12046. endFishing(false);
  12047. return;
  12048. }
  12049. int check = Rnd.get(fishs.size());
  12050. // Use a copy constructor else the fish data may be over-written below
  12051. _fish = new FishData(fishs.get(check));
  12052. fishs.clear();
  12053. fishs = null;
  12054. sendPacket(new SystemMessage(SystemMessageId.CAST_LINE_AND_START_FISHING));
  12055. ExFishingStart efs = null;
  12056. if (!GameTimeController.getInstance().isNowNight() && _lure.isNightLure())
  12057. _fish.setType(-1);
  12058. //sendMessage("Hook x,y: " + _x + "," + _y + " - Water Z, Player Z:" + _z + ", " + getZ()); //debug line, uncoment to show coordinates used in fishing.
  12059. efs = new ExFishingStart(this,_fish.getType(),_x,_y,_z,_lure.isNightLure());
  12060. broadcastPacket(efs);
  12061. startLookingForFishTask();
  12062. }
  12063. public void stopLookingForFishTask()
  12064. {
  12065. if (_taskforfish != null)
  12066. {
  12067. _taskforfish.cancel(false);
  12068. _taskforfish = null;
  12069. }
  12070. }
  12071. public void startLookingForFishTask()
  12072. {
  12073. if (!isDead() && _taskforfish == null)
  12074. {
  12075. int checkDelay = 0;
  12076. boolean isNoob = false;
  12077. boolean isUpperGrade = false;
  12078.  
  12079. if (_lure != null)
  12080. {
  12081. int lureid = _lure.getItemId();
  12082. isNoob = _fish.getGroup() == 0;
  12083. isUpperGrade = _fish.getGroup() == 2;
  12084. if (lureid == 6519 || lureid == 6522 || lureid == 6525 || lureid == 8505 || lureid == 8508 || lureid == 8511) //low grade
  12085. checkDelay = Math.round((float)(_fish.getGutsCheckTime() * (1.33)));
  12086. 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
  12087. checkDelay = Math.round((float)(_fish.getGutsCheckTime() * (1.00)));
  12088. else if (lureid == 6521 || lureid == 6524 || lureid == 6527 || lureid == 8507 || lureid == 8510 || lureid == 8513) //high grade
  12089. checkDelay = Math.round((float)(_fish.getGutsCheckTime() * (0.66)));
  12090. }
  12091. _taskforfish = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new LookingForFishTask(_fish.getWaitTime(), _fish.getFishGuts(), _fish.getType(), isNoob, isUpperGrade), 10000, checkDelay);
  12092. }
  12093. }
  12094.  
  12095. private int GetRandomGroup()
  12096. {
  12097. switch (_lure.getItemId()) {
  12098. case 7807: //green for beginners
  12099. case 7808: //purple for beginners
  12100. case 7809: //yellow for beginners
  12101. case 8486: //prize-winning for beginners
  12102. return 0;
  12103. case 8485: //prize-winning luminous
  12104. case 8506: //green luminous
  12105. case 8509: //purple luminous
  12106. case 8512: //yellow luminous
  12107. return 2;
  12108. default:
  12109. return 1;
  12110. }
  12111. }
  12112. private int GetRandomFishType(int group)
  12113. {
  12114. int check = Rnd.get(100);
  12115. int type = 1;
  12116. switch (group) {
  12117. case 0: //fish for novices
  12118. switch (_lure.getItemId()) {
  12119. case 7807: //green lure, preferred by fast-moving (nimble) fish (type 5)
  12120. if (check <= 54)
  12121. type = 5;
  12122. else if (check <= 77)
  12123. type = 4;
  12124. else
  12125. type = 6;
  12126. break;
  12127. case 7808: //purple lure, preferred by fat fish (type 4)
  12128. if (check <= 54)
  12129. type = 4;
  12130. else if (check <= 77)
  12131. type = 6;
  12132. else
  12133. type = 5;
  12134. break;
  12135. case 7809: //yellow lure, preferred by ugly fish (type 6)
  12136. if (check <= 54)
  12137. type = 6;
  12138. else if (check <= 77)
  12139. type = 5;
  12140. else
  12141. type = 4;
  12142. break;
  12143. case 8486: //prize-winning fishing lure for beginners
  12144. if (check <= 33)
  12145. type = 4;
  12146. else if (check <= 66)
  12147. type = 5;
  12148. else
  12149. type = 6;
  12150. break;
  12151. }
  12152. break;
  12153. case 1: //normal fish
  12154. switch (_lure.getItemId()) {
  12155. case 7610:
  12156. case 7611:
  12157. case 7612:
  12158. case 7613:
  12159. type = 3;
  12160. break;
  12161. case 6519: //all theese lures (green) are prefered by fast-moving (nimble) fish (type 1)
  12162. case 8505:
  12163. case 6520:
  12164. case 6521:
  12165. case 8507:
  12166. if (check <= 54)
  12167. type = 1;
  12168. else if (check <= 74)
  12169. type = 0;
  12170. else if (check <= 94)
  12171. type = 2;
  12172. else
  12173. type = 3;
  12174. break;
  12175. case 6522: //all theese lures (purple) are prefered by fat fish (type 0)
  12176. case 8508:
  12177. case 6523:
  12178. case 6524:
  12179. case 8510:
  12180. if (check <= 54)
  12181. type = 0;
  12182. else if (check <= 74)
  12183. type = 1;
  12184. else if (check <= 94)
  12185. type = 2;
  12186. else
  12187. type = 3;
  12188. break;
  12189. case 6525: //all theese lures (yellow) are prefered by ugly fish (type 2)
  12190. case 8511:
  12191. case 6526:
  12192. case 6527:
  12193. case 8513:
  12194. if (check <= 55)
  12195. type = 2;
  12196. else if (check <= 74)
  12197. type = 1;
  12198. else if (check <= 94)
  12199. type = 0;
  12200. else
  12201. type = 3;
  12202. break;
  12203. case 8484: //prize-winning fishing lure
  12204. if (check <= 33)
  12205. type = 0;
  12206. else if (check <= 66)
  12207. type = 1;
  12208. else
  12209. type = 2;
  12210. break;
  12211. }
  12212. break;
  12213. case 2: //upper grade fish, luminous lure
  12214. switch (_lure.getItemId()) {
  12215. case 8506: //green lure, preferred by fast-moving (nimble) fish (type 8)
  12216. if (check <= 54)
  12217. type = 8;
  12218. else if (check <= 77)
  12219. type = 7;
  12220. else
  12221. type = 9;
  12222. break;
  12223. case 8509: //purple lure, preferred by fat fish (type 7)
  12224. if (check <= 54)
  12225. type = 7;
  12226. else if (check <= 77)
  12227. type = 9;
  12228. else
  12229. type = 8;
  12230. break;
  12231. case 8512: //yellow lure, preferred by ugly fish (type 9)
  12232. if (check <= 54)
  12233. type = 9;
  12234. else if (check <= 77)
  12235. type = 8;
  12236. else
  12237. type = 7;
  12238. break;
  12239. case 8485: //prize-winning fishing lure
  12240. if (check <= 33)
  12241. type = 7;
  12242. else if (check <= 66)
  12243. type = 8;
  12244. else
  12245. type = 9;
  12246. break;
  12247. }
  12248. }
  12249. return type;
  12250. }
  12251. private int GetRandomFishLvl()
  12252. {
  12253. L2Effect[] effects = getAllEffects();
  12254. int skilllvl = getSkillLevel(1315);
  12255. for (L2Effect e : effects) {
  12256. if (e.getSkill().getId() == 2274)
  12257. skilllvl = (int)e.getSkill().getPower(this);
  12258. }
  12259. if (skilllvl <= 0) return 1;
  12260. int randomlvl;
  12261. int check = Rnd.get(100);
  12262.  
  12263. if (check <= 50)
  12264. {
  12265. randomlvl = skilllvl;
  12266. }
  12267. else if (check <= 85)
  12268. {
  12269. randomlvl = skilllvl - 1;
  12270. if (randomlvl <= 0)
  12271. {
  12272. randomlvl = 1;
  12273. }
  12274. }
  12275. else
  12276. {
  12277. randomlvl = skilllvl + 1;
  12278. if (randomlvl > 27) randomlvl = 27;
  12279. }
  12280.  
  12281. return randomlvl;
  12282. }
  12283. public void startFishCombat(boolean isNoob, boolean isUpperGrade)
  12284. {
  12285. _fishCombat = new L2Fishing (this, _fish, isNoob, isUpperGrade);
  12286. }
  12287.  
  12288. public void endFishing(boolean win)
  12289. {
  12290. ExFishingEnd efe = new ExFishingEnd(win, this);
  12291. broadcastPacket(efe);
  12292. _fishing = false;
  12293. _fishx = 0;
  12294. _fishy = 0;
  12295. _fishz = 0;
  12296. broadcastUserInfo();
  12297. if (_fishCombat == null)
  12298. sendPacket(new SystemMessage(SystemMessageId.BAIT_LOST_FISH_GOT_AWAY));
  12299. _fishCombat = null;
  12300. _lure = null;
  12301. //Ends fishing
  12302. sendPacket(new SystemMessage(SystemMessageId.REEL_LINE_AND_STOP_FISHING));
  12303. setIsImmobilized(false);
  12304. stopLookingForFishTask();
  12305. }
  12306.  
  12307. public L2Fishing getFishCombat()
  12308. {
  12309. return _fishCombat;
  12310. }
  12311.  
  12312. public int getFishx()
  12313. {
  12314. return _fishx;
  12315. }
  12316.  
  12317. public int getFishy()
  12318. {
  12319. return _fishy;
  12320. }
  12321.  
  12322. public int getFishz()
  12323. {
  12324. return _fishz;
  12325. }
  12326.  
  12327. public void setLure (L2ItemInstance lure)
  12328. {
  12329. _lure = lure;
  12330. }
  12331.  
  12332. public L2ItemInstance getLure()
  12333. {
  12334. return _lure;
  12335. }
  12336.  
  12337. public int getInventoryLimit()
  12338. {
  12339. int ivlim;
  12340. if (isGM())
  12341. ivlim = Config.INVENTORY_MAXIMUM_GM;
  12342. else if (getRace() == Race.Dwarf)
  12343. ivlim = Config.INVENTORY_MAXIMUM_DWARF;
  12344. else
  12345. ivlim = Config.INVENTORY_MAXIMUM_NO_DWARF;
  12346. ivlim += (int)getStat().calcStat(Stats.INV_LIM, 0, null, null);
  12347.  
  12348. return ivlim;
  12349. }
  12350.  
  12351. public int getWareHouseLimit()
  12352. {
  12353. int whlim;
  12354. if (getRace() == Race.Dwarf)
  12355. whlim = Config.WAREHOUSE_SLOTS_DWARF;
  12356. else
  12357. whlim = Config.WAREHOUSE_SLOTS_NO_DWARF;
  12358.  
  12359. whlim += (int)getStat().calcStat(Stats.WH_LIM, 0, null, null);
  12360.  
  12361. return whlim;
  12362. }
  12363.  
  12364. public int getPrivateSellStoreLimit()
  12365. {
  12366. int pslim;
  12367.  
  12368. if (getRace() == Race.Dwarf)
  12369. pslim = Config.MAX_PVTSTORESELL_SLOTS_DWARF;
  12370. else
  12371. pslim = Config.MAX_PVTSTORESELL_SLOTS_OTHER;
  12372.  
  12373. pslim += (int)getStat().calcStat(Stats.P_SELL_LIM, 0, null, null);
  12374.  
  12375. return pslim;
  12376. }
  12377.  
  12378. public int getPrivateBuyStoreLimit()
  12379. {
  12380. int pblim;
  12381.  
  12382. if (getRace() == Race.Dwarf)
  12383. pblim = Config.MAX_PVTSTOREBUY_SLOTS_DWARF;
  12384. else
  12385. pblim = Config.MAX_PVTSTOREBUY_SLOTS_OTHER;
  12386. pblim += (int)getStat().calcStat(Stats.P_BUY_LIM, 0, null, null);
  12387.  
  12388. return pblim;
  12389. }
  12390.  
  12391. public int getFreightLimit()
  12392. {
  12393. return Config.FREIGHT_SLOTS + (int)getStat().calcStat(Stats.FREIGHT_LIM, 0, null, null);
  12394. }
  12395.  
  12396. public int getDwarfRecipeLimit()
  12397. {
  12398. int recdlim = Config.DWARF_RECIPE_LIMIT;
  12399. recdlim += (int)getStat().calcStat(Stats.REC_D_LIM, 0, null, null);
  12400. return recdlim;
  12401. }
  12402.  
  12403. public int getCommonRecipeLimit()
  12404. {
  12405. int recclim = Config.COMMON_RECIPE_LIMIT;
  12406. recclim += (int)getStat().calcStat(Stats.REC_C_LIM, 0, null, null);
  12407. return recclim;
  12408. }
  12409.  
  12410. /**
  12411. * @return Returns the mountNpcId.
  12412. */
  12413. public int getMountNpcId()
  12414. {
  12415. return _mountNpcId;
  12416. }
  12417.  
  12418. /**
  12419. * @return Returns the mountLevel.
  12420. */
  12421. public int getMountLevel()
  12422. {
  12423. return _mountLevel;
  12424. }
  12425.  
  12426. public void setMountObjectID(int newID)
  12427. {
  12428. _mountObjectID = newID;
  12429. }
  12430.  
  12431. public int getMountObjectID()
  12432. {
  12433. return _mountObjectID;
  12434. }
  12435.  
  12436. private L2ItemInstance _lure = null;
  12437. public int _shortBuffTaskSkillId = 0;
  12438.  
  12439. public long getOnlineTime()
  12440. {
  12441. return _onlineTime;
  12442. }
  12443.  
  12444. /**
  12445. * Get the current skill in use or return null.<BR><BR>
  12446. *
  12447. */
  12448. public SkillDat getCurrentSkill()
  12449. {
  12450. return _currentSkill;
  12451. }
  12452.  
  12453.  
  12454. /**
  12455. * Create a new SkillDat object and set the player _currentSkill.<BR><BR>
  12456. *
  12457. */
  12458. public void setCurrentSkill(L2Skill currentSkill, boolean ctrlPressed,
  12459. boolean shiftPressed)
  12460. {
  12461. if (currentSkill == null)
  12462. {
  12463. if (Config.DEBUG)
  12464. _log.info("Setting current skill: NULL for " + getName() + ".");
  12465.  
  12466. _currentSkill = null;
  12467. return;
  12468. }
  12469.  
  12470. if (Config.DEBUG)
  12471. _log.info("Setting current skill: " + currentSkill.getName() + " (ID: " + currentSkill.getId() + ") for " + getName() + ".");
  12472.  
  12473. _currentSkill = new SkillDat(currentSkill, ctrlPressed, shiftPressed);
  12474. }
  12475.  
  12476. /**
  12477. * Get the current pet skill in use or return null.<br><br>
  12478. *
  12479. */
  12480. public SkillDat getCurrentPetSkill()
  12481. {
  12482. return _currentPetSkill;
  12483. }
  12484.  
  12485. /**
  12486. * Create a new SkillDat object and set the player _currentPetSkill.<br><br>
  12487. *
  12488. */
  12489. public void setCurrentPetSkill(L2Skill currentSkill, boolean ctrlPressed, boolean shiftPressed)
  12490. {
  12491. if (currentSkill == null)
  12492. {
  12493. if (Config.DEBUG)
  12494. _log.info("Setting current pet skill: NULL for " + getName() + ".");
  12495.  
  12496. _currentPetSkill = null;
  12497. return;
  12498. }
  12499.  
  12500. if (Config.DEBUG)
  12501. _log.info("Setting current Pet skill: " + currentSkill.getName() + " (ID: " + currentSkill.getId() + ") for " + getName() + ".");
  12502.  
  12503. _currentPetSkill = new SkillDat(currentSkill, ctrlPressed, shiftPressed);
  12504. }
  12505.  
  12506.  
  12507. public SkillDat getQueuedSkill()
  12508. {
  12509. return _queuedSkill;
  12510. }
  12511.  
  12512.  
  12513. /**
  12514. * Create a new SkillDat object and queue it in the player _queuedSkill.<BR><BR>
  12515. *
  12516. */
  12517. public void setQueuedSkill(L2Skill queuedSkill, boolean ctrlPressed, boolean shiftPressed)
  12518. {
  12519. if (queuedSkill == null)
  12520. {
  12521. if (Config.DEBUG)
  12522. _log.info("Setting queued skill: NULL for " + getName() + ".");
  12523.  
  12524. _queuedSkill = null;
  12525. return;
  12526. }
  12527.  
  12528. if (Config.DEBUG)
  12529. _log.info("Setting queued skill: " + queuedSkill.getName() + " (ID: " + queuedSkill.getId() + ") for " + getName() + ".");
  12530.  
  12531. _queuedSkill = new SkillDat(queuedSkill, ctrlPressed, shiftPressed);
  12532. }
  12533.  
  12534. /**
  12535. * returns punishment level of player
  12536. * @return
  12537. */
  12538. public PunishLevel getPunishLevel()
  12539. {
  12540. return _punishLevel;
  12541. }
  12542.  
  12543. /**
  12544. * @return True if player is jailed
  12545. */
  12546. public boolean isInJail()
  12547. {
  12548. return _punishLevel == PunishLevel.JAIL;
  12549. }
  12550.  
  12551. /**
  12552. * @return True if player is chat banned
  12553. */
  12554. public boolean isChatBanned()
  12555. {
  12556. return _punishLevel == PunishLevel.CHAT;
  12557. }
  12558.  
  12559. public void setPunishLevel(int state)
  12560. {
  12561. switch (state){
  12562. case 0 :
  12563. {
  12564. _punishLevel = PunishLevel.NONE;
  12565. break;
  12566. }
  12567. case 1 :
  12568. {
  12569. _punishLevel = PunishLevel.CHAT;
  12570. break;
  12571. }
  12572. case 2 :
  12573. {
  12574. _punishLevel = PunishLevel.JAIL;
  12575. break;
  12576. }
  12577. case 3 :
  12578. {
  12579. _punishLevel = PunishLevel.CHAR;
  12580. break;
  12581. }
  12582. case 4 :
  12583. {
  12584. _punishLevel = PunishLevel.ACC;
  12585. break;
  12586. }
  12587. }
  12588. }
  12589.  
  12590. /**
  12591. * Sets punish level for player based on delay
  12592. * @param state
  12593. * @param delayInMinutes
  12594. * 0 - Indefinite
  12595. */
  12596. public void setPunishLevel(PunishLevel state, int delayInMinutes)
  12597. {
  12598. long delayInMilliseconds = delayInMinutes * 60000L;
  12599. switch (state)
  12600. {
  12601. case NONE: // Remove Punishments
  12602. {
  12603. switch (_punishLevel)
  12604. {
  12605. case CHAT:
  12606. {
  12607. _punishLevel = state;
  12608. stopPunishTask(true);
  12609. sendPacket(new EtcStatusUpdate(this));
  12610. sendMessage("Your Chat ban has been lifted");
  12611. break;
  12612. }
  12613. case JAIL:
  12614. {
  12615. _punishLevel = state;
  12616. // Open a Html message to inform the player
  12617. NpcHtmlMessage htmlMsg = new NpcHtmlMessage(0);
  12618. String jailInfos = HtmCache.getInstance().getHtm("data/html/jail_out.htm");
  12619. if (jailInfos != null)
  12620. htmlMsg.setHtml(jailInfos);
  12621. else
  12622. htmlMsg.setHtml("<html><body>You are free for now, respect server rules!</body></html>");
  12623. sendPacket(htmlMsg);
  12624. stopPunishTask(true);
  12625. teleToLocation(17836, 170178, -3507, true); // Floran
  12626. break;
  12627. }
  12628. }
  12629. break;
  12630. }
  12631. case CHAT: // Chat Ban
  12632. {
  12633. _punishLevel = state;
  12634. _punishTimer = 0;
  12635. sendPacket(new EtcStatusUpdate(this));
  12636. // Remove the task if any
  12637. stopPunishTask(false);
  12638.  
  12639. if (delayInMinutes > 0)
  12640. {
  12641. _punishTimer = delayInMilliseconds;
  12642.  
  12643. // start the countdown
  12644. _punishTask = ThreadPoolManager.getInstance().scheduleGeneral(new PunishTask(this), _punishTimer);
  12645. sendMessage("You are chat banned for "+delayInMinutes+" minutes.");
  12646. }
  12647. else
  12648. sendMessage("You have been chat banned");
  12649. break;
  12650.  
  12651. }
  12652. case JAIL: // Jail Player
  12653. {
  12654. _punishLevel = state;
  12655. _punishTimer = 0;
  12656. // Remove the task if any
  12657. stopPunishTask(false);
  12658.  
  12659. if (delayInMinutes > 0)
  12660. {
  12661. _punishTimer = delayInMilliseconds;
  12662.  
  12663. // start the countdown
  12664. _punishTask = ThreadPoolManager.getInstance().scheduleGeneral(new PunishTask(this), _punishTimer);
  12665. sendMessage("You are in jail for "+delayInMinutes+" minutes.");
  12666. }
  12667.  
  12668. if (!TvTEvent.isInactive() && TvTEvent.isPlayerParticipant(getObjectId()))
  12669. TvTEvent.removeParticipant(getObjectId());
  12670. if (Olympiad.getInstance().isRegisteredInComp(this))
  12671. Olympiad.getInstance().removeDisconnectedCompetitor(this);
  12672.  
  12673. // Open a Html message to inform the player
  12674. NpcHtmlMessage htmlMsg = new NpcHtmlMessage(0);
  12675. String jailInfos = HtmCache.getInstance().getHtm("data/html/jail_in.htm");
  12676. if (jailInfos != null)
  12677. htmlMsg.setHtml(jailInfos);
  12678. else
  12679. htmlMsg.setHtml("<html><body>You have been put in jail by an admin.</body></html>");
  12680. sendPacket(htmlMsg);
  12681. setInstanceId(0);
  12682. setIsIn7sDungeon(false);
  12683.  
  12684. teleToLocation(-114356, -249645, -2984, false); // Jail
  12685. break;
  12686. }
  12687. case CHAR: // Ban Character
  12688. {
  12689. setAccessLevel(-100);
  12690. logout();
  12691. RegionBBSManager.getInstance().changeCommunityBoard();
  12692. break;
  12693. }
  12694. case ACC: // Ban Account
  12695. {
  12696. setAccountAccesslevel(-100);
  12697. logout();
  12698. RegionBBSManager.getInstance().changeCommunityBoard();
  12699. break;
  12700. }
  12701. default:
  12702. {
  12703. _punishLevel = state;
  12704. break;
  12705. }
  12706. }
  12707.  
  12708. // store in database
  12709. storeCharBase();
  12710. }
  12711.  
  12712. public long getPunishTimer()
  12713. {
  12714. return _punishTimer;
  12715. }
  12716.  
  12717. public void setPunishTimer(long time)
  12718. {
  12719. _punishTimer = time;
  12720. }
  12721.  
  12722. private void updatePunishState()
  12723. {
  12724. if (getPunishLevel() != PunishLevel.NONE)
  12725. {
  12726. // If punish timer exists, restart punishtask.
  12727. if (_punishTimer > 0)
  12728. {
  12729. _punishTask = ThreadPoolManager.getInstance().scheduleGeneral(new PunishTask(this), _punishTimer);
  12730. sendMessage("You are still "+getPunishLevel().string()+" for "+Math.round(_punishTimer/60000)+" minutes.");
  12731. }
  12732. if (getPunishLevel() == PunishLevel.JAIL)
  12733. {
  12734. // If player escaped, put him back in jail
  12735. if (!isInsideZone(ZONE_JAIL))
  12736. teleToLocation(-114356,-249645,-2984, true);
  12737. }
  12738. }
  12739. }
  12740.  
  12741. public void stopPunishTask(boolean save)
  12742. {
  12743. if (_punishTask != null)
  12744. {
  12745. if (save)
  12746. {
  12747. long delay = _punishTask.getDelay(TimeUnit.MILLISECONDS);
  12748. if (delay < 0)
  12749. delay = 0;
  12750. setPunishTimer(delay);
  12751. }
  12752. _punishTask.cancel(false);
  12753. _punishTask = null;
  12754. }
  12755. }
  12756.  
  12757. private class PunishTask implements Runnable
  12758. {
  12759. L2PcInstance _player;
  12760. protected long _startedAt;
  12761.  
  12762. protected PunishTask(L2PcInstance player)
  12763. {
  12764. _player = player;
  12765. _startedAt = System.currentTimeMillis();
  12766. }
  12767.  
  12768. public void run()
  12769. {
  12770. _player.setPunishLevel(PunishLevel.NONE, 0);
  12771. }
  12772. }
  12773. public void startFameTask(long delay, int fameFixRate)
  12774. {
  12775. if (getLevel() < 40 || getClassId().level() < 2)
  12776. return;
  12777. if (_fameTask == null)
  12778. _fameTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new FameTask(this, fameFixRate), delay, delay);
  12779. }
  12780.  
  12781. public void stopFameTask()
  12782. {
  12783. if (_fameTask != null)
  12784. {
  12785. _fameTask.cancel(false);
  12786. _fameTask = null;
  12787. }
  12788. }
  12789.  
  12790. private class FameTask implements Runnable
  12791. {
  12792. private final L2PcInstance _player;
  12793. private final int _value;
  12794.  
  12795. protected FameTask(L2PcInstance player, int value)
  12796. {
  12797. _player = player;
  12798. _value = value;
  12799. }
  12800.  
  12801. public void run()
  12802. {
  12803. if (_player == null || (_player.isDead() && !Config.FAME_FOR_DEAD_PLAYERS))
  12804. return;
  12805. _player.setFame(_player.getFame() + _value);
  12806. SystemMessage sm = new SystemMessage(SystemMessageId.ACQUIRED_S1_REPUTATION_SCORE);
  12807. sm.addNumber(_value);
  12808. _player.sendPacket(sm);
  12809. _player.sendPacket(new UserInfo(_player));
  12810. }
  12811. }
  12812.  
  12813. public void startVitalityTask()
  12814. {
  12815. if (Config.ENABLE_VITALITY && _vitalityTask == null)
  12816. {
  12817. _vitalityTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new VitalityTask(this), 1000, 60000);
  12818. }
  12819. }
  12820.  
  12821. public void stopVitalityTask()
  12822. {
  12823. if (_vitalityTask != null)
  12824. {
  12825. _vitalityTask.cancel(false);
  12826. _vitalityTask = null;
  12827. }
  12828. }
  12829.  
  12830. private class VitalityTask implements Runnable
  12831. {
  12832. private final L2PcInstance _player;
  12833.  
  12834. protected VitalityTask(L2PcInstance player)
  12835. {
  12836. _player = player;
  12837. }
  12838.  
  12839. public void run()
  12840. {
  12841. if (!_player.isInsideZone(L2Character.ZONE_PEACE))
  12842. return;
  12843.  
  12844. if (_player.getVitalityPoints() >= PcStat.MAX_VITALITY_POINTS)
  12845. return;
  12846.  
  12847. _player.updateVitalityPoints(Config.RATE_RECOVERY_VITALITY_PEACE_ZONE, false, false);
  12848. _player.sendPacket(new ExVitalityPointInfo(getVitalityPoints()));
  12849. }
  12850. }
  12851.  
  12852. /**
  12853. * @return
  12854. */
  12855. public int getPowerGrade()
  12856. {
  12857. return _powerGrade;
  12858. }
  12859.  
  12860. /**
  12861. * @return
  12862. */
  12863. public void setPowerGrade(int power)
  12864. {
  12865. _powerGrade = power;
  12866. }
  12867.  
  12868. public boolean isCursedWeaponEquipped()
  12869. {
  12870. return _cursedWeaponEquippedId != 0;
  12871. }
  12872.  
  12873. public void setCursedWeaponEquippedId(int value)
  12874. {
  12875. _cursedWeaponEquippedId = value;
  12876. }
  12877.  
  12878. public int getCursedWeaponEquippedId()
  12879. {
  12880. return _cursedWeaponEquippedId;
  12881. }
  12882.  
  12883. public boolean isCombatFlagEquipped()
  12884. {
  12885. return _combatFlagEquippedId ;
  12886. }
  12887.  
  12888. public void setCombatFlagEquipped(boolean value)
  12889. {
  12890. _combatFlagEquippedId = value;
  12891. }
  12892.  
  12893. public boolean getCharmOfCourage()
  12894. {
  12895. return _charmOfCourage;
  12896. }
  12897.  
  12898. public void setCharmOfCourage(boolean val)
  12899. {
  12900. _charmOfCourage = val;
  12901. sendPacket(new EtcStatusUpdate(this));
  12902. }
  12903.  
  12904. public final void setIsRidingStrider(boolean mode)
  12905. {
  12906. _isRidingStrider = mode;
  12907. }
  12908.  
  12909. /* not used anymore
  12910. public final void setIsRidingFenrirWolf(boolean mode)
  12911. {
  12912. _isRidingFenrirWolf = mode;
  12913. }
  12914. public final void setIsRidingWFenrirWolf(boolean mode)
  12915. {
  12916. _isRidingWFenrirWolf = mode;
  12917. }
  12918. public final void setIsRidingGreatSnowWolf(boolean mode)
  12919. {
  12920. _isRidingGreatSnowWolf = mode;
  12921. }
  12922. public final boolean isRidingFenrirWolf()
  12923. {
  12924. return _isRidingFenrirWolf;
  12925. }
  12926. public final boolean isRidingWFenrirWolf()
  12927. {
  12928. return _isRidingWFenrirWolf;
  12929. }
  12930. public final boolean isRidingGreatSnowWolf()
  12931. {
  12932. return _isRidingGreatSnowWolf;
  12933. }*/
  12934.  
  12935. public final boolean isRidingStrider()
  12936. {
  12937. return _isRidingStrider;
  12938. }
  12939.  
  12940. /**
  12941. * Returns the Number of Souls this L2PcInstance got.
  12942. * @return
  12943. */
  12944. public int getSouls()
  12945. {
  12946. return _souls;
  12947. }
  12948.  
  12949. /**
  12950. * Absorbs a Soul from a Npc.
  12951. * @param skill
  12952. * @param target
  12953. */
  12954. public void absorbSoul(L2Skill skill, L2Npc npc)
  12955. {
  12956. if (_souls >= skill.getNumSouls())
  12957. {
  12958. SystemMessage sm = new SystemMessage(SystemMessageId.SOUL_CANNOT_BE_INCREASED_ANYMORE);
  12959. sendPacket(sm);
  12960. return;
  12961. }
  12962.  
  12963. increaseSouls(1);
  12964.  
  12965. if (npc != null)
  12966. broadcastPacket(new ExSpawnEmitter(this, npc), 500);
  12967. }
  12968.  
  12969. /**
  12970. * Increase Souls
  12971. * @param count
  12972. */
  12973. public void increaseSouls(int count)
  12974. {
  12975. if (count < 0 || count > 45)
  12976. return;
  12977.  
  12978. _souls += count;
  12979.  
  12980. if (getSouls() > 45)
  12981. _souls = 45;
  12982.  
  12983. SystemMessage sm = new SystemMessage(SystemMessageId.YOUR_SOUL_HAS_INCREASED_BY_S1_SO_IT_IS_NOW_AT_S2);
  12984. sm.addNumber(count);
  12985. sm.addNumber(_souls);
  12986. sendPacket(sm);
  12987.  
  12988. restartSoulTask();
  12989.  
  12990. sendPacket(new EtcStatusUpdate(this));
  12991. }
  12992.  
  12993. /**
  12994. * Decreases existing Souls.
  12995. * @param count
  12996. */
  12997. public boolean decreaseSouls(int count, L2Skill skill)
  12998. {
  12999. if (getSouls() <= 0 && skill.getSoulConsumeCount() > 0)
  13000. {
  13001. sendPacket(new SystemMessage(SystemMessageId.THERE_IS_NOT_ENOUGH_SOUL));
  13002. return false;
  13003. }
  13004.  
  13005. _souls -= count;
  13006.  
  13007. if (getSouls() < 0)
  13008. _souls = 0;
  13009.  
  13010. if (getSouls() == 0)
  13011. stopSoulTask();
  13012. else
  13013. restartSoulTask();
  13014.  
  13015. sendPacket(new EtcStatusUpdate(this));
  13016. return true;
  13017. }
  13018.  
  13019. /**
  13020. * Clear out all Souls from this L2PcInstance
  13021. */
  13022. public void clearSouls()
  13023. {
  13024. _souls = 0;
  13025. stopSoulTask();
  13026. sendPacket(new EtcStatusUpdate(this));
  13027. }
  13028.  
  13029. /**
  13030. * Starts/Restarts the SoulTask to Clear Souls after 10 Mins.
  13031. */
  13032. private void restartSoulTask()
  13033. {
  13034. if (_soulTask != null)
  13035. {
  13036. _soulTask.cancel(false);
  13037. _soulTask = null;
  13038. }
  13039. _soulTask = ThreadPoolManager.getInstance().scheduleGeneral(new SoulTask(this), 600000);
  13040. }
  13041.  
  13042. /**
  13043. * Stops the Clearing Task.
  13044. */
  13045. public void stopSoulTask()
  13046. {
  13047. if (_soulTask != null)
  13048. {
  13049. _soulTask.cancel(false);
  13050. _soulTask = null;
  13051. }
  13052. }
  13053.  
  13054. private class SoulTask implements Runnable
  13055. {
  13056. L2PcInstance _player;
  13057.  
  13058. protected SoulTask(L2PcInstance player)
  13059. {
  13060. _player = player;
  13061. }
  13062.  
  13063. public void run()
  13064. {
  13065. _player.clearSouls();
  13066. }
  13067. }
  13068.  
  13069. /**
  13070. *
  13071. * @param magicId
  13072. * @param level
  13073. * @param time
  13074. */
  13075. public void shortBuffStatusUpdate(int magicId, int level, int time)
  13076. {
  13077. if (_shortBuffTask != null)
  13078. {
  13079. _shortBuffTask.cancel(false);
  13080. _shortBuffTask = null;
  13081. }
  13082. _shortBuffTask = ThreadPoolManager.getInstance().scheduleGeneral(new ShortBuffTask(this), time*1000);
  13083. setShortBuffTaskSkillId(magicId);
  13084.  
  13085. sendPacket(new ShortBuffStatusUpdate(magicId, level, time));
  13086. }
  13087.  
  13088. public void setShortBuffTaskSkillId(int id)
  13089. {
  13090. _shortBuffTaskSkillId = id;
  13091. }
  13092. public int getDeathPenaltyBuffLevel()
  13093. {
  13094. return _deathPenaltyBuffLevel;
  13095. }
  13096.  
  13097. public void setDeathPenaltyBuffLevel(int level)
  13098. {
  13099. _deathPenaltyBuffLevel = level;
  13100. }
  13101.  
  13102. public void calculateDeathPenaltyBuffLevel(L2Character killer)
  13103. {
  13104. if((getKarma() > 0 || Rnd.get(1,100) <= Config.DEATH_PENALTY_CHANCE)
  13105. && !(killer instanceof L2PcInstance) && !(this.isGM())
  13106. && !(this.getCharmOfLuck() && killer.isRaid())
  13107. && !isPhoenixBlessed()
  13108. && !(TvTEvent.isStarted() && TvTEvent.isPlayerParticipant(getObjectId()))
  13109. && !(this.isInsideZone(L2Character.ZONE_PVP)||this.isInsideZone(L2Character.ZONE_SIEGE)))
  13110.  
  13111. increaseDeathPenaltyBuffLevel();
  13112. }
  13113.  
  13114. public void increaseDeathPenaltyBuffLevel()
  13115. {
  13116. if(getDeathPenaltyBuffLevel() >= 15) //maximum level reached
  13117. return;
  13118.  
  13119. if(getDeathPenaltyBuffLevel() != 0)
  13120. {
  13121. L2Skill skill = SkillTable.getInstance().getInfo(5076, getDeathPenaltyBuffLevel());
  13122.  
  13123. if(skill != null)
  13124. removeSkill(skill, true);
  13125. }
  13126.  
  13127. _deathPenaltyBuffLevel++;
  13128.  
  13129. addSkill(SkillTable.getInstance().getInfo(5076, getDeathPenaltyBuffLevel()), false);
  13130. sendPacket(new EtcStatusUpdate(this));
  13131. SystemMessage sm = new SystemMessage(SystemMessageId.DEATH_PENALTY_LEVEL_S1_ADDED);
  13132. sm.addNumber(getDeathPenaltyBuffLevel());
  13133. sendPacket(sm);
  13134. }
  13135.  
  13136. public void reduceDeathPenaltyBuffLevel()
  13137. {
  13138. if(getDeathPenaltyBuffLevel() <= 0)
  13139. return;
  13140.  
  13141. L2Skill skill = SkillTable.getInstance().getInfo(5076, getDeathPenaltyBuffLevel());
  13142.  
  13143. if(skill != null)
  13144. removeSkill(skill, true);
  13145.  
  13146. _deathPenaltyBuffLevel--;
  13147.  
  13148. if(getDeathPenaltyBuffLevel() > 0)
  13149. {
  13150. addSkill(SkillTable.getInstance().getInfo(5076, getDeathPenaltyBuffLevel()), false);
  13151. sendPacket(new EtcStatusUpdate(this));
  13152. SystemMessage sm = new SystemMessage(SystemMessageId.DEATH_PENALTY_LEVEL_S1_ADDED);
  13153. sm.addNumber(getDeathPenaltyBuffLevel());
  13154. sendPacket(sm);
  13155. }
  13156. else
  13157. {
  13158. sendPacket(new EtcStatusUpdate(this));
  13159. sendPacket(new SystemMessage(SystemMessageId.DEATH_PENALTY_LIFTED));
  13160. }
  13161. }
  13162.  
  13163. public void restoreDeathPenaltyBuffLevel()
  13164. {
  13165. L2Skill skill = SkillTable.getInstance().getInfo(5076, getDeathPenaltyBuffLevel());
  13166.  
  13167. if(skill != null)
  13168. removeSkill(skill, true);
  13169.  
  13170. if(getDeathPenaltyBuffLevel() > 0)
  13171. {
  13172. addSkill(SkillTable.getInstance().getInfo(5076, getDeathPenaltyBuffLevel()), false);
  13173. }
  13174. }
  13175.  
  13176. private FastMap<Integer, TimeStamp> _reuseTimeStamps = new FastMap<Integer, TimeStamp>().setShared(true);
  13177. private boolean _canFeed;
  13178. private int _afroId = 0;
  13179. private boolean _isInSiege;
  13180.  
  13181. public boolean isOnline;
  13182.  
  13183. public Collection<TimeStamp> getReuseTimeStamps()
  13184. {
  13185. return _reuseTimeStamps.values();
  13186. }
  13187.  
  13188. public FastMap<Integer, TimeStamp> getReuseTimeStamp()
  13189. {
  13190. return _reuseTimeStamps;
  13191. }
  13192.  
  13193. /**
  13194. * Simple class containing all neccessary information to maintain
  13195. * valid timestamps and reuse for skills upon relog. Filter this
  13196. * carefully as it becomes redundant to store reuse for small delays.
  13197. * @author Yesod
  13198. */
  13199. public static class TimeStamp
  13200. {
  13201. private int skill;
  13202. private long reuse;
  13203. private long stamp;
  13204.  
  13205. public TimeStamp(int _skill, long _reuse)
  13206. {
  13207. skill = _skill;
  13208. reuse = _reuse;
  13209. stamp = System.currentTimeMillis()+ reuse;
  13210. }
  13211.  
  13212. public TimeStamp(int _skill, long _reuse, long _systime)
  13213. {
  13214. skill = _skill;
  13215. reuse = _reuse;
  13216. stamp = _systime;
  13217. }
  13218.  
  13219. public long getStamp()
  13220. {
  13221. return stamp;
  13222. }
  13223.  
  13224. public int getSkill()
  13225. {
  13226. return skill;
  13227. }
  13228.  
  13229. public long getReuse()
  13230. {
  13231. return reuse;
  13232. }
  13233.  
  13234. public long getRemaining()
  13235. {
  13236. return Math.max(stamp - System.currentTimeMillis(), 0);
  13237. }
  13238.  
  13239. /* Check if the reuse delay has passed and
  13240. * if it has not then update the stored reuse time
  13241. * according to what is currently remaining on
  13242. * the delay. */
  13243. public boolean hasNotPassed()
  13244. {
  13245. if (System.currentTimeMillis() < stamp)
  13246. {
  13247. return true;
  13248. }
  13249. return false;
  13250. }
  13251. }
  13252.  
  13253. /**
  13254. * Index according to skill id the current
  13255. * timestamp of use.
  13256. * @param skillid
  13257. * @param reuse delay
  13258. */
  13259. @Override
  13260. public void addTimeStamp(int s, int r)
  13261. {
  13262. _reuseTimeStamps.put(s, new TimeStamp(s, r));
  13263. }
  13264.  
  13265. /**
  13266. * Index according to skill this TimeStamp
  13267. * instance for restoration purposes only.
  13268. * @param TimeStamp
  13269. */
  13270. public void addTimeStamp(TimeStamp ts)
  13271. {
  13272. _reuseTimeStamps.put(ts.getSkill(), ts);
  13273. }
  13274.  
  13275. /**
  13276. * Index according to skill id the current
  13277. * timestamp of use.
  13278. * @param skillid
  13279. */
  13280. @Override
  13281. public void removeTimeStamp(int s)
  13282. {
  13283. _reuseTimeStamps.remove(s);
  13284. }
  13285.  
  13286. @Override
  13287. public L2PcInstance getActingPlayer()
  13288. {
  13289. return this;
  13290. }
  13291.  
  13292. @Override
  13293. public final void sendDamageMessage(L2Character target, int damage, boolean mcrit, boolean pcrit, boolean miss)
  13294. {
  13295. // Check if hit is missed
  13296. if (miss)
  13297. {
  13298. sendPacket(new SystemMessage(SystemMessageId.C1_ATTACK_WENT_ASTRAY).addString(getName()));
  13299. return;
  13300. }
  13301.  
  13302. // Check if hit is critical
  13303. if (pcrit)
  13304. {
  13305. sendPacket(new SystemMessage(SystemMessageId.C1_HAD_CRITICAL_HIT).addPcName(this));
  13306. if (target instanceof L2Npc && getSkillLevel(467) > 0)
  13307. {
  13308. L2Skill skill = SkillTable.getInstance().getInfo(467,getSkillLevel(467));
  13309. if (Rnd.get(100) < skill.getCritChance())
  13310. {
  13311. absorbSoul(skill,((L2Npc)target));
  13312. }
  13313. }
  13314. }
  13315. if (mcrit)
  13316. sendPacket(new SystemMessage(SystemMessageId.CRITICAL_HIT_MAGIC));
  13317.  
  13318. if (isInOlympiadMode() &&
  13319. target instanceof L2PcInstance &&
  13320. ((L2PcInstance)target).isInOlympiadMode() &&
  13321. ((L2PcInstance)target).getOlympiadGameId() == getOlympiadGameId())
  13322. {
  13323. Olympiad.getInstance().notifyCompetitorDamage(this, damage, getOlympiadGameId());
  13324. }
  13325.  
  13326. final SystemMessage sm;
  13327.  
  13328. if (target.isInvul() && !(target instanceof L2NpcInstance))
  13329. {
  13330. sm = new SystemMessage(SystemMessageId.ATTACK_WAS_BLOCKED);
  13331. }
  13332. else if (target instanceof L2DoorInstance || target instanceof L2ControlTowerInstance)
  13333. {
  13334. sm = new SystemMessage(SystemMessageId.YOU_DID_S1_DMG);
  13335. sm.addNumber(damage);
  13336. }
  13337. else
  13338. {
  13339. sm = new SystemMessage(SystemMessageId.C1_GAVE_C2_DAMAGE_OF_S3);
  13340. sm.addPcName(this);
  13341. sm.addCharName(target);
  13342. sm.addNumber(damage);
  13343. }
  13344.  
  13345. sendPacket(sm);
  13346. }
  13347.  
  13348.  
  13349. /**
  13350. *
  13351. * @param npcId
  13352. */
  13353. public void setAgathionId(int npcId)
  13354. {
  13355. _agathionId = npcId;
  13356. }
  13357.  
  13358. /**
  13359. *
  13360. * @return
  13361. */
  13362. public int getAgathionId()
  13363. {
  13364. return _agathionId;
  13365. }
  13366.  
  13367. public int getVitalityPoints()
  13368. {
  13369. return getStat().getVitalityPoints();
  13370. }
  13371.  
  13372. public void setVitalityPoints(int points, boolean quiet)
  13373. {
  13374. getStat().setVitalityPoints(points, quiet);
  13375. }
  13376.  
  13377. public synchronized void updateVitalityPoints(float points, boolean useRates, boolean quiet)
  13378. {
  13379. getStat().updateVitalityPoints(points, useRates, quiet);
  13380. }
  13381.  
  13382. /*
  13383. * Function for skill summon friend or Gate Chant.
  13384. */
  13385. /** Request Teleport **/
  13386. public boolean teleportRequest(L2PcInstance requester, L2Skill skill)
  13387. {
  13388. if (_summonRequest.getTarget() != null && requester != null)
  13389. return false;
  13390. _summonRequest.setTarget(requester, skill);
  13391. return true;
  13392. }
  13393.  
  13394. /** Action teleport **/
  13395. public void teleportAnswer(int answer, int requesterId)
  13396. {
  13397. if (_summonRequest.getTarget() == null)
  13398. return;
  13399. if (answer == 1 && _summonRequest.getTarget().getCharId() == requesterId)
  13400. {
  13401. teleToTarget(this, _summonRequest.getTarget(), _summonRequest.getSkill());
  13402. }
  13403. _summonRequest.setTarget(null, null);
  13404. }
  13405.  
  13406. public void teleToTarget(L2PcInstance targetChar, L2PcInstance summonerChar, L2Skill summonSkill)
  13407. {
  13408. if (targetChar == null || summonerChar == null || summonSkill == null)
  13409. return;
  13410.  
  13411. if (!checkSummonerStatus(summonerChar))
  13412. return;
  13413. if (!checkTargetStatus(targetChar, summonerChar))
  13414. return;
  13415.  
  13416. int itemConsumeId = summonSkill.getTargetConsumeId();
  13417. int itemConsumeCount = summonSkill.getTargetConsume();
  13418. if (itemConsumeId != 0 && itemConsumeCount != 0)
  13419. {
  13420. //Delete by rocknow
  13421. if (targetChar.getInventory().getInventoryItemCount(itemConsumeId, 0) < itemConsumeCount)
  13422. {
  13423. SystemMessage sm = new SystemMessage(SystemMessageId.S1_REQUIRED_FOR_SUMMONING);
  13424. sm.addItemName(summonSkill.getTargetConsumeId());
  13425. targetChar.sendPacket(sm);
  13426. return;
  13427. }
  13428. targetChar.getInventory().destroyItemByItemId("Consume", itemConsumeId, itemConsumeCount, summonerChar, targetChar);
  13429. SystemMessage sm = new SystemMessage(SystemMessageId.S1_DISAPPEARED);
  13430. sm.addItemName(summonSkill.getTargetConsumeId());
  13431. targetChar.sendPacket(sm);
  13432. }
  13433. targetChar.teleToLocation(summonerChar.getX(), summonerChar.getY(), summonerChar.getZ(), true);
  13434. }
  13435.  
  13436. public static boolean checkSummonerStatus(L2PcInstance summonerChar)
  13437. {
  13438. if (summonerChar == null)
  13439. return false;
  13440.  
  13441. if (summonerChar.isInOlympiadMode())
  13442. {
  13443. summonerChar.sendPacket(new SystemMessage(SystemMessageId.THIS_ITEM_IS_NOT_AVAILABLE_FOR_THE_OLYMPIAD_EVENT));
  13444. return false;
  13445. }
  13446.  
  13447. if (summonerChar.inObserverMode())
  13448. {
  13449. return false;
  13450. }
  13451.  
  13452. if (summonerChar.isInsideZone(L2Character.ZONE_NOSUMMONFRIEND))
  13453. {
  13454. summonerChar.sendPacket(new SystemMessage(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING));
  13455. return false;
  13456. }
  13457. return true;
  13458. }
  13459.  
  13460. public static boolean checkTargetStatus(L2PcInstance targetChar, L2PcInstance summonerChar)
  13461. {
  13462. if (targetChar == null)
  13463. return false;
  13464.  
  13465. if (targetChar.isAlikeDead())
  13466. {
  13467. SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_DEAD_AT_THE_MOMENT_AND_CANNOT_BE_SUMMONED);
  13468. sm.addPcName(targetChar);
  13469. summonerChar.sendPacket(sm);
  13470. return false;
  13471. }
  13472.  
  13473. if (targetChar.isInStoreMode())
  13474. {
  13475. SystemMessage sm = new SystemMessage(SystemMessageId.C1_CURRENTLY_TRADING_OR_OPERATING_PRIVATE_STORE_AND_CANNOT_BE_SUMMONED);
  13476. sm.addPcName(targetChar);
  13477. summonerChar.sendPacket(sm);
  13478. return false;
  13479. }
  13480.  
  13481. if (targetChar.isRooted() || targetChar.isInCombat())
  13482. {
  13483. SystemMessage sm = new SystemMessage(SystemMessageId.C1_IS_ENGAGED_IN_COMBAT_AND_CANNOT_BE_SUMMONED);
  13484. sm.addPcName(targetChar);
  13485. summonerChar.sendPacket(sm);
  13486. return false;
  13487. }
  13488.  
  13489. if (targetChar.isInOlympiadMode())
  13490. {
  13491. summonerChar.sendPacket(new SystemMessage(SystemMessageId.YOU_CANNOT_SUMMON_PLAYERS_WHO_ARE_IN_OLYMPIAD));
  13492. return false;
  13493. }
  13494.  
  13495. if (targetChar.isFestivalParticipant())
  13496. {
  13497. summonerChar.sendPacket(new SystemMessage(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING));
  13498. return false;
  13499. }
  13500.  
  13501. if (targetChar.inObserverMode())
  13502. {
  13503. summonerChar.sendPacket(new SystemMessage(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING));
  13504. return false;
  13505. }
  13506.  
  13507. if (targetChar.isInsideZone(L2Character.ZONE_NOSUMMONFRIEND))
  13508. {
  13509. SystemMessage sm = new SystemMessage(SystemMessageId.C1_IN_SUMMON_BLOCKING_AREA);
  13510. sm.addString(targetChar.getName());
  13511. summonerChar.sendPacket(sm);
  13512. return false;
  13513. }
  13514.  
  13515. // on retail character can enter 7s dungeon with summon friend,
  13516. // but will be teleported away by mobs
  13517. // because currently this is not working in L2J we do not allowing summoning
  13518. if (summonerChar.isIn7sDungeon())
  13519. {
  13520. int targetCabal = SevenSigns.getInstance().getPlayerCabal(targetChar);
  13521. if (SevenSigns.getInstance().isSealValidationPeriod())
  13522. {
  13523. if (targetCabal != SevenSigns.getInstance().getCabalHighestScore())
  13524. {
  13525. summonerChar.sendPacket(new SystemMessage(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING));
  13526. return false;
  13527. }
  13528. }
  13529. else
  13530. {
  13531. if (targetCabal == SevenSigns.CABAL_NULL)
  13532. {
  13533. summonerChar.sendPacket(new SystemMessage(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING));
  13534. return false;
  13535. }
  13536. }
  13537. }
  13538. return true;
  13539. }
  13540.  
  13541. public void gatesRequest(L2DoorInstance door)
  13542. {
  13543. _gatesRequest.setTarget(door);
  13544. }
  13545.  
  13546. public void gatesAnswer(int answer, int type)
  13547. {
  13548. if (_gatesRequest.getDoor() == null)
  13549. return;
  13550.  
  13551. if (answer == 1 && getTarget() == _gatesRequest.getDoor() && type == 1)
  13552. _gatesRequest.getDoor().openMe();
  13553. else if (answer == 1 && getTarget() == _gatesRequest.getDoor() && type == 0)
  13554. _gatesRequest.getDoor().closeMe();
  13555.  
  13556. _gatesRequest.setTarget(null);
  13557. }
  13558.  
  13559. @Override
  13560. public void setIsCastingNow(boolean value)
  13561. {
  13562. if (value == false)
  13563. _currentSkill = null;
  13564.  
  13565. super.setIsCastingNow(value);
  13566. }
  13567.  
  13568. public void checkItemRestriction()
  13569. {
  13570. for (int i = 0; i < Inventory.PAPERDOLL_TOTALSLOTS; i++)
  13571. {
  13572. L2ItemInstance equippedItem = getInventory().getPaperdollItem(i);
  13573. if (equippedItem != null && !equippedItem.getItem().checkCondition(this, this, false))
  13574. {
  13575. getInventory().unEquipItemInSlotAndRecord(i);
  13576. if (equippedItem.isWear())
  13577. continue;
  13578.  
  13579. SystemMessage sm = null;
  13580. if (equippedItem.getItem().getBodyPart() == L2Item.SLOT_BACK)
  13581. {
  13582. sm = new SystemMessage(SystemMessageId.CLOAK_REMOVED_BECAUSE_ARMOR_SET_REMOVED);
  13583. sendPacket(sm);
  13584. return;
  13585. }
  13586.  
  13587. if (equippedItem.getEnchantLevel() > 0)
  13588. {
  13589. sm = new SystemMessage(SystemMessageId.EQUIPMENT_S1_S2_REMOVED);
  13590. sm.addNumber(equippedItem.getEnchantLevel());
  13591. sm.addItemName(equippedItem);
  13592. }
  13593. else
  13594. {
  13595. sm = new SystemMessage(SystemMessageId.S1_DISARMED);
  13596. sm.addItemName(equippedItem);
  13597. }
  13598. sendPacket(sm);
  13599. }
  13600. }
  13601. }
  13602.  
  13603. public void setTransformAllowedSkills(int[] ids)
  13604. {
  13605. _transformAllowedSkills = ids;
  13606. }
  13607.  
  13608. public boolean containsAllowedTransformSkill(int id)
  13609. {
  13610. for (int i = 0; i < _transformAllowedSkills.length; i++)
  13611. {
  13612. if (_transformAllowedSkills[i] == id)
  13613. {
  13614. return true;
  13615. }
  13616. }
  13617. return false;
  13618. }
  13619.  
  13620. /** Section for mounted pets */
  13621. class FeedTask implements Runnable
  13622. {
  13623. public void run()
  13624. {
  13625. try
  13626. {
  13627. if (!isMounted())
  13628. {
  13629. stopFeed();
  13630. return;
  13631. }
  13632.  
  13633. if (getCurrentFeed() > getFeedConsume())
  13634. {
  13635. // eat
  13636. setCurrentFeed(getCurrentFeed()-getFeedConsume());
  13637. }
  13638. else
  13639. {
  13640. // go back to pet control item, or simply said, unsummon it
  13641. setCurrentFeed(0);
  13642. stopFeed();
  13643. dismount();
  13644. sendPacket(new SystemMessage(SystemMessageId.OUT_OF_FEED_MOUNT_CANCELED));
  13645. }
  13646.  
  13647. int[] foodIds = L2PetDataTable.getFoodItemId(getMountNpcId());
  13648. if (foodIds[0] == 0) return;
  13649. L2ItemInstance food = null;
  13650. food = getInventory().getItemByItemId(foodIds[0]);
  13651.  
  13652. // use better strider food if exists
  13653. if (L2PetDataTable.isStrider(getMountNpcId()))
  13654. {
  13655. if (getInventory().getItemByItemId(foodIds[1]) != null)
  13656. food = getInventory().getItemByItemId(foodIds[1]);
  13657. }
  13658. if (food != null && isHungry())
  13659. {
  13660. IItemHandler handler = ItemHandler.getInstance().getItemHandler(food.getEtcItem());
  13661. if (handler != null)
  13662. {
  13663. handler.useItem(L2PcInstance.this, food);
  13664. SystemMessage sm = new SystemMessage(SystemMessageId.PET_TOOK_S1_BECAUSE_HE_WAS_HUNGRY);
  13665. sm.addItemName(food.getItemId());
  13666. sendPacket(sm);
  13667. }
  13668. }
  13669. }
  13670. catch (Exception e)
  13671. {
  13672. _log.log(Level.SEVERE, "Mounted Pet [NpcId: "+getMountNpcId()+"] a feed task error has occurred", e);
  13673. }
  13674. }
  13675. }
  13676.  
  13677. protected synchronized void startFeed(int npcId)
  13678. {
  13679. _canFeed = npcId > 0;
  13680. if (!isMounted())
  13681. return;
  13682. if (getPet() != null)
  13683. {
  13684. setCurrentFeed(((L2PetInstance) getPet()).getCurrentFed());
  13685. _controlItemId = getPet().getControlItemId();
  13686. sendPacket(new SetupGauge(3, getCurrentFeed()*10000/getFeedConsume(), getMaxFeed()*10000/getFeedConsume()));
  13687. if (!isDead())
  13688. {
  13689. _mountFeedTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new FeedTask(), 10000, 10000);
  13690. }
  13691. }
  13692. else if (_canFeed)
  13693. {
  13694. setCurrentFeed(getMaxFeed());
  13695. SetupGauge sg = new SetupGauge(3, getCurrentFeed()*10000/getFeedConsume(), getMaxFeed()*10000/getFeedConsume());
  13696. sendPacket(sg);
  13697. if (!isDead())
  13698. {
  13699. _mountFeedTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new FeedTask(), 10000, 10000);
  13700. }
  13701. }
  13702. }
  13703.  
  13704. protected synchronized void stopFeed()
  13705. {
  13706. if (_mountFeedTask != null)
  13707. {
  13708. _mountFeedTask.cancel(false);
  13709. _mountFeedTask = null;
  13710. if (Config.DEBUG) _log.fine("Pet [#"+_mountNpcId+"] feed task stop");
  13711. }
  13712. }
  13713.  
  13714. protected final void clearPetData()
  13715. {
  13716. _data = null;
  13717. }
  13718.  
  13719. protected final L2PetData getPetData(int npcId)
  13720. {
  13721. if (_data == null && getPet() != null)
  13722. _data = L2PetDataTable.getInstance().getPetData(getPet().getNpcId(), getPet().getLevel());
  13723. else if (_data == null && npcId > 0)
  13724. {
  13725. _data = L2PetDataTable.getInstance().getPetData(npcId, getLevel());
  13726. }
  13727.  
  13728. return _data;
  13729. }
  13730.  
  13731. public int getCurrentFeed() { return _curFeed; }
  13732.  
  13733. protected int getFeedConsume()
  13734. {
  13735. // if pet is attacking
  13736. if (isAttackingNow())
  13737. return getPetData(_mountNpcId).getPetFeedBattle();
  13738. else
  13739. return getPetData(_mountNpcId).getPetFeedNormal();
  13740. }
  13741.  
  13742. public void setCurrentFeed(int num)
  13743. {
  13744. _curFeed = num > getMaxFeed() ? getMaxFeed() : num;
  13745. SetupGauge sg = new SetupGauge(3, getCurrentFeed()*10000/getFeedConsume(), getMaxFeed()*10000/getFeedConsume());
  13746. sendPacket(sg);
  13747. }
  13748.  
  13749. protected int getMaxFeed()
  13750. {
  13751. return getPetData(_mountNpcId).getPetMaxFeed();
  13752. }
  13753.  
  13754. protected boolean isHungry()
  13755. {
  13756. return _canFeed ? (getCurrentFeed() < (0.55 * getPetData(getMountNpcId()).getPetMaxFeed())):false;
  13757. }
  13758.  
  13759. public class dismount implements Runnable
  13760. {
  13761. public void run()
  13762. {
  13763. try
  13764. {
  13765. L2PcInstance.this.dismount();
  13766. }
  13767. catch (Exception e)
  13768. {e.printStackTrace();}
  13769. }
  13770. }
  13771.  
  13772. public void enteredNoLanding()
  13773. {
  13774. _dismountTask = ThreadPoolManager.getInstance().scheduleGeneral(new L2PcInstance.dismount(), 5000);
  13775. }
  13776.  
  13777. public void exitedNoLanding()
  13778. {
  13779. if (_dismountTask != null)
  13780. {
  13781. _dismountTask.cancel(true);
  13782. _dismountTask = null;
  13783. }
  13784. }
  13785.  
  13786. public void storePetFood(int petId)
  13787. {
  13788. if (_controlItemId != 0 && petId != 0)
  13789. {
  13790. String req;
  13791. req = "UPDATE pets SET fed=? WHERE item_obj_id = ?";
  13792. Connection con = null;
  13793. try
  13794. {
  13795. con = L2DatabaseFactory.getInstance().getConnection();
  13796. PreparedStatement statement = con.prepareStatement(req);
  13797. statement.setInt(1, getCurrentFeed());
  13798. statement.setInt(2, _controlItemId);
  13799. statement.executeUpdate();
  13800. statement.close();
  13801. _controlItemId = 0;
  13802. }
  13803. catch (Exception e)
  13804. {
  13805. _log.log(Level.SEVERE, "Failed to store Pet [NpcId: "+petId+"] data", e);
  13806. }
  13807. finally
  13808. {
  13809. try
  13810. {
  13811. con.close();
  13812. }
  13813. catch (Exception e)
  13814. {
  13815. }
  13816. }
  13817. }
  13818. }
  13819. /** End of section for mounted pets */
  13820.  
  13821. @Override
  13822. public int getAttackElementValue(byte attribute)
  13823. {
  13824. int value = super.getAttackElementValue(attribute);
  13825.  
  13826. // 20% if summon exist
  13827. if (getPet() != null && getClassId().isSummoner() && (getPet() instanceof L2SummonInstance))
  13828. return value / 5;
  13829.  
  13830. return value;
  13831. }
  13832.  
  13833. /**
  13834. * @return afro haircut id
  13835. */
  13836. public int getAfroHaircutId()
  13837. {
  13838. return _afroId ;
  13839. }
  13840.  
  13841. public void setAfroHaircutId(int id)
  13842. {
  13843. _afroId = id;
  13844. broadcastUserInfo();
  13845. }
  13846.  
  13847. public void setIsInSiege(boolean b)
  13848. {
  13849. _isInSiege = b;
  13850. }
  13851.  
  13852. public boolean isInSiege()
  13853. {
  13854. return _isInSiege;
  13855. }
  13856.  
  13857. public FloodProtectors getFloodProtectors()
  13858. {
  13859. return _floodProtectors;
  13860. }
  13861.  
  13862. public boolean isFlyingMounted()
  13863. {
  13864. return _isFlyingMounted;
  13865. }
  13866.  
  13867. public void setIsFlyingMounted(boolean val)
  13868. {
  13869. _isFlyingMounted = val;
  13870. setIsFlying(val);
  13871. }
  13872.  
  13873. /**
  13874. * Returns the Number of Charges this L2PcInstance got.
  13875. * @return
  13876. */
  13877. public int getCharges()
  13878. {
  13879. return _charges.get();
  13880. }
  13881.  
  13882. public synchronized void increaseCharges(int count, int max)
  13883. {
  13884. if (_charges.get() >= max)
  13885. {
  13886. sendPacket(new SystemMessage(SystemMessageId.FORCE_MAXLEVEL_REACHED));
  13887. return;
  13888. }
  13889. else
  13890. {
  13891. // if no charges - start clear task
  13892. if (_charges.get() == 0)
  13893. restartChargeTask();
  13894. }
  13895.  
  13896. if (_charges.addAndGet(count) >= max)
  13897. {
  13898. _charges.set(max);
  13899. sendPacket(new SystemMessage(SystemMessageId.FORCE_MAXLEVEL_REACHED));
  13900. }
  13901. else
  13902. {
  13903. SystemMessage sm = new SystemMessage(SystemMessageId.FORCE_INCREASED_TO_S1);
  13904. sm.addNumber(_charges.get());
  13905. sendPacket(sm);
  13906. }
  13907.  
  13908. sendPacket(new EtcStatusUpdate(this));
  13909. }
  13910.  
  13911. public synchronized boolean decreaseCharges(int count)
  13912. {
  13913. if (_charges.get() < count)
  13914. return false;
  13915.  
  13916. if (_charges.addAndGet(-count) == 0)
  13917. stopChargeTask();
  13918.  
  13919. sendPacket(new EtcStatusUpdate(this));
  13920. return true;
  13921. }
  13922.  
  13923. public void clearCharges()
  13924. {
  13925. _charges.set(0);
  13926. sendPacket(new EtcStatusUpdate(this));
  13927. }
  13928.  
  13929. /**
  13930. * Starts/Restarts the ChargeTask to Clear Charges after 10 Mins.
  13931. */
  13932. private void restartChargeTask()
  13933. {
  13934. if (_chargeTask != null)
  13935. {
  13936. _chargeTask.cancel(false);
  13937. _chargeTask = null;
  13938. }
  13939. _chargeTask = ThreadPoolManager.getInstance().scheduleGeneral(new ChargeTask(this), 600000);
  13940. }
  13941.  
  13942. /**
  13943. * Stops the Charges Clearing Task.
  13944. */
  13945. public void stopChargeTask()
  13946. {
  13947. if (_chargeTask != null)
  13948. {
  13949. _chargeTask.cancel(false);
  13950. _chargeTask = null;
  13951. }
  13952. }
  13953.  
  13954. private class ChargeTask implements Runnable
  13955. {
  13956. L2PcInstance _player;
  13957.  
  13958. protected ChargeTask(L2PcInstance player)
  13959. {
  13960. _player = player;
  13961. }
  13962.  
  13963. public void run()
  13964. {
  13965. _player.clearCharges();
  13966. }
  13967. }
  13968.  
  13969. public class TeleportBookmark
  13970. {
  13971. public int _id,_x,_y,_z,_icon;
  13972. public String _name,_tag;
  13973.  
  13974. TeleportBookmark(int id, int x, int y, int z, int icon,String tag , String name)
  13975. {
  13976. _id = id;
  13977. _x = x;
  13978. _y = y;
  13979. _z = z;
  13980. _icon = icon;
  13981. _name = name;
  13982. _tag = tag;
  13983. }
  13984.  
  13985. }
  13986.  
  13987. public void TeleportBookmarkModify(int Id,int icon, String tag,String name)
  13988. {
  13989. int count = 0;
  13990. int size = tpbookmark.size();
  13991. while(size > count)
  13992. {
  13993. if(tpbookmark.get(count)._id==Id)
  13994. {
  13995. tpbookmark.get(count)._icon = icon;
  13996. tpbookmark.get(count)._tag = tag;
  13997. tpbookmark.get(count)._name = name;
  13998.  
  13999. Connection con = null;
  14000.  
  14001. try
  14002. {
  14003.  
  14004. con = L2DatabaseFactory.getInstance().getConnection();
  14005. PreparedStatement statement = con.prepareStatement(UPDATE_TP_BOOKMARK);
  14006.  
  14007. statement.setInt(1, icon);
  14008. statement.setString(2, tag);
  14009. statement.setString(3, name);
  14010. statement.setInt(4, getObjectId());
  14011. statement.setInt(5, Id);
  14012.  
  14013. statement.execute();
  14014. statement.close();
  14015. }
  14016. catch (Exception e) { _log.warning("Could not update character teleport bookmark data: "+ e); }
  14017. finally { try { con.close(); } catch (Exception e) {} }
  14018.  
  14019. }
  14020. count++;
  14021. }
  14022.  
  14023. sendPacket(new ExGetBookMarkInfoPacket(this));
  14024.  
  14025. }
  14026.  
  14027. public void TeleportBookmarkDelete(int Id)
  14028. {
  14029. Connection con = null;
  14030.  
  14031. try
  14032. {
  14033. con = L2DatabaseFactory.getInstance().getConnection();
  14034. PreparedStatement statement = con.prepareStatement(DELETE_TP_BOOKMARK);
  14035.  
  14036. statement.setInt(1, getObjectId());
  14037. statement.setInt(2, Id);
  14038.  
  14039. statement.execute();
  14040. statement.close();
  14041. }
  14042. catch (Exception e) { _log.warning("Could not delete character teleport bookmark data: "+ e); }
  14043. finally { try { con.close(); } catch (Exception e) {} }
  14044.  
  14045. int count = 0;
  14046. int size = tpbookmark.size();
  14047.  
  14048. while(size > count)
  14049. {
  14050. if(tpbookmark.get(count)._id==Id)
  14051. {
  14052. tpbookmark.remove(count);
  14053. break;
  14054. }
  14055. count++;
  14056. }
  14057.  
  14058. sendPacket(new ExGetBookMarkInfoPacket(this));
  14059. }
  14060.  
  14061. public void TeleportBookmarkGo(int Id)
  14062. {
  14063. if(!TeleportBookmarkCondition(0)||this==null)
  14064. return;
  14065. if (getInventory().getInventoryItemCount(13016,0)==0)
  14066. {
  14067. sendPacket(new SystemMessage(2359));
  14068. return;
  14069. }
  14070. SystemMessage sm = new SystemMessage(SystemMessageId.S1_DISAPPEARED);
  14071. sm.addItemName(13016);
  14072. sendPacket(sm);
  14073. int count = 0;
  14074. int size = tpbookmark.size();
  14075. while(size > count)
  14076. {
  14077. if(tpbookmark.get(count)._id==Id)
  14078. {
  14079. destroyItem("Consume", getInventory().getItemByItemId(13016).getObjectId(), 1, null, false);
  14080. this.teleToLocation(tpbookmark.get(count)._x, tpbookmark.get(count)._y, tpbookmark.get(count)._z);
  14081. break;
  14082. }
  14083. count++;
  14084. }
  14085. sendPacket(new ExGetBookMarkInfoPacket(this));
  14086. }
  14087.  
  14088. public boolean TeleportBookmarkCondition(int type)
  14089. {
  14090.  
  14091. if(this.isInCombat())
  14092. {
  14093. sendPacket(new SystemMessage(2348));
  14094. return false;
  14095. }
  14096. else if (this.isInSiege())
  14097. {
  14098. sendPacket(new SystemMessage(2349));
  14099. return false;
  14100. }
  14101. else if (this.isInDuel())
  14102. {
  14103. sendPacket(new SystemMessage(2350));
  14104. return false;
  14105. }
  14106. else if (this.isFlying())
  14107. {
  14108. sendPacket(new SystemMessage(2351));
  14109. return false;
  14110. }
  14111. else if (this.isInOlympiadMode())
  14112. {
  14113. sendPacket(new SystemMessage(2352));
  14114. return false;
  14115. }
  14116. else if (this.isParalyzed())
  14117. {
  14118. sendPacket(new SystemMessage(2353));
  14119. return false;
  14120. }
  14121. else if (this.isDead())
  14122. {
  14123. sendPacket(new SystemMessage(2354));
  14124. return false;
  14125. }
  14126. else if (this.isInBoat() || this.isInAirShip() || this.isInJail() || this.isInsideZone(ZONE_NOSUMMONFRIEND))
  14127. {
  14128. if(type == 0)
  14129. sendPacket(new SystemMessage(2355));
  14130. else if (type == 1)
  14131. sendPacket(new SystemMessage(2410));
  14132. return false;
  14133. }
  14134. else if (this.isInWater())
  14135. {
  14136. sendPacket(new SystemMessage(2356));
  14137. return false;
  14138. }
  14139. /* TODO: Instant Zone still not implement
  14140. else if (this.isInsideZone(ZONE_INSTANT))
  14141. {
  14142. sendPacket(new SystemMessage(2357));
  14143. return;
  14144. }
  14145. */
  14146. else
  14147. return true;
  14148. }
  14149.  
  14150. public void TeleportBookmarkAdd(int x,int y,int z,int icon, String tag, String name)
  14151. {
  14152. if(this == null)
  14153. return;
  14154.  
  14155. if(!TeleportBookmarkCondition(1))
  14156. return;
  14157.  
  14158. if(tpbookmark.size()>=_bookmarkslot)
  14159. {
  14160. sendPacket(new SystemMessage(2358));
  14161. return;
  14162. }
  14163.  
  14164. if(getInventory().getInventoryItemCount(20033,0) == 0)
  14165. {
  14166. sendPacket(new SystemMessage(6501));
  14167. return;
  14168. }
  14169.  
  14170. int count = 0;
  14171. int id = 1;
  14172. FastList<Integer> idlist = new FastList<Integer>();
  14173.  
  14174. int size = tpbookmark.size();
  14175.  
  14176. while(size > count)
  14177. {
  14178. idlist.add(tpbookmark.get(count)._id);
  14179. count++;
  14180. }
  14181.  
  14182. for(int i=1;i<10;i++)
  14183. {
  14184. if(!idlist.contains(i))
  14185. {
  14186. id = i;
  14187. break;
  14188. }
  14189. }
  14190.  
  14191. TeleportBookmark tpadd = new TeleportBookmark(id,x,y,z,icon,tag,name);
  14192. if(tpbookmark==null)
  14193. tpbookmark = new FastList<TeleportBookmark>();
  14194.  
  14195. tpbookmark.add(tpadd);
  14196.  
  14197. destroyItem("Consume", getInventory().getItemByItemId(20033).getObjectId(), 1, null, false);
  14198.  
  14199. SystemMessage sm = new SystemMessage(SystemMessageId.S1_DISAPPEARED);
  14200. sm.addItemName(20033);
  14201. sendPacket(sm);
  14202.  
  14203. Connection con = null;
  14204.  
  14205. try
  14206. {
  14207.  
  14208. con = L2DatabaseFactory.getInstance().getConnection();
  14209. PreparedStatement statement = con.prepareStatement(INSERT_TP_BOOKMARK);
  14210.  
  14211. statement.setInt(1, getObjectId());
  14212. statement.setInt(2, id);
  14213. statement.setInt(3, x);
  14214. statement.setInt(4, y);
  14215. statement.setInt(5, z);
  14216. statement.setInt(6, icon);
  14217. statement.setString(7, tag);
  14218. statement.setString(8, name);
  14219.  
  14220.  
  14221. statement.execute();
  14222. statement.close();
  14223. }
  14224. catch (Exception e) { _log.warning("Could not insert character teleport bookmark data: "+ e); }
  14225. finally { try { con.close(); } catch (Exception e) {} }
  14226.  
  14227. sendPacket(new ExGetBookMarkInfoPacket(this));
  14228. }
  14229.  
  14230. public void restoreTeleportBookmark()
  14231. {
  14232. if(tpbookmark==null)
  14233. tpbookmark = new FastList<TeleportBookmark>();
  14234. Connection con = null;
  14235.  
  14236. try
  14237. {
  14238. con = L2DatabaseFactory.getInstance().getConnection();
  14239. PreparedStatement statement = con.prepareStatement(RESTORE_TP_BOOKMARK);
  14240. statement.setInt(1, getObjectId());
  14241. ResultSet rset = statement.executeQuery();
  14242.  
  14243. while (rset.next())
  14244. {
  14245. tpbookmark.add(new TeleportBookmark(rset.getInt("Id"), rset.getInt("x"), rset.getInt("y"), rset.getInt("z"), rset.getInt("icon"), rset.getString("tag"), rset.getString("name")));
  14246. }
  14247.  
  14248. rset.close();
  14249. statement.close();
  14250. }
  14251. catch (Exception e)
  14252. {
  14253. _log.log(Level.SEVERE, "Failed restoing character teleport bookmark.", e);
  14254. }
  14255. finally
  14256. {
  14257. try { con.close(); } catch (Exception e) {}
  14258. }
  14259. }
  14260.  
  14261. @Override
  14262. public void sendInfo(L2PcInstance activeChar)
  14263. {
  14264. if(isInBoat())
  14265. {
  14266. getPosition().setWorldPosition(getBoat().getPosition().getWorldPosition());
  14267.  
  14268. activeChar.sendPacket(new CharInfo(this));
  14269. activeChar.sendPacket(new ExBrExtraUserInfo(this));
  14270. int relation1 = getRelation(activeChar);
  14271. int relation2 = activeChar.getRelation(this);
  14272. if (getKnownList().getKnownRelations().get(activeChar.getObjectId()) != null && getKnownList().getKnownRelations().get(activeChar.getObjectId()) != relation1)
  14273. {
  14274. activeChar.sendPacket(new RelationChanged(this, relation1, activeChar.isAutoAttackable(this)));
  14275. if (getPet() != null)
  14276. activeChar.sendPacket(new RelationChanged(getPet(), relation1, activeChar.isAutoAttackable(this)));
  14277. }
  14278. if (activeChar.getKnownList().getKnownRelations().get(getObjectId()) != null && activeChar.getKnownList().getKnownRelations().get(getObjectId()) != relation2)
  14279. {
  14280. sendPacket(new RelationChanged(activeChar, relation2, isAutoAttackable(activeChar)));
  14281. if (activeChar.getPet() != null)
  14282. sendPacket(new RelationChanged(activeChar.getPet(), relation2, isAutoAttackable(activeChar)));
  14283. }
  14284. activeChar.sendPacket(new GetOnVehicle(this, getBoat(), getInBoatPosition().getX(), getInBoatPosition().getY(), getInBoatPosition().getZ()));
  14285. /*if(getBoat().GetVehicleDeparture() == null)
  14286. {
  14287.  
  14288. int xboat = getBoat().getX();
  14289. int yboat= getBoat().getY();
  14290. double modifier = Math.PI/2;
  14291. if (yboat == 0)
  14292. {
  14293. yboat = 1;
  14294. }
  14295. if(yboat < 0)
  14296. {
  14297. modifier = -modifier;
  14298. }
  14299. double angleboat = modifier - Math.atan(xboat/yboat);
  14300. int xp = getX();
  14301. int yp = getY();
  14302. modifier = Math.PI/2;
  14303. if (yp == 0)
  14304. {
  14305. yboat = 1;
  14306. }
  14307. if(yboat < 0)
  14308. {
  14309. modifier = -modifier;
  14310. }
  14311. double anglep = modifier - Math.atan(yp/xp);
  14312.  
  14313. double finx = Math.cos(anglep - angleboat)*Math.sqrt(xp *xp +yp*yp ) + Math.cos(angleboat)*Math.sqrt(xboat *xboat +yboat*yboat );
  14314. double finy = Math.sin(anglep - angleboat)*Math.sqrt(xp *xp +yp*yp ) + Math.sin(angleboat)*Math.sqrt(xboat *xboat +yboat*yboat );
  14315. //getPosition().setWorldPosition(getBoat().getX() - getInBoatPosition().x,getBoat().getY() - getInBoatPosition().y,getBoat().getZ()- getInBoatPosition().z);
  14316. getPosition().setWorldPosition((int)finx,(int)finy,getBoat().getZ()- getInBoatPosition().z);
  14317.  
  14318. }*/
  14319. }
  14320. else if(isInAirShip())
  14321. {
  14322. getPosition().setWorldPosition(getAirShip().getPosition().getWorldPosition());
  14323.  
  14324. activeChar.sendPacket(new CharInfo(this));
  14325. activeChar.sendPacket(new ExBrExtraUserInfo(this));
  14326. int relation1 = getRelation(activeChar);
  14327. int relation2 = activeChar.getRelation(this);
  14328. if (getKnownList().getKnownRelations().get(activeChar.getObjectId()) != null && getKnownList().getKnownRelations().get(activeChar.getObjectId()) != relation1)
  14329. {
  14330. activeChar.sendPacket(new RelationChanged(this, relation1, activeChar.isAutoAttackable(this)));
  14331. if (getPet() != null)
  14332. activeChar.sendPacket(new RelationChanged(getPet(), relation1, activeChar.isAutoAttackable(this)));
  14333. }
  14334. if (activeChar.getKnownList().getKnownRelations().get(getObjectId()) != null && activeChar.getKnownList().getKnownRelations().get(getObjectId()) != relation2)
  14335. {
  14336. sendPacket(new RelationChanged(activeChar, relation2, isAutoAttackable(activeChar)));
  14337. if (activeChar.getPet() != null)
  14338. sendPacket(new RelationChanged(activeChar.getPet(), relation2, isAutoAttackable(activeChar)));
  14339. }
  14340. activeChar.sendPacket(new ExGetOnAirShip(this, getAirShip()));
  14341. }
  14342. else
  14343. {
  14344. activeChar.sendPacket(new CharInfo(this));
  14345. activeChar.sendPacket(new ExBrExtraUserInfo(this));
  14346. int relation1 = getRelation(activeChar);
  14347. int relation2 = activeChar.getRelation(this);
  14348. if (getKnownList().getKnownRelations().get(activeChar.getObjectId()) != null && getKnownList().getKnownRelations().get(activeChar.getObjectId()) != relation1)
  14349. {
  14350. activeChar.sendPacket(new RelationChanged(this, relation1, activeChar.isAutoAttackable(this)));
  14351. if (getPet() != null)
  14352. activeChar.sendPacket(new RelationChanged(getPet(), relation1, activeChar.isAutoAttackable(this)));
  14353. }
  14354. if (activeChar.getKnownList().getKnownRelations().get(getObjectId()) != null && activeChar.getKnownList().getKnownRelations().get(getObjectId()) != relation2)
  14355. {
  14356. sendPacket(new RelationChanged(activeChar, relation2, isAutoAttackable(activeChar)));
  14357. if (activeChar.getPet() != null)
  14358. sendPacket(new RelationChanged(activeChar.getPet(), relation2, isAutoAttackable(activeChar)));
  14359. }
  14360. }
  14361. if (getMountType() == 4)
  14362. {
  14363. // TODO: Remove when horse mounts fixed
  14364. activeChar.sendPacket(new Ride(this, false, 0));
  14365. activeChar.sendPacket(new Ride(this, true, getMountNpcId()));
  14366. }
  14367.  
  14368. switch (getPrivateStoreType())
  14369. {
  14370. case L2PcInstance.STORE_PRIVATE_SELL:
  14371. activeChar.sendPacket(new PrivateStoreMsgSell(this));
  14372. break;
  14373. case L2PcInstance.STORE_PRIVATE_PACKAGE_SELL:
  14374. activeChar.sendPacket(new ExPrivateStoreSetWholeMsg(this));
  14375. break;
  14376. case L2PcInstance.STORE_PRIVATE_BUY:
  14377. activeChar.sendPacket(new PrivateStoreMsgBuy(this));
  14378. break;
  14379. case L2PcInstance.STORE_PRIVATE_MANUFACTURE:
  14380. activeChar.sendPacket(new RecipeShopMsg(this));
  14381. break;
  14382. }
  14383. }
  14384.  
  14385. }
Advertisement
Add Comment
Please, Sign In to add comment