Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2019
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package l2s.gameserver.model;
  2.  
  3. import static l2s.gameserver.network.l2.s2c.ExSetCompassZoneCode.ZONE_ALTERED_FLAG;
  4. import static l2s.gameserver.network.l2.s2c.ExSetCompassZoneCode.ZONE_PEACE_FLAG;
  5. import static l2s.gameserver.network.l2.s2c.ExSetCompassZoneCode.ZONE_PVP_FLAG;
  6. import static l2s.gameserver.network.l2.s2c.ExSetCompassZoneCode.ZONE_SIEGE_FLAG;
  7. import static l2s.gameserver.network.l2.s2c.ExSetCompassZoneCode.ZONE_SSQ_FLAG;
  8.  
  9. import java.awt.*;
  10. import java.sql.Connection;
  11. import java.sql.PreparedStatement;
  12. import java.sql.ResultSet;
  13. import java.sql.SQLException;
  14. import java.sql.Statement;
  15. import java.util.*;
  16. import java.util.List;
  17. import java.util.concurrent.*;
  18. import java.util.concurrent.atomic.AtomicBoolean;
  19. import java.util.concurrent.atomic.AtomicInteger;
  20. import java.util.concurrent.locks.Lock;
  21. import java.util.concurrent.locks.ReentrantLock;
  22.  
  23. import gnu.trove.iterator.TIntLongIterator;
  24. import gnu.trove.map.TIntLongMap;
  25. import gnu.trove.map.hash.TIntLongHashMap;
  26.  
  27. import l2s.commons.collections.LazyArrayList;
  28. import l2s.commons.dbutils.DbUtils;
  29. import l2s.commons.lang.reference.HardReference;
  30. import l2s.commons.lang.reference.HardReferences;
  31. import l2s.commons.threading.RunnableImpl;
  32. import l2s.commons.util.Rnd;
  33. import l2s.commons.util.concurrent.atomic.AtomicState;
  34. import l2s.gameserver.*;
  35. import l2s.gameserver.ai.CtrlEvent;
  36. import l2s.gameserver.ai.CtrlIntention;
  37. import l2s.gameserver.ai.FakeAI;
  38. import l2s.gameserver.ai.PlayableAI.AINextAction;
  39. import l2s.gameserver.ai.PlayerAI;
  40. import l2s.gameserver.dao.*;
  41. import l2s.gameserver.data.QuestHolder;
  42. import l2s.gameserver.data.xml.holder.*;
  43. import l2s.gameserver.database.DatabaseFactory;
  44. import l2s.gameserver.database.mysql;
  45. import l2s.gameserver.handler.items.IItemHandler;
  46. import l2s.gameserver.handler.onshiftaction.OnShiftActionHolder;
  47. import l2s.gameserver.idfactory.IdFactory;
  48. import l2s.gameserver.instancemanager.*;
  49. import l2s.gameserver.instancemanager.BotCheckManager.BotCheckQuestion;
  50. import l2s.gameserver.instancemanager.OfflineBufferManager.BufferData;
  51. import l2s.gameserver.listener.actor.player.OnAnswerListener;
  52. import l2s.gameserver.listener.actor.player.OnPlayerChatMessageReceive;
  53. import l2s.gameserver.listener.actor.player.impl.BotCheckAnswerListner;
  54. import l2s.gameserver.listener.actor.player.impl.ReviveAnswerListener;
  55. import l2s.gameserver.listener.actor.player.impl.SummonAnswerListener;
  56. import l2s.gameserver.listener.hooks.ListenerHook;
  57. import l2s.gameserver.listener.hooks.ListenerHookType;
  58. import l2s.gameserver.model.GameObjectTasks.EndSitDownTask;
  59. import l2s.gameserver.model.GameObjectTasks.EndStandUpTask;
  60. import l2s.gameserver.model.GameObjectTasks.HourlyTask;
  61. import l2s.gameserver.model.GameObjectTasks.KickTask;
  62. import l2s.gameserver.model.GameObjectTasks.PvPFlagTask;
  63. import l2s.gameserver.model.GameObjectTasks.UnJailTask;
  64. import l2s.gameserver.model.GameObjectTasks.WaterTask;
  65. import l2s.gameserver.model.Request.L2RequestType;
  66. import l2s.gameserver.model.Zone.ZoneType;
  67. import l2s.gameserver.model.actor.basestats.PlayerBaseStats;
  68. import l2s.gameserver.model.actor.flags.PlayerFlags;
  69. import l2s.gameserver.model.actor.instances.creature.Abnormal;
  70. import l2s.gameserver.model.actor.instances.player.*;
  71. import l2s.gameserver.model.actor.instances.player.FriendList;
  72. import l2s.gameserver.model.actor.instances.player.tasks.EnableUserRelationTask;
  73. import l2s.gameserver.model.actor.listener.PlayerListenerList;
  74. import l2s.gameserver.model.actor.recorder.PlayerStatsChangeRecorder;
  75. import l2s.gameserver.model.base.*;
  76. import l2s.gameserver.model.entity.Hero;
  77. import l2s.gameserver.model.entity.Reflection;
  78. import l2s.gameserver.model.entity.events.Event;
  79. import l2s.gameserver.model.entity.events.impl.*;
  80. import l2s.gameserver.model.entity.olympiad.Olympiad;
  81. import l2s.gameserver.model.entity.olympiad.OlympiadGame;
  82. import l2s.gameserver.model.entity.olympiad.OlympiadParticipiantData;
  83. import l2s.gameserver.model.entity.residence.Castle;
  84. import l2s.gameserver.model.entity.residence.ClanHall;
  85. import l2s.gameserver.model.entity.residence.Residence;
  86. import l2s.gameserver.model.entity.residence.ResidenceSide;
  87. import l2s.gameserver.model.instances.*;
  88. import l2s.gameserver.model.instances.SummonInstance.RestoredSummon;
  89. import l2s.gameserver.model.instances.residences.SiegeToggleNpcInstance;
  90. import l2s.gameserver.model.items.Inventory;
  91. import l2s.gameserver.model.items.ItemContainer;
  92. import l2s.gameserver.model.items.ItemInstance;
  93. import l2s.gameserver.model.items.LockType;
  94. import l2s.gameserver.model.items.ManufactureItem;
  95. import l2s.gameserver.model.items.PcFreight;
  96. import l2s.gameserver.model.items.PcInventory;
  97. import l2s.gameserver.model.items.PcRefund;
  98. import l2s.gameserver.model.items.PcWarehouse;
  99. import l2s.gameserver.model.items.TradeItem;
  100. import l2s.gameserver.model.items.Warehouse;
  101. import l2s.gameserver.model.items.Warehouse.WarehouseType;
  102. import l2s.gameserver.model.items.attachment.FlagItemAttachment;
  103. import l2s.gameserver.model.items.attachment.PickableAttachment;
  104. import l2s.gameserver.model.matching.MatchingRoom;
  105. import l2s.gameserver.model.petition.PetitionMainGroup;
  106. import l2s.gameserver.model.pledge.Alliance;
  107. import l2s.gameserver.model.pledge.Clan;
  108. import l2s.gameserver.model.pledge.ClanWar;
  109. import l2s.gameserver.model.pledge.Privilege;
  110. import l2s.gameserver.model.pledge.RankPrivs;
  111. import l2s.gameserver.model.pledge.SubUnit;
  112. import l2s.gameserver.model.pledge.UnitMember;
  113. import l2s.gameserver.model.quest.Quest;
  114. import l2s.gameserver.model.quest.QuestEventType;
  115. import l2s.gameserver.model.quest.QuestState;
  116. import l2s.gameserver.network.authcomm.AuthServerCommunication;
  117. import l2s.gameserver.network.authcomm.gs2as.BonusRequest;
  118. import l2s.gameserver.network.authcomm.gs2as.ReduceAccountPoints;
  119. import l2s.gameserver.network.l2.GameClient;
  120. import l2s.gameserver.network.l2.components.*;
  121. import l2s.gameserver.network.l2.s2c.*;
  122. import l2s.gameserver.network.l2.s2c.updatetype.IUpdateTypeComponent;
  123. import l2s.gameserver.skills.AbnormalType;
  124. import l2s.gameserver.skills.EffectType;
  125. import l2s.gameserver.skills.SkillEntry;
  126. import l2s.gameserver.skills.TimeStamp;
  127. import l2s.gameserver.skills.skillclasses.Summon;
  128. import l2s.gameserver.stats.Formulas;
  129. import l2s.gameserver.stats.Stats;
  130. import l2s.gameserver.stats.funcs.FuncTemplate;
  131. import l2s.gameserver.tables.ClanTable;
  132. import l2s.gameserver.taskmanager.AutoSaveManager;
  133. import l2s.gameserver.taskmanager.LazyPrecisionTaskManager;
  134. import l2s.gameserver.templates.CreatureTemplate;
  135. import l2s.gameserver.templates.InstantZone;
  136. import l2s.gameserver.templates.OptionDataTemplate;
  137. import l2s.gameserver.templates.fakeplayer.FakePlayerAITemplate;
  138. import l2s.gameserver.templates.item.ArmorTemplate.ArmorType;
  139. import l2s.gameserver.templates.item.ItemTemplate;
  140. import l2s.gameserver.templates.item.ItemType;
  141. import l2s.gameserver.templates.item.RecipeTemplate;
  142. import l2s.gameserver.templates.item.WeaponTemplate;
  143. import l2s.gameserver.templates.item.WeaponTemplate.WeaponType;
  144. import l2s.gameserver.templates.item.data.ItemData;
  145. import l2s.gameserver.templates.npc.NpcTemplate;
  146. import l2s.gameserver.templates.pet.PetData;
  147. import l2s.gameserver.templates.player.PlayerTemplate;
  148. import l2s.gameserver.templates.player.transform.TransformTemplate;
  149. import l2s.gameserver.templates.premiumaccount.PremiumAccountTemplate;
  150. import l2s.gameserver.utils.*;
  151.  
  152. import org.apache.commons.lang3.ArrayUtils;
  153. import org.apache.commons.lang3.math.NumberUtils;
  154. import org.napile.pair.primitive.IntObjectPair;
  155. import org.napile.pair.primitive.impl.IntObjectPairImpl;
  156. import org.napile.primitive.Containers;
  157. import org.napile.primitive.maps.IntObjectMap;
  158. import org.napile.primitive.maps.impl.CHashIntObjectMap;
  159. import org.napile.primitive.maps.impl.CTreeIntObjectMap;
  160. import org.napile.primitive.maps.impl.HashIntObjectMap;
  161. import org.slf4j.Logger;
  162. import org.slf4j.LoggerFactory;
  163.  
  164. public final class Player extends Playable implements PlayerGroup
  165. {
  166.     private static final long serialVersionUID = 1L;
  167.  
  168.     public static final int DEFAULT_NAME_COLOR = 0xFFFFFF;
  169.     public static final int DEFAULT_TITLE_COLOR = 0xFFFF77;
  170.     public static final int MAX_POST_FRIEND_SIZE = 100;
  171.  
  172.     private static final Logger _log = LoggerFactory.getLogger(Player.class);
  173.  
  174.     public static final String NO_TRADERS_VAR = "notraders";
  175.     public static final String NO_ANIMATION_OF_CAST_VAR = "notShowBuffAnim";
  176.     public static final String MY_BIRTHDAY_RECEIVE_YEAR = "MyBirthdayReceiveYear";
  177.     private static final String NOT_CONNECTED = "<not connected>";
  178.     private static final String RECENT_PRODUCT_LIST_VAR = "recentProductList";
  179.     private static final String LVL_UP_REWARD_VAR = "@lvl_up_reward";
  180.     private static final String ACADEMY_GRADUATED_VAR = "@academy_graduated";
  181.     private static final String JAILED_VAR = "jailed";
  182.     private static final String PA_ITEMS_RECIEVED = "pa_items_recieved";
  183.     private static final String FREE_PA_RECIEVED = "free_pa_recieved";
  184.     private static final String ACTIVE_SHOT_ID_VAR = "@active_shot_id";
  185.     private static final String PC_BANG_POINTS_VAR = "pc_bang_poins";
  186.     private static final String PK_KILL_VAR = "@pk_kill";
  187.  
  188.     public final static int OBSERVER_NONE = 0;
  189.     public final static int OBSERVER_STARTING = 1;
  190.     public final static int OBSERVER_STARTED = 3;
  191.     public final static int OBSERVER_LEAVING = 2;
  192.  
  193.     public static final int STORE_PRIVATE_NONE = 0;
  194.     public static final int STORE_PRIVATE_SELL = 1;
  195.     public static final int STORE_PRIVATE_BUY = 3;
  196.     public static final int STORE_PRIVATE_MANUFACTURE = 5;
  197.     public static final int STORE_OBSERVING_GAMES = 7;
  198.     public static final int STORE_PRIVATE_SELL_PACKAGE = 8;
  199.     public static final int STORE_PRIVATE_BUFF = 20;
  200.  
  201.     public static final int[] EXPERTISE_LEVELS = { 0, 20, 40, 52, 61, 76, 80, 84, 85, 95, 99, Integer.MAX_VALUE };
  202.  
  203.     private PlayerTemplate _baseTemplate;
  204.  
  205.     private GameClient _connection;
  206.     private String _login;
  207.  
  208.     private int _karma, _pkKills, _pvpKills;
  209.     private int _face, _hairStyle, _hairColor;
  210.     private int _beautyFace, _beautyHairStyle, _beautyHairColor;
  211.     private int _recomHave, _recomLeftToday, _fame, _raidPoints;
  212.     private int _recomLeft = 0;
  213.     private int _deleteTimer;
  214.     private boolean _isVoting = false;
  215.  
  216.     private long _createTime, _onlineTime, _onlineBeginTime, _leaveClanTime, _deleteClanTime, _NoChannel, _NoChannelBegin;
  217.     private long _uptime;
  218.     /**
  219.      * Time on login in game
  220.      */
  221.     private long _lastAccess;
  222.  
  223.     /**
  224.      * The Color of players name / title (white is 0xFFFFFF)
  225.      */
  226.     private int _nameColor = DEFAULT_NAME_COLOR, _titlecolor = DEFAULT_TITLE_COLOR;
  227.  
  228.     private boolean _overloaded;
  229.  
  230.     boolean sittingTaskLaunched;
  231.  
  232.     /**
  233.      * Time counter when L2Player is sitting
  234.      */
  235.     private int _waitTimeWhenSit;
  236.  
  237.     private boolean _autoLoot = Config.AUTO_LOOT, AutoLootHerbs = Config.AUTO_LOOT_HERBS, _autoLootOnlyAdena = Config.AUTO_LOOT_ONLY_ADENA;
  238.  
  239.     private final PcInventory _inventory = new PcInventory(this);
  240.     private final Warehouse _warehouse = new PcWarehouse(this);
  241.     private final ItemContainer _refund = new PcRefund(this);
  242.     private final PcFreight _freight = new PcFreight(this);
  243.  
  244.     private final BookMarkList _bookmarks = new BookMarkList(this, 0);
  245.  
  246.     public Location bookmarkLocation = null;
  247.  
  248.     private final AntiFlood _antiFlood = new AntiFlood(this);
  249.  
  250.     private final Map<Integer, RecipeTemplate> _recipebook = new TreeMap<Integer, RecipeTemplate>();
  251.     private final Map<Integer, RecipeTemplate> _commonrecipebook = new TreeMap<Integer, RecipeTemplate>();
  252.  
  253.     /**
  254.      * The table containing all Quests began by the L2Player
  255.      */
  256.     private final IntObjectMap<QuestState> _quests = new HashIntObjectMap<QuestState>();
  257.  
  258.     /**
  259.      * The list containing all shortCuts of this L2Player
  260.      */
  261.     private final ShortCutList _shortCuts = new ShortCutList(this);
  262.  
  263.     /**
  264.      * The list containing all macroses of this L2Player
  265.      */
  266.     private final MacroList _macroses = new MacroList(this);
  267.  
  268.     /**
  269.      * The list containing all subclasses of this L2Player
  270.      */
  271.     private final SubClassList _subClassList = new SubClassList(this);
  272.  
  273.     /**
  274.      * The Private Store type of the L2Player (STORE_PRIVATE_NONE=0, STORE_PRIVATE_SELL=1, sellmanage=2, STORE_PRIVATE_BUY=3, buymanage=4, STORE_PRIVATE_MANUFACTURE=5)
  275.      */
  276.     private int _privatestore;
  277.     /**
  278.      * Данные длÑ� магазина рецептов
  279.      */
  280.     private String _manufactureName;
  281.     private List<ManufactureItem> _createList = Collections.emptyList();
  282.     /**
  283.      * Данные длÑ� магазина продажи
  284.      */
  285.     private String _sellStoreName;
  286.     private String _packageSellStoreName;
  287.     private List<TradeItem> _sellList = Collections.emptyList();
  288.     private List<TradeItem> _packageSellList = Collections.emptyList();
  289.     /**
  290.      * Данные длÑ� магазина покупки
  291.      */
  292.     private String _buyStoreName;
  293.     private List<TradeItem> _buyList = Collections.emptyList();
  294.     /**
  295.      * Данные длÑ� обмена
  296.      */
  297.     private List<TradeItem> _tradeList = Collections.emptyList();
  298.  
  299.     private Party _party;
  300.     private Location _lastPartyPosition;
  301.  
  302.     private Clan _clan;
  303.     private PledgeRank _pledgeRank = PledgeRank.VAGABOND;
  304.     private int _pledgeType = Clan.SUBUNIT_NONE, _powerGrade = 0, _lvlJoinedAcademy = 0, _apprentice = 0;
  305.  
  306.     /**
  307.      * GM Stuff
  308.      */
  309.     private int _accessLevel;
  310.     private PlayerAccess _playerAccess = new PlayerAccess();
  311.  
  312.     private boolean _messageRefusal = false, _tradeRefusal = false, _blockAll = false;
  313.  
  314.     /**
  315.      * The L2Summon of the L2Player
  316.      */
  317.     private SummonInstance _summon = null; // objId is index
  318.     private PetInstance _pet = null;
  319.     private SymbolInstance _symbol = null;
  320.  
  321.     private boolean _riding;
  322.    
  323.     private int _botRating;
  324.  
  325.     private List<DecoyInstance> _decoys = new CopyOnWriteArrayList<DecoyInstance>();
  326.  
  327.     private IntObjectMap<Cubic> _cubics = null;
  328.     private int _agathionId = 0;
  329.  
  330.     private Request _request;
  331.  
  332.     private ItemInstance _arrowItem;
  333.  
  334.     /**
  335.      * The fists L2Weapon of the L2Player (used when no weapon is equipped)
  336.      */
  337.     private WeaponTemplate _fistsWeaponItem;
  338.  
  339.     private Map<Integer, String> _chars = new HashMap<Integer, String>(8);
  340.  
  341.     private ItemInstance _enchantScroll = null;
  342.  
  343.     private WarehouseType _usingWHType;
  344.  
  345.     private boolean _isOnline = false;
  346.  
  347.     private final AtomicBoolean _isLogout = new AtomicBoolean();
  348.  
  349.     /**
  350.      * The L2NpcInstance corresponding to the last Folk which one the player talked.
  351.      */
  352.     private HardReference<NpcInstance> _lastNpc = HardReferences.emptyRef();
  353.     /**
  354.      * тут храним мультиÑ�елл Ñ� которым работаем
  355.      */
  356.     private MultiSellListContainer _multisell = null;
  357.  
  358.     private IntObjectMap<SoulShotType> _activeAutoShots = new CHashIntObjectMap<SoulShotType>();
  359.  
  360.     private ObservePoint _observePoint;
  361.     private AtomicInteger _observerMode = new AtomicInteger(0);
  362.  
  363.     public int _telemode = 0;
  364.  
  365.     public boolean entering = true;
  366.  
  367.     /**
  368.      * Эта точка проверÑ�етÑ�Ñ� при нештатном выходе чара, и еÑ�ли не равна null чар возвращаетÑ�Ñ� в нее
  369.      * ИÑ�пользуетÑ�Ñ� например длÑ� возвращениÑ� при падении Ñ� виверны
  370.      * Поле heading иÑ�пользуетÑ�Ñ� длÑ� хранениÑ� денег возвращаемых при Ñ�бое
  371.      */
  372.     private Location _stablePoint = null;
  373.  
  374.     /**
  375.      * new loto ticket *
  376.      */
  377.     public int _loto[] = new int[5];
  378.     /**
  379.      * new race ticket *
  380.      */
  381.     public int _race[] = new int[2];
  382.  
  383.     private final BlockList _blockList = new BlockList(this);
  384.     private final FriendList _friendList = new FriendList(this);
  385.     private final PremiumItemList _premiumItemList = new PremiumItemList(this);
  386.     private final ProductHistoryList _productHistoryList = new ProductHistoryList(this);
  387.     private final HennaList _hennaList = new HennaList(this);
  388.  
  389.     private final AttendanceRewards _attendanceRewards = new AttendanceRewards(this);
  390.     private final DailyMissionList _dailiyMissionList = new DailyMissionList(this);
  391.  
  392.     private boolean _hero = false;
  393.  
  394.     private PremiumAccountTemplate _premiumAccount = PremiumAccountHolder.getInstance().getPremiumAccount(0);
  395.     private Future<?> _premiumAccountExpirationTask;
  396.  
  397.     private boolean _isSitting;
  398.  
  399.     private ChairInstance _chairObject;
  400.  
  401.     private boolean _inOlympiadMode;
  402.     private OlympiadGame _olympiadGame;
  403.     private ObservableArena _observableArena;
  404.  
  405.     private int _olympiadSide = -1;
  406.  
  407.     /**
  408.      * ally with ketra or varka related wars
  409.      */
  410.     private int _varka = 0;
  411.     private int _ketra = 0;
  412.     private int _ram = 0;
  413.  
  414.     private byte[] _keyBindings = ArrayUtils.EMPTY_BYTE_ARRAY;
  415.  
  416.     private final Fishing _fishing = new Fishing(this);
  417.  
  418.     private Future<?> _taskWater;
  419.     private Future<?> _autoSaveTask;
  420.     private Future<?> _kickTask;
  421.  
  422.     private Future<?> _pcCafePointsTask;
  423.     private Future<?> _unjailTask;
  424.     private Future<?> _trainingCampTask;
  425.  
  426.     private final Lock _storeLock = new ReentrantLock();
  427.  
  428.     private int _zoneMask;
  429.  
  430.     private boolean _offline = false;
  431.     private boolean _awaying = false;
  432.  
  433.     private boolean _registeredInEvent = false;
  434.    
  435.     private int _pcBangPoints;
  436.  
  437.     private int _expandInventory = 0;
  438.     private int _expandWarehouse = 0;
  439.     private int _battlefieldChatId;
  440.     private int _lectureMark;
  441.  
  442.     private AtomicState _gmInvisible = new AtomicState();
  443.     private AtomicState _gmUndying = new AtomicState();
  444.  
  445.     private IntObjectMap<String> _postFriends = Containers.emptyIntObjectMap();
  446.  
  447.     private List<String> _blockedActions = new ArrayList<String>();
  448.  
  449.     private BypassStorage _bypassStorage = new BypassStorage();
  450.  
  451.     private boolean _notShowBuffAnim = false;
  452.     private boolean _notShowTraders = false;
  453.     private boolean _canSeeAllShouts = false;
  454.     private boolean _debug = false;
  455.  
  456.     private long _dropDisabled;
  457.     private long _lastItemAuctionInfoRequest;
  458.  
  459.     private IntObjectPair<OnAnswerListener> _askDialog = null;
  460.  
  461.     private boolean _matchingRoomWindowOpened = false;
  462.     private MatchingRoom _matchingRoom;
  463.     private PetitionMainGroup _petitionGroup;
  464.     private final Map<Integer, Long> _instancesReuses = new ConcurrentHashMap<Integer, Long>();
  465.  
  466.     private Language _language = Config.DEFAULT_LANG;
  467.  
  468.     private int _npcDialogEndTime = 0;
  469.  
  470.     private Mount _mount = null;
  471.  
  472.     private final Map<String, CharacterVariable> _variables = new ConcurrentHashMap<String, CharacterVariable>();
  473.  
  474.     private List<RestoredSummon> _restoredSummons = null;
  475.  
  476.     private boolean _autoSearchParty;
  477.     private Future<?> _substituteTask;
  478.  
  479.     private TransformTemplate _transform = null;
  480.  
  481.     private final IntObjectMap<SkillEntry> _transformSkills = new CHashIntObjectMap<SkillEntry>();
  482.  
  483.     private long _lastMultisellBuyTime = 0L;
  484.     private long _lastEnchantItemTime = 0L;
  485.     private long _lastAttributeItemTime = 0L;
  486.  
  487.     private Future<?> _enableRelationTask;
  488.    
  489.     private boolean _isInReplaceTeleport = false;
  490.  
  491.     private int _armorSetEnchant = 0;
  492.  
  493.     private int _usedWorldChatPoints = 0;
  494.  
  495.     private boolean _hideHeadAccessories = false;
  496.  
  497.     private ItemInstance _synthesisItem1 = null;
  498.     private ItemInstance _synthesisItem2 = null;
  499.  
  500.     private List<TrapInstance> _traps = Collections.emptyList();
  501.     private boolean _isInJail = false;
  502.     private final IntObjectMap<OptionDataTemplate> _options = new CTreeIntObjectMap<OptionDataTemplate>();
  503.     private long _receivedExp = 0L;
  504.     private Reflection _activeReflection = null;
  505.     private int _questZoneId = -1;
  506.     private ClassId _selectedMultiClassId = null;
  507.  
  508.     /**
  509.      * КонÑ�труктор длÑ� L2Player. Ð�апрÑ�мую не вызываетÑ�Ñ�, длÑ� Ñ�озданиÑ� игрока иÑ�пользуетÑ�Ñ� PlayerManager.create
  510.      */
  511.     public Player(final int objectId, final PlayerTemplate template, final String accountName)
  512.     {
  513.         super(objectId, template);
  514.  
  515.         _baseTemplate = template;
  516.         _login = accountName;
  517.     }
  518.  
  519.     private Player(final FakePlayerAITemplate fakeAiTemplate, final int objectId, final PlayerTemplate template)
  520.     {
  521.         this(objectId, template, null);
  522.         _ai = new FakeAI(this, fakeAiTemplate);
  523.     }
  524.  
  525.     /**
  526.      * Constructor<?> of L2Player (use L2Character constructor).<BR><BR>
  527.      * <p/>
  528.      * <B><U> Actions</U> :</B><BR><BR>
  529.      * <li>Call the L2Character constructor to create an empty _skills slot and copy basic Calculator set to this L2Player </li>
  530.      * <li>Create a L2Radar object</li>
  531.      * <li>Retrieve from the database all items of this L2Player and add them to _inventory </li>
  532.      * <p/>
  533.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T SET the account name of the L2Player</B></FONT><BR><BR>
  534.      *  @param objectId Identifier of the object to initialized
  535.      * @param template The L2PlayerTemplate to apply to the L2Player
  536.      */
  537.     private Player(final int objectId, final PlayerTemplate template)
  538.     {
  539.         this(objectId, template, null);
  540.  
  541.         if(GameObjectsStorage.getPlayers().size() >= GameServer.getInstance().getOnlineLimit())
  542.         {
  543.             kick();
  544.             return;
  545.         }
  546.  
  547.         _baseTemplate = template;
  548.  
  549.         _ai = new PlayerAI(this);
  550.  
  551.         if(!Config.EVERYBODY_HAS_ADMIN_RIGHTS)
  552.             setPlayerAccess(Config.gmlist.get(objectId));
  553.         else
  554.             setPlayerAccess(Config.gmlist.get(0));
  555.     }
  556.  
  557.     @SuppressWarnings("unchecked")
  558.     @Override
  559.     public HardReference<Player> getRef()
  560.     {
  561.         return (HardReference<Player>) super.getRef();
  562.     }
  563.  
  564.     public String getAccountName()
  565.     {
  566.         if(_connection == null)
  567.             return _login;
  568.         return _connection.getLogin();
  569.     }
  570.  
  571.     public String getIP()
  572.     {
  573.         if(_connection == null)
  574.             return NOT_CONNECTED;
  575.         return _connection.getIpAddr();
  576.     }
  577.  
  578.     public String getLogin()
  579.     {
  580.         return _login;
  581.     }
  582.  
  583.     public void setLogin(String val)
  584.     {
  585.         _login = val;
  586.     }
  587.  
  588.     /**
  589.      * Возвращает Ñ�пиÑ�ок перÑ�онажей на аккаунте, за иÑ�ключением текущего
  590.      *
  591.      * @return СпиÑ�ок перÑ�онажей
  592.      */
  593.     public Map<Integer, String> getAccountChars()
  594.     {
  595.         return _chars;
  596.     }
  597.  
  598.     @Override
  599.     public final PlayerTemplate getTemplate()
  600.     {
  601.         return (PlayerTemplate) super.getTemplate();
  602.     }
  603.  
  604.     @Override
  605.     public final void setTemplate(CreatureTemplate template)
  606.     {
  607.         if(isBaseClassActive())
  608.             _baseTemplate = (PlayerTemplate) template;
  609.  
  610.         super.setTemplate(template);
  611.     }
  612.  
  613.     public final PlayerTemplate getBaseTemplate()
  614.     {
  615.         return _baseTemplate;
  616.     }
  617.  
  618.     @Override
  619.     public final boolean isTransformed()
  620.     {
  621.         return _transform != null;
  622.     }
  623.  
  624.     @Override
  625.     public final TransformTemplate getTransform()
  626.     {
  627.         return _transform;
  628.     }
  629.  
  630.     @Override
  631.     public final void setTransform(int id)
  632.     {
  633.         TransformTemplate template = id > 0 ? TransformTemplateHolder.getInstance().getTemplate(getSex(), id) : null;
  634.         setTransform(template);
  635.     }
  636.  
  637.     @Override
  638.     public final void setTransform(TransformTemplate transform)
  639.     {
  640.         if(transform == _transform || transform != null && _transform != null)
  641.             return;
  642.  
  643.         boolean isFlying = false;
  644.         final boolean isVisible = isVisible();
  645.  
  646.         synchronized (_transform)
  647.         {
  648.             // ДлÑ� каждой транÑ�формации Ñ�вой набор Ñ�килов
  649.             if(transform == null) // ОбычнаÑ� форма
  650.             {
  651.                 isFlying = _transform.getType() == TransformType.FLYING;
  652.  
  653.                 if(isFlying)
  654.                 {
  655.                     decayMe();
  656.                     setFlying(false);
  657.                     setLoc(getLoc().correctGeoZ());
  658.                 }
  659.  
  660.                 if(!_transformSkills.isEmpty())
  661.                 {
  662.                     // УдалÑ�ем Ñ�килы транÑ�формации
  663.                     for(SkillEntry skillEntry : _transformSkills.values())
  664.                     {
  665.                         if(!SkillAcquireHolder.getInstance().isSkillPossible(this, skillEntry.getTemplate()))
  666.                             super.removeSkill(skillEntry);
  667.                     }
  668.                     _transformSkills.clear();
  669.                 }
  670.  
  671.                 if(_transform.getItemCheckType() != LockType.NONE)
  672.                     getInventory().unlock();
  673.  
  674.                 _transform = transform;
  675.  
  676.                 checkActiveToggleEffects();
  677.  
  678.                 // ОÑ�танавливаем текущий Ñ�ффект транÑ�формации
  679.                 getAbnormalList().stop(AbnormalType.transform);
  680.             }
  681.             else
  682.             {
  683.                 isFlying = transform.getType() == TransformType.FLYING;
  684.  
  685.                 if(isFlying)
  686.                 {
  687.                     for(Servitor servitor : getServitors())
  688.                         servitor.unSummon(false);
  689.  
  690.                     decayMe();
  691.                     setFlying(true);
  692.                     setLoc(getLoc().changeZ(transform.getSpawnHeight())); // Ð�емного поднимаем чара над землей
  693.                 }
  694.  
  695.                 // ДобавлÑ�ем Ñ�киллы транÑ�формации
  696.                 for(SkillLearn sl : transform.getSkills())
  697.                 {
  698.                     SkillEntry skillEntry = SkillHolder.getInstance().getSkillEntry(sl.getId(), sl.getLevel());
  699.                     if(skillEntry == null)
  700.                         continue;
  701.  
  702.                     _transformSkills.put(skillEntry.getId(), skillEntry);
  703.                 }
  704.  
  705.                 // ДобавлÑ�ем Ñ�киллы транÑ�формации завиÑ�Ñ�щие от уровнÑ� перÑ�онажа
  706.                 for(SkillLearn sl : transform.getAddtionalSkills())
  707.                 {
  708.                     if(sl.getMinLevel() > getLevel())
  709.                         continue;
  710.  
  711.                     SkillEntry skillEntry = _transformSkills.get(sl.getId());
  712.                     if(skillEntry != null && skillEntry.getLevel() >= sl.getLevel())
  713.                         continue;
  714.  
  715.                     skillEntry = SkillHolder.getInstance().getSkillEntry(sl.getId(), sl.getLevel());
  716.                     if(skillEntry == null)
  717.                         continue;
  718.  
  719.                     _transformSkills.put(skillEntry.getId(), skillEntry);
  720.                 }
  721.  
  722.                 for(SkillEntry skillEntry : _transformSkills.values())
  723.                     addSkill(skillEntry, false);
  724.  
  725.                 if(transform.getItemCheckType() != LockType.NONE)
  726.                 {
  727.                     getInventory().unlock();
  728.                     getInventory().lockItems(transform.getItemCheckType(), transform.getItemCheckIDs());
  729.                 }
  730.  
  731.                 checkActiveToggleEffects();
  732.  
  733.                 _transform = transform;
  734.             }
  735.         }
  736.  
  737.         sendPacket(new ExBasicActionList(this));
  738.         sendSkillList();
  739.         sendPacket(new ShortCutInitPacket(this));
  740.  
  741.         sendActiveAutoShots();
  742.  
  743.         if(isFlying && isVisible)
  744.             spawnMe();
  745.  
  746.         sendChanges();
  747.     }
  748.  
  749.     public void changeSex()
  750.     {
  751.         PlayerTemplate template = PlayerTemplateHolder.getInstance().getPlayerTemplate(getRace(), getClassId(), getSex().revert());
  752.         if(template == null)
  753.             return;
  754.  
  755.         setTemplate(template);
  756.         if(isTransformed())
  757.         {
  758.             int transformId = getTransform().getId();
  759.             setTransform(null);
  760.             setTransform(transformId);
  761.         }
  762.     }
  763.  
  764.     @Override
  765.     public PlayerAI getAI()
  766.     {
  767.         return (PlayerAI) _ai;
  768.     }
  769.  
  770.     @Override
  771.     public void doCast(final SkillEntry skillEntry, final Creature target, boolean forceUse)
  772.     {
  773.         if(skillEntry == null)
  774.             return;
  775.  
  776.         super.doCast(skillEntry, target, forceUse);
  777.     }
  778.  
  779.     @Override
  780.     public void sendReuseMessage(Skill skill)
  781.     {
  782.         if(isCastingNow())
  783.             return;
  784.  
  785.         TimeStamp sts = getSkillReuse(skill);
  786.         if(sts == null || !sts.hasNotPassed())
  787.             return;
  788.         long timeleft = sts.getReuseCurrent();
  789.         if(!Config.ALT_SHOW_REUSE_MSG && timeleft < 10000 || timeleft < 500)
  790.             return;
  791.         long hours = timeleft / 3600000;
  792.         long minutes = (timeleft - hours * 3600000) / 60000;
  793.         long seconds = (long) Math.ceil((timeleft - hours * 3600000 - minutes * 60000) / 1000.);
  794.         if(hours > 0)
  795.             sendPacket(new SystemMessage(SystemMessage.THERE_ARE_S2_HOURS_S3_MINUTES_AND_S4_SECONDS_REMAINING_IN_S1S_REUSE_TIME).addSkillName(skill.getId(), skill.getDisplayLevel()).addNumber(hours).addNumber(minutes).addNumber(seconds));
  796.         else if(minutes > 0)
  797.             sendPacket(new SystemMessage(SystemMessage.THERE_ARE_S2_MINUTES_S3_SECONDS_REMAINING_IN_S1S_REUSE_TIME).addSkillName(skill.getId(), skill.getDisplayLevel()).addNumber(minutes).addNumber(seconds));
  798.         else
  799.             sendPacket(new SystemMessage(SystemMessage.THERE_ARE_S2_SECONDS_REMAINING_IN_S1S_REUSE_TIME).addSkillName(skill.getId(), skill.getDisplayLevel()).addNumber(seconds));
  800.     }
  801.  
  802.     @Override
  803.     public final int getLevel()
  804.     {
  805.         return getActiveSubClass() == null ? 1 : getActiveSubClass().getLevel();
  806.     }
  807.  
  808.     @Override
  809.     public final Sex getSex()
  810.     {
  811.         return getTemplate().getSex();
  812.     }
  813.  
  814.     public int getFace()
  815.     {
  816.         return _face;
  817.     }
  818.  
  819.     public void setFace(int face)
  820.     {
  821.         _face = face;
  822.     }
  823.  
  824.     public int getBeautyFace()
  825.     {
  826.         return _beautyFace;
  827.     }
  828.  
  829.     public void setBeautyFace(int face)
  830.     {
  831.         _beautyFace = face;
  832.     }
  833.  
  834.     public int getHairColor()
  835.     {
  836.         return _hairColor;
  837.     }
  838.  
  839.     public void setHairColor(int hairColor)
  840.     {
  841.         _hairColor = hairColor;
  842.     }
  843.  
  844.     public int getBeautyHairColor()
  845.     {
  846.         return _beautyHairColor;
  847.     }
  848.  
  849.     public void setBeautyHairColor(int hairColor)
  850.     {
  851.         _beautyHairColor = hairColor;
  852.     }
  853.  
  854.     public int getHairStyle()
  855.     {
  856.         return _hairStyle;
  857.     }
  858.  
  859.     public void setHairStyle(int hairStyle)
  860.     {
  861.         _hairStyle = hairStyle;
  862.     }
  863.  
  864.     public int getBeautyHairStyle()
  865.     {
  866.         return _beautyHairStyle;
  867.     }
  868.  
  869.     public void setBeautyHairStyle(int hairStyle)
  870.     {
  871.         _beautyHairStyle = hairStyle;
  872.     }
  873.  
  874.     public void offline()
  875.     {
  876.         offline(Config.SERVICES_OFFLINE_TRADE_SECONDS_TO_KICK);
  877.     }
  878.  
  879.     public void offline(int delay)
  880.     {
  881.         if(_connection != null)
  882.         {
  883.             _connection.setActiveChar(null);
  884.             _connection.close(ServerCloseSocketPacket.STATIC);
  885.             setNetConnection(null);
  886.         }
  887.  
  888.         startAbnormalEffect(Config.SERVICES_OFFLINE_TRADE_ABNORMAL_EFFECT);
  889.         setOfflineMode(true);
  890.  
  891.         if(isInBuffStore())
  892.             OfflineBufferManager.getInstance().storeBufferData(this);
  893.         else
  894.             storePrivateStore();
  895.  
  896.         if(delay > 0)
  897.         {
  898.             setVar(isInBuffStore() ? "offlinebuff" : "offline", delay + System.currentTimeMillis() / 1000L);
  899.             startKickTask(delay * 1000L);
  900.         }
  901.         else
  902.             setVar(isInBuffStore() ? "offlinebuff" : "offline", Integer.MAX_VALUE);
  903.  
  904.         Party party = getParty();
  905.         if(party != null)
  906.             leaveParty();
  907.  
  908.         if(isAutoSearchParty())
  909.             PartySubstituteManager.getInstance().removeWaitingPlayer(this);
  910.  
  911.  
  912.         for(Servitor servitor : getServitors())
  913.             servitor.unSummon(false);
  914.  
  915.         Olympiad.logoutPlayer(this);
  916.  
  917.         if(isFishing())
  918.             getFishing().stop();
  919.  
  920.         MatchingRoomManager.getInstance().removeFromWaitingList(this);
  921.  
  922.         broadcastCharInfo();
  923.         stopWaterTask();
  924.         stopPremiumAccountTask();
  925.         stopHourlyTask();
  926.         stopPcBangPointsTask();
  927.         stopTrainingCampTask();
  928.         stopAutoSaveTask();
  929.         stopQuestTimers();
  930.         stopEnableUserRelationTask();
  931.         broadcastUserInfo(true);
  932.  
  933.         try
  934.         {
  935.             getInventory().store();
  936.         }
  937.         catch(Throwable t)
  938.         {
  939.             _log.error("", t);
  940.         }
  941.  
  942.         try
  943.         {
  944.             store(false);
  945.         }
  946.         catch(Throwable t)
  947.         {
  948.             _log.error("", t);
  949.         }
  950.     }
  951.  
  952.     /**
  953.      * Соединение закрываетÑ�Ñ�, клиент закрываетÑ�Ñ�, перÑ�онаж Ñ�охранÑ�етÑ�Ñ� и удалÑ�етÑ�Ñ� из игры
  954.      */
  955.     public void kick()
  956.     {
  957.         prepareToLogout1();
  958.         if(_connection != null)
  959.         {
  960.             _connection.close(LogOutOkPacket.STATIC);
  961.             setNetConnection(null);
  962.         }
  963.         prepareToLogout2();
  964.         deleteMe();
  965.     }
  966.  
  967.     /**
  968.      * Соединение не закрываетÑ�Ñ�, клиент не закрываетÑ�Ñ�, перÑ�онаж Ñ�охранÑ�етÑ�Ñ� и удалÑ�етÑ�Ñ� из игры
  969.      */
  970.     public void restart()
  971.     {
  972.         prepareToLogout1();
  973.         if(_connection != null)
  974.         {
  975.             _connection.setActiveChar(null);
  976.             setNetConnection(null);
  977.         }
  978.         prepareToLogout2();
  979.         deleteMe();
  980.     }
  981.  
  982.     /**
  983.      * Соединение закрываетÑ�Ñ�, клиент не закрываетÑ�Ñ�, перÑ�онаж Ñ�охранÑ�етÑ�Ñ� и удалÑ�етÑ�Ñ� из игры
  984.      */
  985.     public void logout()
  986.     {
  987.         prepareToLogout1();
  988.         if(_connection != null)
  989.         {
  990.             _connection.close(ServerCloseSocketPacket.STATIC);
  991.             setNetConnection(null);
  992.         }
  993.         prepareToLogout2();
  994.         deleteMe();
  995.     }
  996.  
  997.     private void prepareToLogout1()
  998.     {
  999.         for(Servitor servitor : getServitors())
  1000.             sendPacket(new PetDeletePacket(servitor.getObjectId(), servitor.getServitorType()));
  1001.  
  1002.         if(isProcessingRequest())
  1003.         {
  1004.             Request request = getRequest();
  1005.             if(isInTrade())
  1006.             {
  1007.                 Player parthner = request.getOtherPlayer(this);
  1008.                 parthner.sendPacket(SystemMsg.THAT_PLAYER_IS_NOT_ONLINE);
  1009.                 parthner.sendPacket(TradeDonePacket.FAIL);
  1010.             }
  1011.             request.cancel();
  1012.         }
  1013.         World.removeObjectsFromPlayer(this);
  1014.     }
  1015.  
  1016.     private void prepareToLogout2()
  1017.     {
  1018.         if(_isLogout.getAndSet(true))
  1019.             return;
  1020.  
  1021.         for(ListenerHook hook : getListenerHooks(ListenerHookType.PLAYER_QUIT_GAME))
  1022.             hook.onPlayerQuitGame(this);
  1023.  
  1024.         for(ListenerHook hook : ListenerHook.getGlobalListenerHooks(ListenerHookType.PLAYER_QUIT_GAME))
  1025.             hook.onPlayerQuitGame(this);
  1026.  
  1027.         FlagItemAttachment attachment = getActiveWeaponFlagAttachment();
  1028.         if(attachment != null)
  1029.             attachment.onLogout(this);
  1030.  
  1031.         setNetConnection(null);
  1032.         setIsOnline(false);
  1033.  
  1034.         getListeners().onExit();
  1035.  
  1036.         if(isFlying() && !checkLandingState())
  1037.             _stablePoint = TeleportUtils.getRestartPoint(this, RestartType.TO_VILLAGE).getLoc();
  1038.  
  1039.         if(isCastingNow())
  1040.             abortCast(true, true);
  1041.  
  1042.         Party party = getParty();
  1043.         if(party != null)
  1044.             leaveParty();
  1045.  
  1046.         if(_observableArena != null)
  1047.             _observableArena.removeObserver(_observePoint);
  1048.  
  1049.         Olympiad.logoutPlayer(this);
  1050.  
  1051.         if(isFishing())
  1052.             getFishing().stop();
  1053.  
  1054.         if(_stablePoint != null)
  1055.             teleToLocation(_stablePoint);
  1056.  
  1057.         for(Servitor servitor : getServitors())
  1058.             servitor.unSummon(true);
  1059.  
  1060.         if(isMounted())
  1061.             _mount.onLogout();
  1062.  
  1063.         _friendList.notifyFriends(false);
  1064.  
  1065.         if(getClan() != null)
  1066.             getClan().loginClanCond(this, false);
  1067.  
  1068.         if(isProcessingRequest())
  1069.             getRequest().cancel();
  1070.  
  1071.         stopAllTimers();
  1072.  
  1073.         if(isInBoat())
  1074.             getBoat().removePlayer(this);
  1075.  
  1076.         SubUnit unit = getSubUnit();
  1077.         UnitMember member = unit == null ? null : unit.getUnitMember(getObjectId());
  1078.         if(member != null)
  1079.         {
  1080.             int sponsor = member.getSponsor();
  1081.             int apprentice = getApprentice();
  1082.             PledgeShowMemberListUpdatePacket memberUpdate = new PledgeShowMemberListUpdatePacket(this);
  1083.             for(Player clanMember : _clan.getOnlineMembers(getObjectId()))
  1084.             {
  1085.                 clanMember.sendPacket(memberUpdate);
  1086.                 if(clanMember.getObjectId() == sponsor)
  1087.                     clanMember.sendPacket(new SystemMessage(SystemMessage.S1_YOUR_CLAN_ACADEMYS_APPRENTICE_HAS_LOGGED_OUT).addString(_name));
  1088.                 else if(clanMember.getObjectId() == apprentice)
  1089.                     clanMember.sendPacket(new SystemMessage(SystemMessage.S1_YOUR_CLAN_ACADEMYS_SPONSOR_HAS_LOGGED_OUT).addString(_name));
  1090.             }
  1091.             member.setPlayerInstance(this, true);
  1092.         }
  1093.  
  1094.         MatchingRoom room = getMatchingRoom();
  1095.         if(room != null)
  1096.         {
  1097.             if(room.getLeader() == this)
  1098.                 room.disband();
  1099.             else
  1100.                 room.removeMember(this, false);
  1101.         }
  1102.         setMatchingRoom(null);
  1103.  
  1104.         MatchingRoomManager.getInstance().removeFromWaitingList(this);
  1105.  
  1106.         destroyAllTraps();
  1107.  
  1108.         if(!_decoys.isEmpty())
  1109.         {
  1110.             for(DecoyInstance decoy : getDecoys())
  1111.             {
  1112.                 decoy.unSummon();
  1113.                 removeDecoy(decoy);
  1114.             }
  1115.         }
  1116.  
  1117.         stopPvPFlag();
  1118.  
  1119.         Reflection ref = getReflection();
  1120.  
  1121.         if(!ref.isMain())
  1122.         {
  1123.             if(ref.getReturnLoc() != null)
  1124.                 _stablePoint = ref.getReturnLoc();
  1125.  
  1126.             ref.removeObject(this);
  1127.         }
  1128.  
  1129.         try
  1130.         {
  1131.             getInventory().store();
  1132.             getRefund().clear();
  1133.         }
  1134.         catch(Throwable t)
  1135.         {
  1136.             _log.error("", t);
  1137.         }
  1138.  
  1139.         try
  1140.         {
  1141.             store(false);
  1142.         }
  1143.         catch(Throwable t)
  1144.         {
  1145.             _log.error("", t);
  1146.         }
  1147.     }
  1148.  
  1149.     /**
  1150.      * @return a table containing all L2RecipeList of the L2Player.<BR><BR>
  1151.      */
  1152.     public Collection<RecipeTemplate> getDwarvenRecipeBook()
  1153.     {
  1154.         return _recipebook.values();
  1155.     }
  1156.  
  1157.     public Collection<RecipeTemplate> getCommonRecipeBook()
  1158.     {
  1159.         return _commonrecipebook.values();
  1160.     }
  1161.  
  1162.     public int recipesCount()
  1163.     {
  1164.         return _commonrecipebook.size() + _recipebook.size();
  1165.     }
  1166.  
  1167.     public boolean hasRecipe(final RecipeTemplate id)
  1168.     {
  1169.         return _recipebook.containsValue(id) || _commonrecipebook.containsValue(id);
  1170.     }
  1171.  
  1172.     public boolean findRecipe(final int id)
  1173.     {
  1174.         return _recipebook.containsKey(id) || _commonrecipebook.containsKey(id);
  1175.     }
  1176.  
  1177.     /**
  1178.      * Add a new L2RecipList to the table _recipebook containing all L2RecipeList of the L2Player
  1179.      */
  1180.     public void registerRecipe(final RecipeTemplate recipe, boolean saveDB)
  1181.     {
  1182.         if(recipe == null)
  1183.             return;
  1184.  
  1185.         if(recipe.isCommon())
  1186.             _commonrecipebook.put(recipe.getId(), recipe);
  1187.         else
  1188.             _recipebook.put(recipe.getId(), recipe);
  1189.  
  1190.         if(saveDB)
  1191.             mysql.set("REPLACE INTO character_recipebook (char_id, id) VALUES(?,?)", getObjectId(), recipe.getId());
  1192.     }
  1193.  
  1194.     /**
  1195.      * Remove a L2RecipList from the table _recipebook containing all L2RecipeList of the L2Player
  1196.      */
  1197.     public void unregisterRecipe(final int RecipeID)
  1198.     {
  1199.         if(_recipebook.containsKey(RecipeID))
  1200.         {
  1201.             mysql.set("DELETE FROM `character_recipebook` WHERE `char_id`=? AND `id`=? LIMIT 1", getObjectId(), RecipeID);
  1202.             _recipebook.remove(RecipeID);
  1203.         }
  1204.         else if(_commonrecipebook.containsKey(RecipeID))
  1205.         {
  1206.             mysql.set("DELETE FROM `character_recipebook` WHERE `char_id`=? AND `id`=? LIMIT 1", getObjectId(), RecipeID);
  1207.             _commonrecipebook.remove(RecipeID);
  1208.         }
  1209.         else
  1210.             _log.warn("Attempted to remove unknown RecipeList" + RecipeID);
  1211.     }
  1212.  
  1213.     public QuestState getQuestState(int id)
  1214.     {
  1215.         questRead.lock();
  1216.         try
  1217.         {
  1218.             return _quests.get(id);
  1219.         }
  1220.         finally
  1221.         {
  1222.             questRead.unlock();
  1223.         }
  1224.     }
  1225.  
  1226.     public QuestState getQuestState(Quest quest)
  1227.     {
  1228.         return getQuestState(quest.getId());
  1229.     }
  1230.  
  1231.     public boolean isQuestCompleted(int id)
  1232.     {
  1233.         QuestState qs = getQuestState(id);
  1234.         return qs != null && qs.isCompleted();
  1235.     }
  1236.  
  1237.     public boolean isQuestCompleted(Quest quest)
  1238.     {
  1239.         return isQuestCompleted(quest.getId());
  1240.     }
  1241.  
  1242.     public void setQuestState(QuestState qs)
  1243.     {
  1244.         questWrite.lock();
  1245.         try
  1246.         {
  1247.             _quests.put(qs.getQuest().getId(), qs);
  1248.         }
  1249.         finally
  1250.         {
  1251.             questWrite.unlock();
  1252.         }
  1253.     }
  1254.  
  1255.     public void removeQuestState(int id)
  1256.     {
  1257.         questWrite.lock();
  1258.         try
  1259.         {
  1260.             _quests.remove(id);
  1261.         }
  1262.         finally
  1263.         {
  1264.             questWrite.unlock();
  1265.         }
  1266.     }
  1267.  
  1268.     public void removeQuestState(Quest quest)
  1269.     {
  1270.         removeQuestState(quest.getId());
  1271.     }
  1272.  
  1273.     public Quest[] getAllActiveQuests()
  1274.     {
  1275.         List<Quest> quests = new ArrayList<Quest>(_quests.size());
  1276.         questRead.lock();
  1277.         try
  1278.         {
  1279.             for(final QuestState qs : _quests.values())
  1280.                 if(qs.isStarted())
  1281.                     quests.add(qs.getQuest());
  1282.         }
  1283.         finally
  1284.         {
  1285.             questRead.unlock();
  1286.         }
  1287.         return quests.toArray(new Quest[quests.size()]);
  1288.     }
  1289.  
  1290.     public QuestState[] getAllQuestsStates()
  1291.     {
  1292.         questRead.lock();
  1293.         try
  1294.         {
  1295.             return _quests.values().toArray(new QuestState[_quests.size()]);
  1296.         }
  1297.         finally
  1298.         {
  1299.             questRead.unlock();
  1300.         }
  1301.     }
  1302.  
  1303.     public List<QuestState> getQuestsForEvent(NpcInstance npc, QuestEventType event)
  1304.     {
  1305.         List<QuestState> states = new ArrayList<QuestState>();
  1306.         Set<Quest> quests = npc.getTemplate().getEventQuests(event);
  1307.         if(quests != null)
  1308.         {
  1309.             QuestState qs;
  1310.             for(Quest quest : quests)
  1311.             {
  1312.                 qs = getQuestState(quest);
  1313.                 if(qs != null && !qs.isCompleted())
  1314.                     states.add(getQuestState(quest));
  1315.             }
  1316.         }
  1317.         return states;
  1318.     }
  1319.  
  1320.     public void processQuestEvent(int questId, String event, NpcInstance npc)
  1321.     {
  1322.         if(event == null)
  1323.             event = "";
  1324.         QuestState qs = getQuestState(questId);
  1325.         if(qs == null)
  1326.         {
  1327.             Quest q = QuestHolder.getInstance().getQuest(questId);
  1328.             if(q == null)
  1329.             {
  1330.                 _log.warn("Quest ID[" + questId + "] not found!");
  1331.                 return;
  1332.             }
  1333.             qs = q.newQuestState(this);
  1334.         }
  1335.         if(qs == null || qs.isCompleted())
  1336.             return;
  1337.         qs.getQuest().notifyEvent(event, qs, npc);
  1338.         sendPacket(new QuestListPacket(this));
  1339.     }
  1340.  
  1341.     public boolean isInventoryFull()
  1342.     {
  1343.         if(getWeightPenalty() >= 3 || getInventoryLimit() * 0.8 < getInventory().getSize())
  1344.             return true;
  1345.  
  1346.         return false;
  1347.     }
  1348.  
  1349.     /**
  1350.      * Проверка на переполнение инвентарÑ� и перебор в веÑ�е длÑ� квеÑ�тов и Ñ�вентов
  1351.      *
  1352.      * @return true еÑ�ли ве проверки прошли уÑ�пешно
  1353.      */
  1354.     public boolean isQuestContinuationPossible(boolean msg)
  1355.     {
  1356.         if(isInventoryFull() || Config.QUEST_INVENTORY_MAXIMUM * 0.8 < getInventory().getQuestSize())
  1357.         {
  1358.             if(msg)
  1359.                 sendPacket(SystemMsg.PROGRESS_IN_A_QUEST_IS_POSSIBLE_ONLY_WHEN_YOUR_INVENTORYS_WEIGHT_AND_SLOT_COUNT_ARE_LESS_THAN_80_PERCENT_OF_CAPACITY);
  1360.             return false;
  1361.         }
  1362.         return true;
  1363.     }
  1364.  
  1365.     /**
  1366.      * ОÑ�танавливаем и запоминаем вÑ�е квеÑ�товые таймеры
  1367.      */
  1368.     public void stopQuestTimers()
  1369.     {
  1370.         for(QuestState qs : getAllQuestsStates())
  1371.             if(qs.isStarted())
  1372.                 qs.pauseQuestTimers();
  1373.             else
  1374.                 qs.stopQuestTimers();
  1375.     }
  1376.  
  1377.     /**
  1378.      * ВоÑ�Ñ�танавливаем вÑ�е квеÑ�товые таймеры
  1379.      */
  1380.     public void resumeQuestTimers()
  1381.     {
  1382.         for(QuestState qs : getAllQuestsStates())
  1383.             qs.resumeQuestTimers();
  1384.     }
  1385.  
  1386.     // ----------------- End of Quest Engine -------------------
  1387.  
  1388.     public Collection<ShortCut> getAllShortCuts()
  1389.     {
  1390.         return _shortCuts.getAllShortCuts();
  1391.     }
  1392.  
  1393.     public ShortCut getShortCut(int slot, int page)
  1394.     {
  1395.         return _shortCuts.getShortCut(slot, page);
  1396.     }
  1397.  
  1398.     public void registerShortCut(ShortCut shortcut)
  1399.     {
  1400.         _shortCuts.registerShortCut(shortcut);
  1401.     }
  1402.  
  1403.     public void deleteShortCut(int slot, int page)
  1404.     {
  1405.         _shortCuts.deleteShortCut(slot, page);
  1406.     }
  1407.  
  1408.     public void registerMacro(Macro macro)
  1409.     {
  1410.         _macroses.registerMacro(macro);
  1411.     }
  1412.  
  1413.     public void deleteMacro(int id)
  1414.     {
  1415.         _macroses.deleteMacro(id);
  1416.     }
  1417.  
  1418.     public MacroList getMacroses()
  1419.     {
  1420.         return _macroses;
  1421.     }
  1422.  
  1423.     public boolean isCastleLord(int castleId)
  1424.     {
  1425.         return _clan != null && isClanLeader() && _clan.getCastle() == castleId;
  1426.     }
  1427.  
  1428.     public int getPkKills()
  1429.     {
  1430.         return _pkKills;
  1431.     }
  1432.  
  1433.     public void setPkKills(final int pkKills)
  1434.     {
  1435.         _pkKills = pkKills;
  1436.     }
  1437.  
  1438.     public long getCreateTime()
  1439.     {
  1440.         return _createTime;
  1441.     }
  1442.  
  1443.     public void setCreateTime(final long createTime)
  1444.     {
  1445.         _createTime = createTime;
  1446.     }
  1447.  
  1448.     public int getDeleteTimer()
  1449.     {
  1450.         return _deleteTimer;
  1451.     }
  1452.  
  1453.     public void setDeleteTimer(final int deleteTimer)
  1454.     {
  1455.         _deleteTimer = deleteTimer;
  1456.     }
  1457.  
  1458.     @Override
  1459.     public int getCurrentLoad()
  1460.     {
  1461.         return getInventory().getTotalWeight();
  1462.     }
  1463.  
  1464.     public long getLastAccess()
  1465.     {
  1466.         return _lastAccess;
  1467.     }
  1468.  
  1469.     public void setLastAccess(long value)
  1470.     {
  1471.         _lastAccess = value;
  1472.     }
  1473.  
  1474.     public int getRecomHave()
  1475.     {
  1476.         return _recomHave;
  1477.     }
  1478.  
  1479.     public void setRecomHave(int value)
  1480.     {
  1481.         if(value > 255)
  1482.             _recomHave = 255;
  1483.         else if(value < 0)
  1484.             _recomHave = 0;
  1485.         else
  1486.             _recomHave = value;
  1487.     }
  1488.  
  1489.     public int getRecomLeft()
  1490.     {
  1491.         return _recomLeft;
  1492.     }
  1493.  
  1494.     public void setRecomLeft(final int value)
  1495.     {
  1496.         _recomLeft = value;
  1497.     }
  1498.  
  1499.     public void giveRecom(final Player target)
  1500.     {
  1501.         int targetRecom = target.getRecomHave();
  1502.         if(targetRecom < 255)
  1503.             target.addRecomHave(1);
  1504.         if(getRecomLeft() > 0)
  1505.             setRecomLeft(getRecomLeft() - 1);
  1506.  
  1507.         sendUserInfo(true);
  1508.     }
  1509.  
  1510.     public void addRecomHave(final int val)
  1511.     {
  1512.         setRecomHave(getRecomHave() + val);
  1513.         broadcastUserInfo(true);
  1514.     }
  1515.  
  1516.     @Override
  1517.     public int getKarma()
  1518.     {
  1519.         return _karma;
  1520.     }
  1521.  
  1522.     public void setKarma(int karma)
  1523.     {
  1524.         if(_karma == karma)
  1525.             return;
  1526.  
  1527.         _karma = Math.min(0, karma);
  1528.  
  1529.         sendChanges();
  1530.  
  1531.         for(Servitor servitor : getServitors())
  1532.             servitor.broadcastCharInfo();
  1533.     }
  1534.  
  1535.     @Override
  1536.     public int getMaxLoad()
  1537.     {
  1538.         return (int) calcStat(Stats.MAX_LOAD, 69000, this, null);
  1539.     }
  1540.  
  1541.     @Override
  1542.     public void updateAbnormalIcons()
  1543.     {
  1544.         if(entering || isLogoutStarted())
  1545.             return;
  1546.  
  1547.         super.updateAbnormalIcons();
  1548.     }
  1549.  
  1550.     @Override
  1551.     public void updateAbnormalIconsImpl()
  1552.     {
  1553.         Abnormal[] effects = getAbnormalList().toArray();
  1554.         Arrays.sort(effects, AbnormalsComparator.getInstance());
  1555.  
  1556.         PartySpelledPacket ps = new PartySpelledPacket(this, false);
  1557.         AbnormalStatusUpdatePacket abnormalStatus = new AbnormalStatusUpdatePacket();
  1558.  
  1559.         for(Abnormal effect : effects)
  1560.         {
  1561.             if(effect == null)
  1562.                 continue;
  1563.             if(effect.checkAbnormalType(AbnormalType.hp_recover))
  1564.                 sendPacket(new ShortBuffStatusUpdatePacket(effect));
  1565.             else
  1566.                 effect.addIcon(abnormalStatus);
  1567.             if(_party != null)
  1568.                 effect.addPartySpelledIcon(ps);
  1569.         }
  1570.  
  1571.         sendPacket(abnormalStatus);
  1572.         if(_party != null)
  1573.             _party.broadCast(ps);
  1574.  
  1575.         if(isInOlympiadMode() && isOlympiadCompStart())
  1576.         {
  1577.             OlympiadGame olymp_game = _olympiadGame;
  1578.             if(olymp_game != null)
  1579.             {
  1580.                 ExOlympiadSpelledInfoPacket olympiadSpelledInfo = new ExOlympiadSpelledInfoPacket();
  1581.  
  1582.                 for(Abnormal effect : effects)
  1583.                     if(effect != null)
  1584.                         effect.addOlympiadSpelledIcon(this, olympiadSpelledInfo);
  1585.  
  1586.                 sendPacket(olympiadSpelledInfo);
  1587.  
  1588.                 for(ObservePoint observer : olymp_game.getObservers())
  1589.                     observer.sendPacket(olympiadSpelledInfo);
  1590.             }
  1591.         }
  1592.  
  1593.         final List<SingleMatchEvent> events = getEvents(SingleMatchEvent.class);
  1594.         for(SingleMatchEvent event : events)
  1595.             event.onEffectIconsUpdate(this, effects);
  1596.  
  1597.         super.updateAbnormalIconsImpl();
  1598.     }
  1599.  
  1600.     @Override
  1601.     public int getWeightPenalty()
  1602.     {
  1603.         return getSkillLevel(4270, 0);
  1604.     }
  1605.  
  1606.     public void refreshOverloaded()
  1607.     {
  1608.         if(isLogoutStarted() || getMaxLoad() <= 0)
  1609.             return;
  1610.  
  1611.         setOverloaded(getCurrentLoad() > getMaxLoad());
  1612.         double weightproc = 100. * (getCurrentLoad() - calcStat(Stats.MAX_NO_PENALTY_LOAD, 0, this, null)) / getMaxLoad();
  1613.         int newWeightPenalty = 0;
  1614.  
  1615.         if(weightproc < 50)
  1616.             newWeightPenalty = 0;
  1617.         else if(weightproc < 66.6)
  1618.             newWeightPenalty = 1;
  1619.         else if(weightproc < 80)
  1620.             newWeightPenalty = 2;
  1621.         else if(weightproc < 100)
  1622.             newWeightPenalty = 3;
  1623.         else
  1624.             newWeightPenalty = 4;
  1625.  
  1626.         int current = getWeightPenalty();
  1627.         if(current == newWeightPenalty)
  1628.             return;
  1629.  
  1630.         if(newWeightPenalty > 0)
  1631.             addSkill(SkillHolder.getInstance().getSkillEntry(4270, newWeightPenalty));
  1632.         else
  1633.             super.removeSkill(getKnownSkill(4270));
  1634.  
  1635.         sendSkillList();
  1636.         sendEtcStatusUpdate();
  1637.         updateStats();
  1638.     }
  1639.  
  1640.     public int getArmorsExpertisePenalty()
  1641.     {
  1642.         return getSkillLevel(6213, 0);
  1643.     }
  1644.  
  1645.     public int getWeaponsExpertisePenalty()
  1646.     {
  1647.         return getSkillLevel(6209, 0);
  1648.     }
  1649.  
  1650.     public int getExpertisePenalty(ItemInstance item)
  1651.     {
  1652.         if(item.getTemplate().getType2() == ItemTemplate.TYPE2_WEAPON)
  1653.             return getWeaponsExpertisePenalty();
  1654.         else if(item.getTemplate().getType2() == ItemTemplate.TYPE2_SHIELD_ARMOR || item.getTemplate().getType2() == ItemTemplate.TYPE2_ACCESSORY)
  1655.             return getArmorsExpertisePenalty();
  1656.         return 0;
  1657.     }
  1658.  
  1659.     public void refreshExpertisePenalty()
  1660.     {
  1661.         if(isLogoutStarted())
  1662.             return;
  1663.  
  1664.         // Calculate the current higher Expertise of the L2Player
  1665.         int level = (int) calcStat(Stats.GRADE_EXPERTISE_LEVEL, getLevel(), null, null);
  1666.         int skillLvl = 0;
  1667.         for(skillLvl = 0; skillLvl < EXPERTISE_LEVELS.length; skillLvl++)
  1668.             if(level < EXPERTISE_LEVELS[skillLvl + 1])
  1669.                 break;
  1670.  
  1671.         skillLvl = Math.max(skillLvl, (int) calcStat(Stats.ADDITIONAL_EXPERTISE_INDEX));
  1672.         if(skillLvl == 7)
  1673.             skillLvl--;
  1674.  
  1675.         boolean skillUpdate = false; // ДлÑ� того, чтобы лишний раз не поÑ�ылать пакеты
  1676.  
  1677.         if(skillLvl > 0)
  1678.         {
  1679.             while(skillLvl >= 1)
  1680.             {
  1681.                 SkillEntry skill = SkillHolder.getInstance().getSkillEntry(239, skillLvl);
  1682.                 if(skill != null)
  1683.                 {
  1684.                     if(addSkill(skill, false) != skill)
  1685.                         skillUpdate = true;
  1686.                     break;
  1687.                 }
  1688.                 else
  1689.                     skillLvl--;
  1690.             }
  1691.         }
  1692.  
  1693.         if(Config.EXPERTISE_PENALTY_ENABLED)
  1694.         {
  1695.             int expertiseIndex = getExpertiseIndex();
  1696.             int newWeaponPenalty = 0;
  1697.             int newArmorPenalty = 0;
  1698.             ItemInstance[] items = getInventory().getPaperdollItems();
  1699.             for(ItemInstance item : items)
  1700.                 if(item != null)
  1701.                 {
  1702.                     int crystaltype = item.getTemplate().getGrade().ordinal();
  1703.                     if(item.getTemplate().getType2() == ItemTemplate.TYPE2_WEAPON)
  1704.                     {
  1705.                         if(crystaltype > newWeaponPenalty)
  1706.                             newWeaponPenalty = crystaltype;
  1707.                     }
  1708.                     else if(item.getTemplate().getType2() == ItemTemplate.TYPE2_SHIELD_ARMOR || item.getTemplate().getType2() == ItemTemplate.TYPE2_ACCESSORY)
  1709.                     {
  1710.                         if(crystaltype > expertiseIndex)
  1711.                         {
  1712.                             if(item.getBodyPart() == ItemTemplate.SLOT_FULL_ARMOR)
  1713.                                 newArmorPenalty++;
  1714.                             newArmorPenalty++;
  1715.                         }
  1716.                     }
  1717.                 }
  1718.  
  1719.             //Уровень штрафа оружиÑ� равен разнице между рангом оружиÑ� и допуÑ�тим рангом длÑ� перÑ�онажа.
  1720.             newWeaponPenalty = newWeaponPenalty - expertiseIndex;
  1721.             newWeaponPenalty = Math.max(0, Math.min(4, newWeaponPenalty));
  1722.  
  1723.             //Уровень штрафа брони равен количеÑ�тву одетой брони на перÑ�онажа не по рангу.
  1724.             newArmorPenalty = Math.max(0, Math.min(4, newArmorPenalty));
  1725.  
  1726.             int weaponExpertise = getWeaponsExpertisePenalty();
  1727.             int armorExpertise = getArmorsExpertisePenalty();
  1728.  
  1729.             if(weaponExpertise != newWeaponPenalty)
  1730.             {
  1731.                 weaponExpertise = newWeaponPenalty;
  1732.                 if(newWeaponPenalty > 0)
  1733.                     addSkill(SkillHolder.getInstance().getSkillEntry(6209, weaponExpertise));
  1734.                 else
  1735.                     super.removeSkill(getKnownSkill(6209));
  1736.                 skillUpdate = true;
  1737.             }
  1738.             if(armorExpertise != newArmorPenalty)
  1739.             {
  1740.                 armorExpertise = newArmorPenalty;
  1741.                 if(newArmorPenalty > 0)
  1742.                     addSkill(SkillHolder.getInstance().getSkillEntry(6213, armorExpertise));
  1743.                 else
  1744.                     super.removeSkill(getKnownSkill(6213));
  1745.                 skillUpdate = true;
  1746.             }
  1747.         }
  1748.  
  1749.         if(skillUpdate)
  1750.         {
  1751.             getInventory().validateItemsSkills();
  1752.  
  1753.             sendSkillList();
  1754.             sendEtcStatusUpdate();
  1755.             updateStats();
  1756.         }
  1757.     }
  1758.  
  1759.     public int getPvpKills()
  1760.     {
  1761.         return _pvpKills;
  1762.     }
  1763.  
  1764.     public void setPvpKills(int pvpKills)
  1765.     {
  1766.         _pvpKills = pvpKills;
  1767.     }
  1768.  
  1769.     public ClassLevel getClassLevel()
  1770.     {
  1771.         return getClassId().getClassLevel();
  1772.     }
  1773.  
  1774.     public boolean isAcademyGraduated()
  1775.     {
  1776.         return getVarBoolean(ACADEMY_GRADUATED_VAR, false);
  1777.     }
  1778.  
  1779.     /**
  1780.      * Set the template of the L2Player.
  1781.      *
  1782.      * @param id The Identifier of the L2PlayerTemplate to set to the L2Player
  1783.      */
  1784.     public synchronized void setClassId(final int id, boolean noban)
  1785.     {
  1786.         ClassId classId = ClassId.VALUES[id];
  1787.         if(classId.isDummy())
  1788.             return;
  1789.         if(!noban && !(classId.equalsOrChildOf(getClassId()) || getPlayerAccess().CanChangeClass || Config.EVERYBODY_HAS_ADMIN_RIGHTS))
  1790.         {
  1791.             Thread.dumpStack();
  1792.             return;
  1793.         }
  1794.  
  1795.         PlayerTemplate template = PlayerTemplateHolder.getInstance().getPlayerTemplate(getRace(), classId, getSex());
  1796.         if(template == null)
  1797.         {
  1798.             _log.error("Missing template for classId: " + id);
  1799.             return;
  1800.         }
  1801.         setTemplate(template);
  1802.  
  1803.         //ЕÑ�ли новый ID не принадлежит имеющимÑ�Ñ� клаÑ�Ñ�ам значит Ñ�то новаÑ� профа
  1804.         if(!_subClassList.containsClassId(id))
  1805.         {
  1806.             final SubClass cclass = getActiveSubClass();
  1807.             final ClassId oldClass = ClassId.VALUES[cclass.getClassId()];
  1808.  
  1809.             _subClassList.changeSubClassId(oldClass.getId(), id);
  1810.             changeClassInDb(oldClass.getId(), id);
  1811.  
  1812.             onReceiveNewClassId(oldClass, classId);
  1813.  
  1814.             storeCharSubClasses();
  1815.  
  1816.             getListeners().onClassChange(oldClass, classId);
  1817.  
  1818.             for(QuestState qs : getAllQuestsStates())
  1819.                 qs.getQuest().notifyTutorialEvent("CE", false, "100", qs);
  1820.         }
  1821.         else
  1822.             getListeners().onClassChange(null, classId);
  1823.  
  1824.         broadcastUserInfo(true);
  1825.  
  1826.         // Update class icon in party and clan
  1827.         if(isInParty())
  1828.             getParty().broadCast(new PartySmallWindowUpdatePacket(this));
  1829.         if(getClan() != null)
  1830.             getClan().broadcastToOnlineMembers(new PledgeShowMemberListUpdatePacket(this));
  1831.         if(_matchingRoom != null)
  1832.             _matchingRoom.broadcastPlayerUpdate(this);
  1833.     }
  1834.  
  1835.     private void onReceiveNewClassId(ClassId oldClass, ClassId newClass)
  1836.     {
  1837.         if(oldClass != null)
  1838.         {
  1839.             if(isBaseClassActive())
  1840.             {
  1841.                 OlympiadParticipiantData participant = Olympiad.getParticipantInfo(getObjectId());
  1842.                 if(participant != null)
  1843.                     participant.setClassId(newClass.getId());
  1844.             }
  1845.  
  1846.             if(!newClass.equalsOrChildOf(oldClass))
  1847.             {
  1848.                 removeAllSkills();
  1849.                 restoreSkills();
  1850.                 rewardSkills(false);
  1851.  
  1852.                 checkSkills();
  1853.  
  1854.                 refreshExpertisePenalty();
  1855.  
  1856.                 getInventory().refreshEquip();
  1857.                 getInventory().validateItems();
  1858.  
  1859.                 getHennaList().refreshStats(true);
  1860.  
  1861.                 sendSkillList();
  1862.  
  1863.                 updateStats();
  1864.             }
  1865.             else
  1866.                 rewardSkills(true);
  1867.         }
  1868.     }
  1869.  
  1870.     public long getExp()
  1871.     {
  1872.         return getActiveSubClass() == null ? 0 : getActiveSubClass().getExp();
  1873.     }
  1874.  
  1875.     public long getMaxExp()
  1876.     {
  1877.         return getActiveSubClass() == null ? Experience.getExpForLevel(Experience.getMaxLevel() + 1) : getActiveSubClass().getMaxExp();
  1878.     }
  1879.  
  1880.     public void setEnchantScroll(final ItemInstance scroll)
  1881.     {
  1882.         _enchantScroll = scroll;
  1883.     }
  1884.  
  1885.     public ItemInstance getEnchantScroll()
  1886.     {
  1887.         return _enchantScroll;
  1888.     }
  1889.  
  1890.     public void addExpAndCheckBonus(MonsterInstance mob, final double noRateExp, double noRateSp)
  1891.     {
  1892.         if(getActiveSubClass() == null)
  1893.             return;
  1894.  
  1895.         // Ð�ачиÑ�ление душ камаÑ�лÑ�м
  1896.         double neededExp = calcStat(Stats.SOULS_CONSUME_EXP, 0, mob, null);
  1897.         if(neededExp > 0 && noRateExp > neededExp)
  1898.         {
  1899.             mob.broadcastPacket(new ExSpawnEmitterPacket(mob, this));
  1900.             ThreadPoolManager.getInstance().schedule(new GameObjectTasks.SoulConsumeTask(this), 1000);
  1901.         }
  1902.  
  1903.         if(noRateExp > 0)
  1904.         {
  1905.             if(!(getVarBoolean("NoExp") && getExp() == Experience.getExpForLevel(getLevel() + 1) - 1))
  1906.             {
  1907.                 Clan clan = getClan();
  1908.                 if(clan != null)
  1909.                 {
  1910.                     int huntingPoints = Math.max((int)(noRateExp * (getRateExp() / Config.RATE_XP_BY_LVL[getLevel()]) / Math.pow(getLevel(), 2.0) * Config.CLAN_HUNTING_PROGRESS_RATE), 1);
  1911.                     clan.addHuntingProgress(huntingPoints);
  1912.                 }
  1913.             }  
  1914.         }
  1915.  
  1916.         long normalExp = (long) (noRateExp * getRateExp() * (mob.isRaid() ? Config.RATE_XP_RAIDBOSS_MODIFIER : 1.0));
  1917.         long normalSp = (long) (noRateSp * getRateSp());
  1918.  
  1919.         long expWithoutBonus = (long) (noRateExp * Config.RATE_XP_BY_LVL[getLevel()]);
  1920.         long spWithoutBonus = (long) (noRateSp * Config.RATE_SP_BY_LVL[getLevel()]);
  1921.  
  1922.         addExpAndSp(normalExp, normalSp, normalExp - expWithoutBonus, normalSp - spWithoutBonus, false, true, false, true, true);
  1923.     }
  1924.  
  1925.     @Override
  1926.     public void addExpAndSp(long exp, long sp)
  1927.     {
  1928.         addExpAndSp(exp, sp, -1, -1, false, false, Config.ALT_DELEVEL_ON_DEATH_PENALTY_MIN_LEVEL > -1 && getLevel() >= Config.ALT_DELEVEL_ON_DEATH_PENALTY_MIN_LEVEL, true, true);
  1929.     }
  1930.  
  1931.     public void addExpAndSp(long exp, long sp, boolean delevel)
  1932.     {
  1933.         addExpAndSp(exp, sp, -1, -1, false, false, delevel, true, true);
  1934.     }
  1935.  
  1936.     public void addExpAndSp(long addToExp, long addToSp, long bonusAddExp, long bonusAddSp, boolean applyRate, boolean applyToPet, boolean delevel, boolean clearKarma, boolean sendMsg)
  1937.     {
  1938.         if(getActiveSubClass() == null)
  1939.             return;
  1940.  
  1941.         if(addToExp < 0 && isFakePlayer())
  1942.             return;
  1943.  
  1944.         if(applyRate)
  1945.         {
  1946.             addToExp *= getRateExp();
  1947.             addToSp *= getRateSp();
  1948.         }
  1949.  
  1950.         PetInstance pet = getPet();
  1951.         if(addToExp > 0)
  1952.         {
  1953.             if(applyToPet)
  1954.             {
  1955.                 if(pet != null && !pet.isDead() && !pet.getData().isOfType(PetType.SPECIAL))
  1956.                 {
  1957.                     // Sin Eater забирает вÑ�ÑŽ Ñ�кÑ�пу у перÑ�онажа
  1958.                     if(pet.getData().isOfType(PetType.KARMA))
  1959.                     {
  1960.                         pet.addExpAndSp(addToExp, 0);
  1961.                         addToExp = 0;
  1962.                     }
  1963.                     else if(pet.getExpPenalty() > 0f)
  1964.                     {
  1965.                         if(pet.getLevel() > getLevel() - 20 && pet.getLevel() < getLevel() + 5)
  1966.                         {
  1967.                             pet.addExpAndSp((long) (addToExp * pet.getExpPenalty()), 0);
  1968.                             addToExp *= 1. - pet.getExpPenalty();
  1969.                         }
  1970.                         else
  1971.                         {
  1972.                             pet.addExpAndSp((long) (addToExp * pet.getExpPenalty() / 5.), 0);
  1973.                             addToExp *= 1. - pet.getExpPenalty() / 5.;
  1974.                         }
  1975.                     }
  1976.                     else if(pet.isSummon())
  1977.                         addToExp *= 1. - pet.getExpPenalty();
  1978.                 }
  1979.             }
  1980.  
  1981.             // Remove Karma when the player kills L2MonsterInstance
  1982.             //TODO [G1ta0] двинуть в метод начиÑ�лениÑ� наград при убйиÑ�тве моба
  1983.             if(clearKarma && isPK() && !isInZoneBattle())
  1984.             {
  1985.                 int karmaLost = Formulas.calculateKarmaLost(this, addToExp);
  1986.                 if(karmaLost > 0)
  1987.                 {
  1988.                     _karma += karmaLost;
  1989.                     if(_karma > 0)
  1990.                         _karma = 0;
  1991.  
  1992.                     if(sendMsg)
  1993.                         sendPacket(new SystemMessagePacket(SystemMsg.YOUR_FAME_HAS_BEEN_CHANGED_TO_S1).addInteger(_karma));
  1994.                 }
  1995.             }
  1996.  
  1997.             long max_xp = getVarBoolean("NoExp") || isInDuel() ? Experience.getExpForLevel(getLevel() + 1) - 1 : getMaxExp();
  1998.             addToExp = Math.min(addToExp, max_xp - getExp());
  1999.         }
  2000.  
  2001.         int oldLvl = getActiveSubClass().getLevel();
  2002.  
  2003.         getActiveSubClass().addExp(addToExp, delevel);
  2004.         getActiveSubClass().addSp(addToSp);
  2005.  
  2006.         if(addToExp > 0)
  2007.             _receivedExp += addToExp;
  2008.  
  2009.         if(sendMsg)
  2010.         {
  2011.             if((addToExp > 0 || addToSp > 0) && bonusAddExp >= 0 && bonusAddSp >= 0)
  2012.                 sendPacket(new SystemMessagePacket(SystemMsg.YOU_HAVE_ACQUIRED_S1_EXP_BONUS_S2_AND_S3_SP_BONUS_S4).addLong(addToExp).addLong(bonusAddExp).addInteger(addToSp).addInteger((int) bonusAddSp));
  2013.             else if(addToSp > 0 && addToExp == 0)
  2014.                 sendPacket(new SystemMessage(SystemMessage.YOU_HAVE_ACQUIRED_S1_SP).addNumber(addToSp));
  2015.             else if(addToSp > 0 && addToExp > 0)
  2016.                 sendPacket(new SystemMessage(SystemMessage.YOU_HAVE_EARNED_S1_EXPERIENCE_AND_S2_SP).addNumber(addToExp).addNumber(addToSp));
  2017.             else if(addToSp == 0 && addToExp > 0)
  2018.                 sendPacket(new SystemMessage(SystemMessage.YOU_HAVE_EARNED_S1_EXPERIENCE).addNumber(addToExp));
  2019.         }
  2020.  
  2021.         int level = getActiveSubClass().getLevel();
  2022.         if(level != oldLvl)
  2023.         {
  2024.             levelSet(level - oldLvl);
  2025.             getListeners().onLevelChange(oldLvl, level);
  2026.  
  2027.             for(ListenerHook hook : ListenerHook.getGlobalListenerHooks(ListenerHookType.PLAYER_GLOBAL_LEVEL_UP))
  2028.                 hook.onPlayerGlobalLevelUp(this, oldLvl, level);
  2029.         }
  2030.  
  2031.         if(pet != null && pet.getData().isOfType(PetType.SPECIAL))
  2032.         {
  2033.             pet.setLevel(getLevel());
  2034.             pet.setExp(pet.getExpForNextLevel());
  2035.             pet.broadcastStatusUpdate();
  2036.         }
  2037.  
  2038.         updateStats();
  2039.     }
  2040.  
  2041.     private boolean _dontRewardSkills = false; // ГлупаÑ� заглушка, но Ñ�паÑ�ает.
  2042.  
  2043.     public void rewardSkills(boolean send)
  2044.     {
  2045.         rewardSkills(send, true, Config.AUTO_LEARN_SKILLS, true);
  2046.     }
  2047.  
  2048.     public int rewardSkills(boolean send, boolean checkShortCuts, boolean learnAllSkills, boolean checkRequiredItems)
  2049.     {
  2050.         if(_dontRewardSkills)
  2051.             return 0;
  2052.  
  2053.         List<SkillLearn> skillLearns = new ArrayList<SkillLearn>(SkillAcquireHolder.getInstance().getAvailableNextLevelsSkills(this, AcquireType.NORMAL));
  2054.         Collections.sort(skillLearns);
  2055.         Collections.reverse(skillLearns);
  2056.  
  2057.         IntObjectMap<SkillLearn> skillsToLearnMap = new HashIntObjectMap<SkillLearn>();
  2058.         for(SkillLearn sl : skillLearns)
  2059.         {
  2060.             if(!(sl.isAutoGet() && ((learnAllSkills && (!checkRequiredItems || !sl.haveRequiredItemsForLearn(AcquireType.NORMAL))) || sl.isFreeAutoGet(AcquireType.NORMAL))))
  2061.             {
  2062.                 // ЕÑ�ли предыдущий уровень умениÑ� учитÑ�Ñ� Ð�Е БЕСПЛÐ�ТÐ�О, то не учим беÑ�платно больший уровень умениÑ�.
  2063.                 skillsToLearnMap.remove(sl.getId());
  2064.                 continue;
  2065.             }
  2066.  
  2067.             if(!skillsToLearnMap.containsKey(sl.getId()))
  2068.                 skillsToLearnMap.put(sl.getId(), sl);
  2069.         }
  2070.  
  2071.         boolean update = false;
  2072.         int addedSkillsCount = 0;
  2073.  
  2074.         for(SkillLearn sl : skillsToLearnMap.values())
  2075.         {
  2076.             SkillEntry skillEntry = SkillHolder.getInstance().getSkillEntry(sl.getId(), sl.getLevel());
  2077.             if(skillEntry == null)
  2078.                 continue;
  2079.  
  2080.             if(addSkill(skillEntry, true) == null)
  2081.                 addedSkillsCount++;
  2082.  
  2083.             if(checkShortCuts && getAllShortCuts().size() > 0 && skillEntry.getLevel() > 1)
  2084.                 updateSkillShortcuts(skillEntry.getId(), skillEntry.getLevel());
  2085.  
  2086.             update = true;
  2087.         }
  2088.  
  2089.         if(isTransformed())
  2090.         {
  2091.             boolean added = false;
  2092.             // ДобавлÑ�ем Ñ�киллы транÑ�формации завиÑ�Ñ�щие от уровнÑ� перÑ�онажа
  2093.             for(SkillLearn sl : _transform.getAddtionalSkills())
  2094.             {
  2095.                 if(sl.getMinLevel() > getLevel())
  2096.                     continue;
  2097.  
  2098.                 SkillEntry skillEntry = _transformSkills.get(sl.getId());
  2099.                 if(skillEntry != null && skillEntry.getLevel() >= sl.getLevel())
  2100.                     continue;
  2101.  
  2102.                 skillEntry = SkillHolder.getInstance().getSkillEntry(sl.getId(), sl.getLevel());
  2103.                 if(skillEntry == null)
  2104.                     continue;
  2105.  
  2106.                 _transformSkills.remove(skillEntry.getId());
  2107.                 _transformSkills.put(skillEntry.getId(), skillEntry);
  2108.  
  2109.                 update = true;
  2110.                 added = true;
  2111.             }
  2112.  
  2113.             if(added)
  2114.             {
  2115.                 for(SkillEntry skillEntry : _transformSkills.values())
  2116.                 {
  2117.                     if(addSkill(skillEntry, false) == null)
  2118.                         addedSkillsCount++;
  2119.                 }
  2120.             }
  2121.         }
  2122.  
  2123.         updateStats();
  2124.  
  2125.         if(send && update)
  2126.             sendSkillList();
  2127.  
  2128.         return addedSkillsCount;
  2129.     }
  2130.  
  2131.     public Race getRace()
  2132.     {
  2133.         return ClassId.VALUES[getBaseClassId()].getRace();
  2134.     }
  2135.  
  2136.     public ClassType getBaseClassType()
  2137.     {
  2138.         return ClassId.VALUES[getBaseClassId()].getType();
  2139.     }
  2140.  
  2141.     public long getSp()
  2142.     {
  2143.         return getActiveSubClass() == null ? 0 : getActiveSubClass().getSp();
  2144.     }
  2145.  
  2146.     public void setSp(long sp)
  2147.     {
  2148.         if(getActiveSubClass() != null)
  2149.             getActiveSubClass().setSp(sp);
  2150.     }
  2151.  
  2152.     public int getClanId()
  2153.     {
  2154.         return _clan == null ? 0 : _clan.getClanId();
  2155.     }
  2156.  
  2157.     public long getLeaveClanTime()
  2158.     {
  2159.         return _leaveClanTime;
  2160.     }
  2161.  
  2162.     public long getDeleteClanTime()
  2163.     {
  2164.         return _deleteClanTime;
  2165.     }
  2166.  
  2167.     public void setLeaveClanTime(final long time)
  2168.     {
  2169.         _leaveClanTime = time;
  2170.     }
  2171.  
  2172.     public void setDeleteClanTime(final long time)
  2173.     {
  2174.         _deleteClanTime = time;
  2175.     }
  2176.  
  2177.     public void setOnlineTime(final long time)
  2178.     {
  2179.         _onlineTime = time;
  2180.         _onlineBeginTime = System.currentTimeMillis();
  2181.     }
  2182.  
  2183.     public int getOnlineTime()
  2184.     {
  2185.         return (int) (_onlineBeginTime > 0 ? (_onlineTime + System.currentTimeMillis() - _onlineBeginTime) / 1000L : _onlineTime / 1000L);
  2186.     }
  2187.  
  2188.     public long getOnlineBeginTime()
  2189.     {
  2190.         return _onlineBeginTime;
  2191.     }
  2192.  
  2193.     public void setNoChannel(final long time)
  2194.     {
  2195.         _NoChannel = time;
  2196.         if(_NoChannel > 2145909600000L || _NoChannel < 0)
  2197.             _NoChannel = -1;
  2198.  
  2199.         if(_NoChannel > 0)
  2200.             _NoChannelBegin = System.currentTimeMillis();
  2201.         else
  2202.             _NoChannelBegin = 0;
  2203.     }
  2204.  
  2205.     public long getNoChannel()
  2206.     {
  2207.         return _NoChannel;
  2208.     }
  2209.  
  2210.     public long getNoChannelRemained()
  2211.     {
  2212.         if(_NoChannel == 0)
  2213.             return 0;
  2214.         else if(_NoChannel < 0)
  2215.             return -1;
  2216.         else
  2217.         {
  2218.             long remained = _NoChannel - System.currentTimeMillis() + _NoChannelBegin;
  2219.             if(remained < 0)
  2220.                 return 0;
  2221.  
  2222.             return remained;
  2223.         }
  2224.     }
  2225.  
  2226.     public boolean isChatBlocked()
  2227.     {
  2228.         return getFlags().getChatBlocked().get();
  2229.     }
  2230.  
  2231.     public boolean isEscapeBlocked()
  2232.     {
  2233.         return getFlags().getEscapeBlocked().get();
  2234.     }
  2235.  
  2236.     public boolean isPartyBlocked()
  2237.     {
  2238.         return getFlags().getPartyBlocked().get();
  2239.     }
  2240.  
  2241.     public boolean isVioletBoy()
  2242.     {
  2243.         return getFlags().getVioletBoy().get();
  2244.     }
  2245.  
  2246.     public void setLeaveClanCurTime()
  2247.     {
  2248.         _leaveClanTime = System.currentTimeMillis();
  2249.     }
  2250.  
  2251.     public void setDeleteClanCurTime()
  2252.     {
  2253.         _deleteClanTime = System.currentTimeMillis();
  2254.     }
  2255.  
  2256.     public boolean canJoinClan()
  2257.     {
  2258.         if(_leaveClanTime == 0)
  2259.             return true;
  2260.         if(System.currentTimeMillis() - _leaveClanTime >= Config.ALT_CLAN_LEAVE_PENALTY_TIME * 60 * 60 * 1000L)
  2261.         {
  2262.             _leaveClanTime = 0;
  2263.             return true;
  2264.         }
  2265.         return false;
  2266.     }
  2267.  
  2268.     public boolean canCreateClan()
  2269.     {
  2270.         if(_deleteClanTime == 0)
  2271.             return true;
  2272.         if(System.currentTimeMillis() - _deleteClanTime >= Config.ALT_CLAN_CREATE_PENALTY_TIME * 60 * 60 * 1000L)
  2273.         {
  2274.             _deleteClanTime = 0;
  2275.             return true;
  2276.         }
  2277.         return false;
  2278.     }
  2279.  
  2280.     public IBroadcastPacket canJoinParty(Player inviter)
  2281.     {
  2282.         Request request = getRequest();
  2283.         if(request != null && request.isInProgress() && request.getOtherPlayer(this) != inviter)
  2284.             return SystemMsg.WAITING_FOR_ANOTHER_REPLY.packet(inviter); // занÑ�Ñ‚
  2285.         if(isBlockAll() || getMessageRefusal()) // вÑ�ех нафиг
  2286.             return SystemMsg.THAT_PERSON_IS_IN_MESSAGE_REFUSAL_MODE.packet(inviter);
  2287.         if(isInParty()) // уже
  2288.             return new SystemMessagePacket(SystemMsg.C1_IS_A_MEMBER_OF_ANOTHER_PARTY_AND_CANNOT_BE_INVITED).addName(this);
  2289.         if(isPartyBlocked())
  2290.             return new SystemMessagePacket(SystemMsg.C1_HAS_BEEN_REPORTED_AS_AN_ILLEGAL_PROGRAM_USER_AND_CANNOT_JOIN_A_PARTY).addName(this);
  2291.         if(inviter.getReflection() != getReflection()) // в разных инÑ�тантах
  2292.             if(!inviter.getReflection().isMain() && !getReflection().isMain())
  2293.                 return SystemMsg.INVALID_TARGET.packet(inviter);
  2294.         if(inviter.isInOlympiadMode() || isInOlympiadMode()) // олимпиада
  2295.             return SystemMsg.A_USER_CURRENTLY_PARTICIPATING_IN_THE_OLYMPIAD_CANNOT_SEND_PARTY_AND_FRIEND_INVITATIONS.packet(inviter);
  2296.         if(!inviter.getPlayerAccess().CanJoinParty || !getPlayerAccess().CanJoinParty) // низÑ�
  2297.             return SystemMsg.INVALID_TARGET.packet(inviter);
  2298.         return null;
  2299.     }
  2300.  
  2301.     @Override
  2302.     public PcInventory getInventory()
  2303.     {
  2304.         return _inventory;
  2305.     }
  2306.  
  2307.     @Override
  2308.     public long getWearedMask()
  2309.     {
  2310.         return _inventory.getWearedMask();
  2311.     }
  2312.  
  2313.     public PcFreight getFreight()
  2314.     {
  2315.         return _freight;
  2316.     }
  2317.  
  2318.     public void removeItemFromShortCut(final int objectId)
  2319.     {
  2320.         _shortCuts.deleteShortCutByObjectId(objectId);
  2321.     }
  2322.  
  2323.     public void removeSkillFromShortCut(final int skillId)
  2324.     {
  2325.         _shortCuts.deleteShortCutBySkillId(skillId);
  2326.     }
  2327.  
  2328.     @Override
  2329.     public boolean isSitting()
  2330.     {
  2331.         return _isSitting;
  2332.     }
  2333.  
  2334.     public void setSitting(boolean val)
  2335.     {
  2336.         _isSitting = val;
  2337.     }
  2338.  
  2339.     public boolean getSittingTask()
  2340.     {
  2341.         return sittingTaskLaunched;
  2342.     }
  2343.  
  2344.     public ChairInstance getChairObject()
  2345.     {
  2346.         return _chairObject;
  2347.     }
  2348.  
  2349.     @Override
  2350.     public void sitDown(ChairInstance chair)
  2351.     {
  2352.         if(isSitting() || sittingTaskLaunched || isAlikeDead())
  2353.             return;
  2354.  
  2355.         if(isStunned() || isSleeping() || isDecontrolled() || isAttackingNow() || isCastingNow() || isMoving)
  2356.         {
  2357.             getAI().setNextAction(AINextAction.REST, null, null, false, false);
  2358.             return;
  2359.         }
  2360.  
  2361.         resetWaitSitTime();
  2362.         getAI().setIntention(CtrlIntention.AI_INTENTION_REST, null, null);
  2363.  
  2364.         if(chair == null)
  2365.             broadcastPacket(new ChangeWaitTypePacket(this, ChangeWaitTypePacket.WT_SITTING));
  2366.         else
  2367.         {
  2368.             chair.setSeatedPlayer(this);
  2369.             broadcastPacket(new ChairSitPacket(this, chair));
  2370.         }
  2371.  
  2372.         _chairObject = chair;
  2373.         setSitting(true);
  2374.         sittingTaskLaunched = true;
  2375.         ThreadPoolManager.getInstance().schedule(new EndSitDownTask(this), 2500);
  2376.     }
  2377.  
  2378.     @Override
  2379.     public void standUp()
  2380.     {
  2381.         if(!isSitting() || sittingTaskLaunched || isInStoreMode() || isAlikeDead())
  2382.             return;
  2383.  
  2384.         //FIXME [G1ta0] Ñ�ффект Ñ�ам отключаетÑ�Ñ� во времÑ� дейÑ�твиÑ�, еÑ�ли перÑ�онаж не Ñ�идит, возможно Ñ�тоит убрать
  2385.         getAbnormalList().stop(EffectType.Relax);
  2386.  
  2387.         getAI().clearNextAction();
  2388.         broadcastPacket(new ChangeWaitTypePacket(this, ChangeWaitTypePacket.WT_STANDING));
  2389.  
  2390.         if(_chairObject != null)
  2391.             _chairObject.setSeatedPlayer(this);
  2392.  
  2393.         _chairObject = null;
  2394.         sittingTaskLaunched = true;
  2395.         ThreadPoolManager.getInstance().schedule(new EndStandUpTask(this), 2500);
  2396.     }
  2397.  
  2398.     public void updateWaitSitTime()
  2399.     {
  2400.         if(_waitTimeWhenSit < 200)
  2401.             _waitTimeWhenSit += 2;
  2402.     }
  2403.  
  2404.     public int getWaitSitTime()
  2405.     {
  2406.         return _waitTimeWhenSit;
  2407.     }
  2408.  
  2409.     public void resetWaitSitTime()
  2410.     {
  2411.         _waitTimeWhenSit = 0;
  2412.     }
  2413.  
  2414.     public Warehouse getWarehouse()
  2415.     {
  2416.         return _warehouse;
  2417.     }
  2418.  
  2419.     public ItemContainer getRefund()
  2420.     {
  2421.         return _refund;
  2422.     }
  2423.  
  2424.     public long getAdena()
  2425.     {
  2426.         return getInventory().getAdena();
  2427.     }
  2428.  
  2429.     public boolean reduceAdena(long adena)
  2430.     {
  2431.         return reduceAdena(adena, false);
  2432.     }
  2433.  
  2434.     /**
  2435.      * Забирает адену у игрока.<BR><BR>
  2436.      *
  2437.      * @param adena  - Ñ�колько адены забрать
  2438.      * @param notify - отображать Ñ�иÑ�темное Ñ�ообщение
  2439.      * @return true еÑ�ли Ñ�нÑ�ли
  2440.      */
  2441.     public boolean reduceAdena(long adena, boolean notify)
  2442.     {
  2443.         if(adena < 0)
  2444.             return false;
  2445.         if(adena == 0)
  2446.             return true;
  2447.         boolean result = getInventory().reduceAdena(adena);
  2448.         if(notify && result)
  2449.             sendPacket(SystemMessagePacket.removeItems(ItemTemplate.ITEM_ID_ADENA, adena));
  2450.         return result;
  2451.     }
  2452.  
  2453.     public ItemInstance addAdena(long adena)
  2454.     {
  2455.         return addAdena(adena, false);
  2456.     }
  2457.  
  2458.     /**
  2459.      * ДобавлÑ�ет адену игроку.<BR><BR>
  2460.      *
  2461.      * @param adena  - Ñ�колько адены дать
  2462.      * @param notify - отображать Ñ�иÑ�темное Ñ�ообщение
  2463.      * @return L2ItemInstance - новое количеÑ�тво адены
  2464.      */
  2465.     public ItemInstance addAdena(long adena, boolean notify)
  2466.     {
  2467.         if(adena < 1)
  2468.             return null;
  2469.         ItemInstance item = getInventory().addAdena(adena);
  2470.         if(item != null && notify)
  2471.             sendPacket(SystemMessagePacket.obtainItems(ItemTemplate.ITEM_ID_ADENA, adena, 0));
  2472.         return item;
  2473.     }
  2474.  
  2475.     public GameClient getNetConnection()
  2476.     {
  2477.         return _connection;
  2478.     }
  2479.  
  2480.     public int getRevision()
  2481.     {
  2482.         return _connection == null ? 0 : _connection.getRevision();
  2483.     }
  2484.  
  2485.     public void setNetConnection(final GameClient connection)
  2486.     {
  2487.         _connection = connection;
  2488.     }
  2489.  
  2490.     public boolean isConnected()
  2491.     {
  2492.         return _connection != null && _connection.isConnected();
  2493.     }
  2494.  
  2495.     @Override
  2496.     public void onAction(final Player player, boolean shift)
  2497.     {
  2498.         if(!isTargetable(player))
  2499.         {
  2500.             player.sendActionFailed();
  2501.             return;
  2502.         }
  2503.  
  2504.         if(isFrozen())
  2505.         {
  2506.             player.sendPacket(ActionFailPacket.STATIC);
  2507.             return;
  2508.         }
  2509.  
  2510.         if(shift && OnShiftActionHolder.getInstance().callShiftAction(player, Player.class, this, true))
  2511.             return;
  2512.  
  2513.         // Check if the other player already target this L2Player
  2514.         if(player.getTarget() != this)
  2515.         {
  2516.             player.setTarget(this);
  2517.             if(player.getTarget() != this)
  2518.                 player.sendPacket(ActionFailPacket.STATIC);
  2519.         }
  2520.         else if(getPrivateStoreType() != Player.STORE_PRIVATE_NONE)
  2521.         {
  2522.             if(!player.checkInteractionDistance(this) && player.getAI().getIntention() != CtrlIntention.AI_INTENTION_INTERACT)
  2523.             {
  2524.                 if(!shift)
  2525.                     player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this, null);
  2526.                 else
  2527.                     player.sendPacket(ActionFailPacket.STATIC);
  2528.             }
  2529.             else
  2530.                 player.doInteract(this);
  2531.         }
  2532.         else if(isAutoAttackable(player))
  2533.             player.getAI().Attack(this, false, shift);
  2534.         else if(player != this)
  2535.         {
  2536.             if(player.getAI().getIntention() != CtrlIntention.AI_INTENTION_FOLLOW)
  2537.             {
  2538.                 if(!shift)
  2539.                     player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this, Config.FOLLOW_RANGE);
  2540.                 else
  2541.                     player.sendPacket(ActionFailPacket.STATIC);
  2542.             }
  2543.             else
  2544.                 player.sendPacket(ActionFailPacket.STATIC);
  2545.         }
  2546.         else
  2547.             player.sendPacket(ActionFailPacket.STATIC);
  2548.     }
  2549.  
  2550.     @Override
  2551.     public void broadcastStatusUpdate()
  2552.     {
  2553.         //if(!needStatusUpdate()) //По идее еше должно Ñ�резать траффик. Будут глюки Ñ� отображением - убрать Ñ�то уÑ�ловие.
  2554.             //return;
  2555.  
  2556.         sendPacket(makeStatusUpdate(null, StatusUpdatePacket.MAX_HP, StatusUpdatePacket.MAX_MP, StatusUpdatePacket.MAX_CP, StatusUpdatePacket.CUR_HP, StatusUpdatePacket.CUR_MP, StatusUpdatePacket.CUR_CP));
  2557.         broadcastPacketToOthers(makeStatusUpdate(null, StatusUpdatePacket.MAX_HP, StatusUpdatePacket.MAX_MP, StatusUpdatePacket.MAX_CP, StatusUpdatePacket.CUR_HP, StatusUpdatePacket.CUR_MP, StatusUpdatePacket.CUR_CP));
  2558.  
  2559.         // Check if a party is in progress
  2560.         if(isInParty())
  2561.             // Send the Server->Client packet PartySmallWindowUpdatePacket with current HP, MP and Level to all other L2Player of the Party
  2562.             getParty().broadcastToPartyMembers(this, new PartySmallWindowUpdatePacket(this));
  2563.  
  2564.         final List<SingleMatchEvent> events = getEvents(SingleMatchEvent.class);
  2565.         for(SingleMatchEvent event : events)
  2566.             event.onStatusUpdate(this);
  2567.  
  2568.         if(isInOlympiadMode() && isOlympiadCompStart())
  2569.         {
  2570.             if(_olympiadGame != null)
  2571.                 _olympiadGame.broadcastInfo(this, null, false);
  2572.         }
  2573.     }
  2574.  
  2575.     private ScheduledFuture<?> _broadcastCharInfoTask;
  2576.  
  2577.     public class BroadcastCharInfoTask extends RunnableImpl
  2578.     {
  2579.         @Override
  2580.         public void runImpl() throws Exception
  2581.         {
  2582.             broadcastCharInfoImpl();
  2583.             _broadcastCharInfoTask = null;
  2584.         }
  2585.     }
  2586.  
  2587.     @Override
  2588.     public void broadcastCharInfo()
  2589.     {
  2590.         broadcastUserInfo(false);
  2591.     }
  2592.  
  2593.     /**
  2594.      * ОтправлÑ�ет UserInfo даному игроку и CIPacket вÑ�ем окружающим.<BR><BR>
  2595.      * <p/>
  2596.      * <B><U> Концепт</U> :</B><BR><BR>
  2597.      * Сервер шлет игроку UserInfo.
  2598.      * Сервер вызывает метод {@link Creature#broadcastPacketToOthers(L2GameServerPacket...)} длÑ� раÑ�Ñ�ылки CIPacket<BR><BR>
  2599.      * <p/>
  2600.      * <B><U> ДейÑ�твиÑ�</U> :</B><BR><BR>
  2601.      * <li>ОтÑ�ылка игроку UserInfo(личные и общие данные)</li>
  2602.      * <li>ОтÑ�ылка другим игрокам CIPacket(Public data only)</li><BR><BR>
  2603.      * <p/>
  2604.      * <FONT COLOR=#FF0000><B> <U>Внимание</U> : Ð�Е ПОСЫЛÐ�ЙТЕ UserInfo другим игрокам либо CIPacket даному игроку.<BR>
  2605.      * Ð�Е ВЫЗЫВÐ�ЕЙТЕ ЭТОТ МЕТОД КРОМЕ ОСОБЫХ ОБСТОЯТЕЛЬСТВ(Ñ�мена Ñ�абклаÑ�Ñ�а к примеру)!!! Траффик дико кушаетÑ�Ñ� у игроков и начинаютÑ�Ñ� лаги.<br>
  2606.      * ИÑ�пользуйте метод {@link Player#sendChanges()}</B></FONT><BR><BR>
  2607.      */
  2608.     public void broadcastUserInfo(boolean force)
  2609.     {
  2610.         sendUserInfo(force);
  2611.  
  2612.         if(!isVisible())
  2613.             return;
  2614.  
  2615.         if(Config.BROADCAST_CHAR_INFO_INTERVAL == 0)
  2616.             force = true;
  2617.  
  2618.         if(force)
  2619.         {
  2620.             if(_broadcastCharInfoTask != null)
  2621.             {
  2622.                 _broadcastCharInfoTask.cancel(false);
  2623.                 _broadcastCharInfoTask = null;
  2624.             }
  2625.             broadcastCharInfoImpl();
  2626.             return;
  2627.         }
  2628.  
  2629.         if(_broadcastCharInfoTask != null)
  2630.             return;
  2631.  
  2632.         _broadcastCharInfoTask = ThreadPoolManager.getInstance().schedule(new BroadcastCharInfoTask(), Config.BROADCAST_CHAR_INFO_INTERVAL);
  2633.     }
  2634.  
  2635.     private int _polyNpcId;
  2636.  
  2637.     public void setPolyId(int polyid)
  2638.     {
  2639.         _polyNpcId = polyid;
  2640.  
  2641.         teleToLocation(getLoc());
  2642.         broadcastUserInfo(true);
  2643.     }
  2644.  
  2645.     public boolean isPolymorphed()
  2646.     {
  2647.         return _polyNpcId != 0;
  2648.     }
  2649.  
  2650.     public int getPolyId()
  2651.     {
  2652.         return _polyNpcId;
  2653.     }
  2654.  
  2655.     @Override
  2656.     public void broadcastCharInfoImpl(IUpdateTypeComponent... components)
  2657.     {
  2658.         if(!isVisible())
  2659.             return;
  2660.  
  2661.         for(Player target : World.getAroundObservers(this))
  2662.         {
  2663.             if(isInvisible(target))
  2664.                 continue;
  2665.    
  2666.             target.sendPacket(isPolymorphed() ? new NpcInfoPoly(this) : new CIPacket(this, target));
  2667.             target.sendPacket(new RelationChangedPacket(this, target));
  2668.         }
  2669.     }
  2670.  
  2671.     public void sendEtcStatusUpdate()
  2672.     {
  2673.         if(!isVisible())
  2674.             return;
  2675.  
  2676.         sendPacket(new EtcStatusUpdatePacket(this));
  2677.     }
  2678.  
  2679.     private Future<?> _userInfoTask;
  2680.  
  2681.     private class UserInfoTask extends RunnableImpl
  2682.     {
  2683.         @Override
  2684.         public void runImpl() throws Exception
  2685.         {
  2686.             sendUserInfoImpl();
  2687.             _userInfoTask = null;
  2688.         }
  2689.     }
  2690.  
  2691.     private void sendUserInfoImpl()
  2692.     {
  2693.         sendPacket(new UIPacket(this));
  2694.     }
  2695.  
  2696.     public void sendUserInfo()
  2697.     {
  2698.         sendUserInfo(false);
  2699.     }
  2700.  
  2701.     public void sendUserInfo(boolean force)
  2702.     {
  2703.         if(!isVisible() || entering || isLogoutStarted() || isFakePlayer())
  2704.             return;
  2705.  
  2706.         if(Config.USER_INFO_INTERVAL == 0 || force)
  2707.         {
  2708.             if(_userInfoTask != null)
  2709.             {
  2710.                 _userInfoTask.cancel(false);
  2711.                 _userInfoTask = null;
  2712.             }
  2713.             sendUserInfoImpl();
  2714.             return;
  2715.         }
  2716.  
  2717.         if(_userInfoTask != null)
  2718.             return;
  2719.  
  2720.         _userInfoTask = ThreadPoolManager.getInstance().schedule(new UserInfoTask(), Config.USER_INFO_INTERVAL);
  2721.     }
  2722.  
  2723.     public void sendSkillList(int learnedSkillId)
  2724.     {
  2725.         sendPacket(new SkillListPacket(this, learnedSkillId));
  2726.         sendPacket(new AcquireSkillListPacket(this));
  2727.     }
  2728.  
  2729.     public void sendSkillList()
  2730.     {
  2731.         sendSkillList(0);
  2732.     }
  2733.  
  2734.     public void updateSkillShortcuts(int skillId, int skillLevel)
  2735.     {
  2736.         for(ShortCut sc : getAllShortCuts())
  2737.         {
  2738.             if(sc.getId() == skillId && sc.getType() == ShortCut.TYPE_SKILL)
  2739.             {
  2740.                 ShortCut newsc = new ShortCut(sc.getSlot(), sc.getPage(), sc.getType(), sc.getId(), skillLevel, 1);
  2741.                 sendPacket(new ShortCutRegisterPacket(this, newsc));
  2742.                 registerShortCut(newsc);
  2743.             }
  2744.         }
  2745.     }
  2746.  
  2747.     @Override
  2748.     public StatusUpdatePacket makeStatusUpdate(Creature caster, int... fields)
  2749.     {
  2750.         StatusUpdatePacket su = new StatusUpdatePacket(this, caster);
  2751.         for(int field : fields)
  2752.             switch(field)
  2753.             {
  2754.                 case StatusUpdatePacket.CUR_HP:
  2755.                     su.addAttribute(field, (int) getCurrentHp());
  2756.                     break;
  2757.                 case StatusUpdatePacket.MAX_HP:
  2758.                     su.addAttribute(field, getMaxHp());
  2759.                     break;
  2760.                 case StatusUpdatePacket.CUR_MP:
  2761.                     su.addAttribute(field, (int) getCurrentMp());
  2762.                     break;
  2763.                 case StatusUpdatePacket.MAX_MP:
  2764.                     su.addAttribute(field, getMaxMp());
  2765.                     break;
  2766.                 case StatusUpdatePacket.CUR_LOAD:
  2767.                     su.addAttribute(field, getCurrentLoad());
  2768.                     break;
  2769.                 case StatusUpdatePacket.MAX_LOAD:
  2770.                     su.addAttribute(field, getMaxLoad());
  2771.                     break;
  2772.                 case StatusUpdatePacket.PVP_FLAG:
  2773.                     su.addAttribute(field, getPvpFlag());
  2774.                     break;
  2775.                 case StatusUpdatePacket.KARMA:
  2776.                     su.addAttribute(field, getKarma());
  2777.                     break;
  2778.                 case StatusUpdatePacket.CUR_CP:
  2779.                     su.addAttribute(field, (int) getCurrentCp());
  2780.                     break;
  2781.                 case StatusUpdatePacket.MAX_CP:
  2782.                     su.addAttribute(field, getMaxCp());
  2783.                     break;
  2784.             }
  2785.         return su;
  2786.     }
  2787.  
  2788.     public void sendStatusUpdate(boolean broadCast, boolean withPet, int... fields)
  2789.     {
  2790.         if(fields.length == 0 || entering && !broadCast)
  2791.             return;
  2792.  
  2793.         StatusUpdatePacket su = makeStatusUpdate(null, fields);
  2794.         if(!su.hasAttributes())
  2795.             return;
  2796.  
  2797.         List<L2GameServerPacket> packets = new ArrayList<L2GameServerPacket>(withPet ? 2 : 1);
  2798.         if(withPet)
  2799.         {
  2800.             for(Servitor servitor : getServitors())
  2801.                 packets.add(servitor.makeStatusUpdate(null, fields));
  2802.         }
  2803.  
  2804.         packets.add(su);
  2805.  
  2806.         if(!broadCast)
  2807.             sendPacket(packets);
  2808.         else if(entering)
  2809.             broadcastPacketToOthers(packets);
  2810.         else
  2811.             broadcastPacket(packets);
  2812.     }
  2813.  
  2814.     /**
  2815.      * @return the Alliance Identifier of the L2Player.<BR><BR>
  2816.      */
  2817.     public int getAllyId()
  2818.     {
  2819.         return _clan == null ? 0 : _clan.getAllyId();
  2820.     }
  2821.  
  2822.     @Override
  2823.     public void sendPacket(IBroadcastPacket p)
  2824.     {
  2825.         if(p == null)
  2826.             return;
  2827.  
  2828.         if(isPacketIgnored(p))
  2829.             return;
  2830.  
  2831.         GameClient connection = getNetConnection();
  2832.         if(connection != null && connection.isConnected())
  2833.             _connection.sendPacket(p.packet(this));
  2834.     }
  2835.  
  2836.     @Override
  2837.     public void sendPacket(IBroadcastPacket... packets)
  2838.     {
  2839.         for(IBroadcastPacket p : packets)
  2840.             sendPacket(p);
  2841.     }
  2842.  
  2843.     @Override
  2844.     public void sendPacket(List<? extends IBroadcastPacket> packets)
  2845.     {
  2846.         for(IBroadcastPacket p : packets)
  2847.             sendPacket(p);
  2848.     }
  2849.  
  2850.     private boolean isPacketIgnored(IBroadcastPacket p)
  2851.     {
  2852.         if(p == null)
  2853.             return true;
  2854.  
  2855.         //if(_notShowTraders && (p.getClass() == PrivateStoreBuyMsg.class || p.getClass() == PrivateStoreMsg.class || p.getClass() == RecipeShopMsgPacket.class))
  2856.         //      return true;
  2857.  
  2858.         return false;
  2859.     }
  2860.  
  2861.     public void doInteract(GameObject target)
  2862.     {
  2863.         if(target == null || isActionsDisabled())
  2864.         {
  2865.             sendActionFailed();
  2866.             return;
  2867.         }
  2868.         if(target.isPlayer())
  2869.         {
  2870.             if(checkInteractionDistance(target))
  2871.             {
  2872.                 Player temp = (Player) target;
  2873.  
  2874.                 if(temp.getPrivateStoreType() == STORE_PRIVATE_SELL || temp.getPrivateStoreType() == STORE_PRIVATE_SELL_PACKAGE)
  2875.                     sendPacket(new PrivateStoreList(this, temp));
  2876.                 else if(temp.getPrivateStoreType() == STORE_PRIVATE_BUY)
  2877.                     sendPacket(new PrivateStoreBuyList(this, temp));
  2878.                 else if(temp.getPrivateStoreType() == STORE_PRIVATE_MANUFACTURE)
  2879.                     sendPacket(new RecipeShopSellListPacket(this, temp));
  2880.                 else if(temp.getPrivateStoreType() == STORE_PRIVATE_BUFF)
  2881.                     OfflineBufferManager.getInstance().processBypass(this, "bufflist_" + temp.getObjectId());
  2882.  
  2883.                 sendActionFailed();
  2884.             }
  2885.             else if(getAI().getIntention() != CtrlIntention.AI_INTENTION_INTERACT)
  2886.                 getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this, null);
  2887.         }
  2888.         else
  2889.             target.onAction(this, false);
  2890.     }
  2891.  
  2892.     public void doAutoLootOrDrop(ItemInstance item, NpcInstance fromNpc)
  2893.     {
  2894.         boolean forceAutoloot = fromNpc.isFlying() || getReflection().isAutolootForced();
  2895.  
  2896.         if((fromNpc.isRaid() || fromNpc instanceof ReflectionBossInstance) && !Config.AUTO_LOOT_FROM_RAIDS && !item.isHerb() && !forceAutoloot)
  2897.         {
  2898.             item.dropToTheGround(this, fromNpc);
  2899.             return;
  2900.         }
  2901.  
  2902.         // Herbs
  2903.         if(item.isHerb())
  2904.         {
  2905.             if(!AutoLootHerbs && !forceAutoloot)
  2906.             {
  2907.                 item.dropToTheGround(this, fromNpc);
  2908.                 return;
  2909.             }
  2910.             for(SkillEntry skillEntry : item.getTemplate().getAttachedSkills())
  2911.             {
  2912.                 altUseSkill(skillEntry.getTemplate(), this);
  2913.  
  2914.                 for(Servitor servitor : getServitors())
  2915.                 {
  2916.                     if(servitor.isSummon() && !servitor.isDead())
  2917.                         servitor.altUseSkill(skillEntry.getTemplate(), servitor);
  2918.                 }
  2919.             }
  2920.             item.deleteMe();
  2921.             return;
  2922.         }
  2923.  
  2924.         if(!forceAutoloot && !(_autoLoot && (Config.AUTO_LOOT_ITEM_ID_LIST.isEmpty() || Config.AUTO_LOOT_ITEM_ID_LIST.contains(item.getItemId()))) && !(_autoLootOnlyAdena && item.getTemplate().isAdena()))
  2925.         {
  2926.             item.dropToTheGround(this, fromNpc);
  2927.             return;
  2928.         }
  2929.  
  2930.         // Check if the L2Player is in a Party
  2931.         if(!isInParty())
  2932.         {
  2933.             if(!pickupItem(item, Log.Pickup))
  2934.             {
  2935.                 item.dropToTheGround(this, fromNpc);
  2936.                 return;
  2937.             }
  2938.         }
  2939.         else
  2940.             getParty().distributeItem(this, item, fromNpc);
  2941.  
  2942.         broadcastPickUpMsg(item);
  2943.     }
  2944.  
  2945.     @Override
  2946.     public void doPickupItem(final GameObject object)
  2947.     {
  2948.         // Check if the L2Object to pick up is a L2ItemInstance
  2949.         if(!object.isItem())
  2950.         {
  2951.             _log.warn("trying to pickup wrong target." + getTarget());
  2952.             return;
  2953.         }
  2954.  
  2955.         sendActionFailed();
  2956.         stopMove();
  2957.  
  2958.         ItemInstance item = (ItemInstance) object;
  2959.  
  2960.         synchronized (item)
  2961.         {
  2962.             if(!item.isVisible())
  2963.                 return;
  2964.  
  2965.             // Check if me not owner of item and, if in party, not in owner party and nonowner pickup delay still active
  2966.             if(!ItemFunctions.checkIfCanPickup(this, item))
  2967.             {
  2968.                 SystemMessage sm;
  2969.                 if(item.getItemId() == 57)
  2970.                 {
  2971.                     sm = new SystemMessage(SystemMessage.YOU_HAVE_FAILED_TO_PICK_UP_S1_ADENA);
  2972.                     sm.addNumber(item.getCount());
  2973.                 }
  2974.                 else
  2975.                 {
  2976.                     sm = new SystemMessage(SystemMessage.YOU_HAVE_FAILED_TO_PICK_UP_S1);
  2977.                     sm.addItemName(item.getItemId());
  2978.                 }
  2979.                 sendPacket(sm);
  2980.                 return;
  2981.             }
  2982.  
  2983.             // Herbs
  2984.             if(item.isHerb())
  2985.             {
  2986.                 for(SkillEntry skillEntry : item.getTemplate().getAttachedSkills())
  2987.                     altUseSkill(skillEntry.getTemplate(), this);
  2988.  
  2989.                 broadcastPacket(new GetItemPacket(item, getObjectId()));
  2990.                 item.deleteMe();
  2991.                 return;
  2992.             }
  2993.  
  2994.             FlagItemAttachment attachment = item.getAttachment() instanceof FlagItemAttachment ? (FlagItemAttachment) item.getAttachment() : null;
  2995.  
  2996.             if(!isInParty() || attachment != null)
  2997.             {
  2998.                 if(pickupItem(item, Log.Pickup))
  2999.                 {
  3000.                     broadcastPacket(new GetItemPacket(item, getObjectId()));
  3001.                     broadcastPickUpMsg(item);
  3002.                     item.pickupMe();
  3003.                 }
  3004.             }
  3005.             else
  3006.                 getParty().distributeItem(this, item, null);
  3007.         }
  3008.     }
  3009.  
  3010.     public boolean pickupItem(ItemInstance item, String log)
  3011.     {
  3012.         PickableAttachment attachment = item.getAttachment() instanceof PickableAttachment ? (PickableAttachment) item.getAttachment() : null;
  3013.  
  3014.         if(!ItemFunctions.canAddItem(this, item))
  3015.             return false;
  3016.  
  3017.         Log.LogItem(this, log, item);
  3018.         sendPacket(SystemMessagePacket.obtainItems(item));
  3019.         getInventory().addItem(item);
  3020.  
  3021.         if(attachment != null)
  3022.             attachment.pickUp(this);
  3023.  
  3024.         getListeners().onPickupItem(item);
  3025.  
  3026.         sendChanges();
  3027.         return true;
  3028.     }
  3029.  
  3030.     public void setNpcTarget(GameObject target)
  3031.     {
  3032.         setTarget(target);
  3033.         if(target == null)
  3034.             return;
  3035.  
  3036.         if(target == getTarget())
  3037.         {
  3038.             if(target.isNpc())
  3039.             {
  3040.                 NpcInstance npc = (NpcInstance) target;
  3041.                 sendPacket(npc.makeStatusUpdate(null, StatusUpdatePacket.CUR_HP, StatusUpdatePacket.MAX_HP));
  3042.                 sendPacket(new ValidateLocationPacket(npc), ActionFailPacket.STATIC);
  3043.             }
  3044.         }
  3045.     }
  3046.  
  3047.     @Override
  3048.     public void setTarget(GameObject newTarget)
  3049.     {
  3050.         // Check if the new target is visible
  3051.         if(newTarget != null && !newTarget.isVisible())
  3052.             newTarget = null;
  3053.  
  3054.         GameObject oldTarget = getTarget();
  3055.  
  3056.         if(oldTarget != null)
  3057.         {
  3058.             if(oldTarget.equals(newTarget))
  3059.                 return;
  3060.  
  3061.             broadcastPacket(new TargetUnselectedPacket(this));
  3062.         }
  3063.  
  3064.         if(newTarget != null)
  3065.         {
  3066.             broadcastTargetSelected(newTarget);
  3067.  
  3068.             if(newTarget.isCreature())
  3069.                 sendPacket(((Creature) newTarget).getAbnormalStatusUpdate());
  3070.         }
  3071.  
  3072.         if(newTarget != null && newTarget != this && getDecoys() != null && !getDecoys().isEmpty() && newTarget.isCreature())
  3073.         {
  3074.             for(DecoyInstance dec : getDecoys())
  3075.             {
  3076.                 if(dec == null)
  3077.                     continue;
  3078.                 if(dec.getAI() == null)
  3079.                 {
  3080.                     _log.info("This decoy has NULL AI");
  3081.                     continue;
  3082.                 }
  3083.                 if(newTarget.isCreature())
  3084.                 {
  3085.                     Creature _nt = (Creature) newTarget;
  3086.                     if(_nt.isInPeaceZone()) //won't attack in peace zone anyone.
  3087.                         continue;
  3088.                 }
  3089.                 dec.getAI().notifyEvent(CtrlEvent.EVT_AGGRESSION, newTarget, 1000);
  3090.                 //dec.getAI().checkAggression(((Creature)newTarget));
  3091.                 //dec.getAI().Attack(newTarget, true, false);
  3092.             }
  3093.         }
  3094.  
  3095.         super.setTarget(newTarget);
  3096.     }
  3097.  
  3098.     public void broadcastTargetSelected(GameObject newTarget)
  3099.     {
  3100.         sendPacket(new MyTargetSelectedPacket(this, newTarget));
  3101.         broadcastPacket(new TargetSelectedPacket(getObjectId(), newTarget.getObjectId(), getLoc()));
  3102.     }
  3103.  
  3104.     /**
  3105.      * @return the active weapon instance (always equipped in the right hand).<BR><BR>
  3106.      */
  3107.     @Override
  3108.     public ItemInstance getActiveWeaponInstance()
  3109.     {
  3110.         return getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
  3111.     }
  3112.  
  3113.     /**
  3114.      * @return the active weapon item (always equipped in the right hand).<BR><BR>
  3115.      */
  3116.     @Override
  3117.     public WeaponTemplate getActiveWeaponTemplate()
  3118.     {
  3119.         final ItemInstance weapon = getActiveWeaponInstance();
  3120.  
  3121.         if(weapon == null)
  3122.             return null;
  3123.  
  3124.         ItemTemplate template = weapon.getTemplate();
  3125.         if(template == null)
  3126.             return null;
  3127.  
  3128.         if(!(template instanceof WeaponTemplate))
  3129.         {
  3130.             _log.warn("Template in active weapon not WeaponTemplate! (Item ID[" + weapon.getItemId() + "])");
  3131.             return null;
  3132.         }
  3133.  
  3134.         return (WeaponTemplate) template;
  3135.     }
  3136.  
  3137.     /**
  3138.      * @return the secondary weapon instance (always equipped in the left hand).<BR><BR>
  3139.      */
  3140.     @Override
  3141.     public ItemInstance getSecondaryWeaponInstance()
  3142.     {
  3143.         return getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
  3144.     }
  3145.  
  3146.     /**
  3147.      * @return the secondary weapon item (always equipped in the left hand) or the fists weapon.<BR><BR>
  3148.      */
  3149.     @Override
  3150.     public WeaponTemplate getSecondaryWeaponTemplate()
  3151.     {
  3152.         final ItemInstance weapon = getSecondaryWeaponInstance();
  3153.  
  3154.         if(weapon == null)
  3155.             return null;
  3156.  
  3157.         final ItemTemplate item = weapon.getTemplate();
  3158.  
  3159.         if(item instanceof WeaponTemplate)
  3160.             return (WeaponTemplate) item;
  3161.  
  3162.         return null;
  3163.     }
  3164.  
  3165.     public ArmorType getWearingArmorType()
  3166.     {
  3167.         final ItemInstance chest = getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST);
  3168.         if(chest == null)
  3169.             return ArmorType.NONE;
  3170.  
  3171.         final ItemType chestItemType = chest.getItemType();
  3172.         if(!(chestItemType instanceof ArmorType))
  3173.             return ArmorType.NONE;
  3174.  
  3175.         final ArmorType chestArmorType = (ArmorType) chestItemType;
  3176.         if(chest.getBodyPart() == ItemTemplate.SLOT_FULL_ARMOR)
  3177.             return chestArmorType;
  3178.  
  3179.         final ItemInstance legs = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LEGS);
  3180.         if(legs == null)
  3181.             return ArmorType.NONE;
  3182.  
  3183.         if(legs.getItemType() != chestArmorType)
  3184.             return ArmorType.NONE;
  3185.  
  3186.         return chestArmorType;
  3187.     }
  3188.  
  3189.     @Override
  3190.     public void reduceCurrentHp(double damage, Creature attacker, Skill skill, boolean awake, boolean standUp, boolean directHp, boolean canReflectAndAbsorb, boolean transferDamage, boolean isDot, boolean sendReceiveMessage, boolean sendGiveMessage, boolean crit, boolean miss, boolean shld)
  3191.     {
  3192.         if(attacker == null || isDead() || (attacker.isDead() && !isDot))
  3193.             return;
  3194.  
  3195.         // 5182 = Blessing of protection, работает еÑ�ли разница уровней больше 10 и не в зоне оÑ�ады
  3196.         if(attacker.isPlayer() && Math.abs(attacker.getLevel() - getLevel()) > 10)
  3197.         {
  3198.             // ПК не может нанеÑ�ти урон чару Ñ� блеÑ�Ñ�ингом
  3199.             if(attacker.isPK() && getAbnormalList().contains(5182) && !isInSiegeZone())
  3200.                 return;
  3201.             // чар Ñ� блеÑ�Ñ�ингом не может нанеÑ�ти урон ПК
  3202.             if(isPK() && attacker.getAbnormalList().contains(5182) && !attacker.isInSiegeZone())
  3203.                 return;
  3204.         }
  3205.  
  3206.         // Reduce the current HP of the L2Player
  3207.         super.reduceCurrentHp(damage, attacker, skill, awake, standUp, directHp, canReflectAndAbsorb, transferDamage, isDot, sendReceiveMessage, sendGiveMessage, crit, miss, shld);
  3208.     }
  3209.  
  3210.     @Override
  3211.     protected void onReduceCurrentHp(double damage, Creature attacker, Skill skill, boolean awake, boolean standUp, boolean directHp, boolean isDot)
  3212.     {
  3213.         if(damage <= 0)
  3214.             return;
  3215.  
  3216.         if(standUp)
  3217.         {
  3218.             standUp();
  3219.             if(isFakeDeath())
  3220.                 breakFakeDeath();
  3221.         }
  3222.  
  3223.         final double originDamage = damage;
  3224.  
  3225.         if(attacker.isPlayable())
  3226.         {
  3227.             if(!directHp && getCurrentCp() > 0)
  3228.             {
  3229.                 double cp = getCurrentCp();
  3230.                 if(cp >= damage)
  3231.                 {
  3232.                     cp -= damage;
  3233.                     damage = 0;
  3234.                 }
  3235.                 else
  3236.                 {
  3237.                     damage -= cp;
  3238.                     cp = 0;
  3239.                 }
  3240.  
  3241.                 setCurrentCp(cp);
  3242.             }
  3243.         }
  3244.  
  3245.         double hp = getCurrentHp();
  3246.  
  3247.         DuelEvent duelEvent = getEvent(DuelEvent.class);
  3248.         if(duelEvent != null)
  3249.         {
  3250.             if(hp - damage <= 1 && !isDeathImmune()) // еÑ�ли хп <= 1 - убит
  3251.             {
  3252.                 setCurrentHp(1, false);
  3253.                 duelEvent.onDie(this);
  3254.                 return;
  3255.             }
  3256.         }
  3257.  
  3258.         if(isInOlympiadMode())
  3259.         {
  3260.             OlympiadGame game = _olympiadGame;
  3261.             if(this != attacker && (skill == null || skill.isOffensive())) // Ñ�читаем дамаг от проÑ�Ñ‚Ñ‹Ñ… ударов и атакующих Ñ�киллов
  3262.                 game.addDamage(this, Math.min(hp, originDamage));
  3263.  
  3264.             if(hp - damage <= 1 && !isDeathImmune()) // еÑ�ли хп <= 1 - убит
  3265.             {
  3266.                 game.setWinner(getOlympiadSide() == 1 ? 2 : 1);
  3267.                 game.endGame(20000, false);
  3268.                 setCurrentHp(1, false);
  3269.                 attacker.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
  3270.                 attacker.sendActionFailed();
  3271.                 return;
  3272.             }
  3273.         }
  3274.  
  3275.         if(calcStat(Stats.RestoreHPGiveDamage) == 1 && Rnd.chance(1))
  3276.             setCurrentHp(getCurrentHp() + getMaxHp() / 10, false);
  3277.  
  3278.         super.onReduceCurrentHp(damage, attacker, skill, awake, standUp, directHp, isDot);
  3279.     }
  3280.  
  3281.     private void altDeathPenalty(final Creature killer)
  3282.     {
  3283.         // Reduce the Experience of the L2Player in function of the calculated Death Penalty
  3284.         if(!Config.ALT_GAME_DELEVEL)
  3285.             return;
  3286.         if(isInZoneBattle())
  3287.             return;
  3288.         deathPenalty(killer);
  3289.     }
  3290.  
  3291.     public final boolean atWarWith(final Player player)
  3292.     {
  3293.         return _clan != null && player.getClan() != null && getPledgeType() != -1 && player.getPledgeType() != -1 && _clan.isAtWarWith(player.getClan().getClanId());
  3294.     }
  3295.  
  3296.     public boolean atMutualWarWith(Player player)
  3297.     {
  3298.         return _clan != null && player.getClan() != null && getPledgeType() != -1 && player.getPledgeType() != -1 && _clan.isAtWarWith(player.getClan().getClanId()) && player.getClan().isAtWarWith(_clan.getClanId());
  3299.     }
  3300.  
  3301.     public final void doPurePk(final Player killer)
  3302.     {
  3303.         // Check if the attacker has a PK counter greater than 0
  3304.         final int pkCountMulti = (int) Math.max(killer.getPkKills() * Config.KARMA_PENALTY_DURATION_INCREASE, 1);
  3305.  
  3306.         // Calculate the level difference Multiplier between attacker and killed L2Player
  3307.         //final int lvlDiffMulti = Math.max(killer.getLevel() / _level, 1);
  3308.  
  3309.         // Calculate the new Karma of the attacker : newKarma = baseKarma*pkCountMulti*lvlDiffMulti
  3310.         // Add karma to attacker and increase its PK counter
  3311.         killer.decreaseKarma(Config.KARMA_MIN_KARMA * pkCountMulti); // * lvlDiffMulti);
  3312.         killer.setPkKills(killer.getPkKills() + 1);
  3313.     }
  3314.  
  3315.     public final void doKillInPeace(final Player killer) // Check if the L2Player killed haven't Karma
  3316.     {
  3317.         if(!isPK())
  3318.             doPurePk(killer);
  3319.         else
  3320.         {
  3321.             String var = PK_KILL_VAR + "_" + getObjectId();
  3322.             if(!killer.getVarBoolean(var))
  3323.             {
  3324.                 // Ð’ течении 30 минут не выдаем карму за убийÑ�тво данного ПК. (TODO: [Bonux] Проверить времÑ� на оффе.)
  3325.                 long expirationTime = System.currentTimeMillis() + (30 * 60 * 1000);
  3326.                 killer.setVar(var, true, expirationTime);
  3327.             }
  3328.         }
  3329.     }
  3330.  
  3331.     public void checkAddItemToDrop(List<ItemInstance> array, List<ItemInstance> items, int maxCount)
  3332.     {
  3333.         for(int i = 0; i < maxCount && !items.isEmpty(); i++)
  3334.             array.add(items.remove(Rnd.get(items.size())));
  3335.     }
  3336.  
  3337.     public FlagItemAttachment getActiveWeaponFlagAttachment()
  3338.     {
  3339.         ItemInstance item = getActiveWeaponInstance();
  3340.         if(item == null || !(item.getAttachment() instanceof FlagItemAttachment))
  3341.             return null;
  3342.         return (FlagItemAttachment) item.getAttachment();
  3343.     }
  3344.  
  3345.     protected void doPKPVPManage(Creature killer)
  3346.     {
  3347.         FlagItemAttachment attachment = getActiveWeaponFlagAttachment();
  3348.         if(attachment != null)
  3349.             attachment.onDeath(this, killer);
  3350.  
  3351.         if(killer == null || isMyServitor(killer.getObjectId()) || killer == this)
  3352.             return;
  3353.  
  3354.         if(killer.isServitor() && (killer = killer.getPlayer()) == null)
  3355.             return;
  3356.  
  3357.         if(killer.isPlayer())
  3358.             PvPRewardManager.tryGiveReward(this, killer.getPlayer());
  3359.  
  3360.         if(isInZoneBattle() || killer.isInZoneBattle())
  3361.             return;
  3362.  
  3363.         if(killer.getTeam() != TeamType.NONE && getTeam() != TeamType.NONE) //in events or duels we don't increase pvp/pk/karma
  3364.             return;
  3365.  
  3366.         // Processing Karma/PKCount/PvPCount for killer
  3367.         if(killer.isPlayer() || killer instanceof FakePlayer) //addon if killer is clone instance should do also this method.
  3368.         {
  3369.             final Player pk = killer.getPlayer();
  3370.             boolean war = atMutualWarWith(pk);
  3371.  
  3372.             //TODO [VISTALL] fix it
  3373.             if(war /*|| _clan.getSiege() != null && _clan.getSiege() == pk.getClan().getSiege() && (_clan.isDefender() && pk.getClan().isAttacker() || _clan.isAttacker() && pk.getClan().isDefender())*/)
  3374.             {
  3375.                 ClanWar clanWar = _clan.getClanWar(pk.getClan());
  3376.                 if(clanWar != null)
  3377.                     clanWar.onKill(pk, this);
  3378.             }
  3379.  
  3380.             if(isInSiegeZone())
  3381.                 return;
  3382.  
  3383.             Castle castle = getCastle();
  3384.             if(getPvpFlag() > 0 || war || castle != null && castle.getResidenceSide() == ResidenceSide.DARK)
  3385.                 pk.setPvpKills(pk.getPvpKills() + 1);
  3386.             else
  3387.                 doKillInPeace(pk);
  3388.  
  3389.             pk.sendChanges();
  3390.         }
  3391.  
  3392.         int karma = _karma;
  3393.         if(isPK())
  3394.         {
  3395.             increaseKarma(Config.KARMA_LOST_BASE);
  3396.             if(_karma > 0)
  3397.                 _karma = 0;
  3398.         }
  3399.  
  3400.         // в нормальных уÑ�ловиÑ�Ñ… вещи терÑ�ÑŽÑ‚Ñ�Ñ� только при Ñ�мерти от гварда или игрока
  3401.         // кроме того, альт на потерю вещей при Ñ�метри позволÑ�ет терÑ�Ñ‚ÑŒ вещи при Ñ�мтери от монÑ�тра
  3402.         boolean isPvP = killer.isPlayable() || killer instanceof GuardInstance;
  3403.  
  3404.         if(isFakePlayer() // еÑ�ли фейк плейер
  3405.                 || killer.isMonster() && !Config.DROP_ITEMS_ON_DIE // еÑ�ли убил монÑ�Ñ‚Ñ€ и альт выключен
  3406.                 || isPvP // еÑ�ли убил игрок или гвард и
  3407.                 && (_pkKills < Config.MIN_PK_TO_ITEMS_DROP // количеÑ�тво пк Ñ�лишком мало
  3408.                 || karma >= 0 && Config.KARMA_NEEDED_TO_DROP) // кармы нет
  3409.                 || !killer.isMonster() && !isPvP) // в прочих Ñ�лучаÑ�Ñ… тоже
  3410.             return;
  3411.  
  3412.         // No drop from GM's
  3413.         if(!Config.KARMA_DROP_GM && isGM())
  3414.             return;
  3415.  
  3416.         final int max_drop_count = isPvP ? Config.KARMA_DROP_ITEM_LIMIT : 1;
  3417.  
  3418.         double dropRate; // базовый шанÑ� в процентах
  3419.         if(isPvP)
  3420.             dropRate = _pkKills * Config.KARMA_DROPCHANCE_MOD + Config.KARMA_DROPCHANCE_BASE;
  3421.         else
  3422.             dropRate = Config.NORMAL_DROPCHANCE_BASE;
  3423.  
  3424.         int dropEquipCount = 0, dropWeaponCount = 0, dropItemCount = 0;
  3425.  
  3426.         for(int i = 0; i < Math.ceil(dropRate / 100) && i < max_drop_count; i++)
  3427.             if(Rnd.chance(dropRate))
  3428.             {
  3429.                 int rand = Rnd.get(Config.DROPCHANCE_EQUIPPED_WEAPON + Config.DROPCHANCE_EQUIPMENT + Config.DROPCHANCE_ITEM) + 1;
  3430.                 if(rand > Config.DROPCHANCE_EQUIPPED_WEAPON + Config.DROPCHANCE_EQUIPMENT)
  3431.                     dropItemCount++;
  3432.                 else if(rand > Config.DROPCHANCE_EQUIPPED_WEAPON)
  3433.                     dropEquipCount++;
  3434.                 else
  3435.                     dropWeaponCount++;
  3436.             }
  3437.  
  3438.         List<ItemInstance> drop = new LazyArrayList<ItemInstance>(), // общий маÑ�Ñ�ив Ñ� результатами выбора
  3439.             dropItem = new LazyArrayList<ItemInstance>(), dropEquip = new LazyArrayList<ItemInstance>(), dropWeapon = new LazyArrayList<ItemInstance>(); // временные
  3440.  
  3441.         getInventory().writeLock();
  3442.         try
  3443.         {
  3444.             for(ItemInstance item : getInventory().getItems())
  3445.             {
  3446.                 if(!item.canBeDropped(this, true) || Config.KARMA_LIST_NONDROPPABLE_ITEMS.contains(item.getItemId()))
  3447.                     continue;
  3448.  
  3449.                 if(item.getTemplate().getType2() == ItemTemplate.TYPE2_WEAPON)
  3450.                     dropWeapon.add(item);
  3451.                 else if(item.getTemplate().getType2() == ItemTemplate.TYPE2_SHIELD_ARMOR || item.getTemplate().getType2() == ItemTemplate.TYPE2_ACCESSORY)
  3452.                     dropEquip.add(item);
  3453.                 else if(item.getTemplate().getType2() == ItemTemplate.TYPE2_OTHER)
  3454.                     dropItem.add(item);
  3455.             }
  3456.  
  3457.             checkAddItemToDrop(drop, dropWeapon, dropWeaponCount);
  3458.             checkAddItemToDrop(drop, dropEquip, dropEquipCount);
  3459.             checkAddItemToDrop(drop, dropItem, dropItemCount);
  3460.  
  3461.             // Dropping items, if present
  3462.             if(drop.isEmpty())
  3463.                 return;
  3464.  
  3465.             for(ItemInstance item : drop)
  3466.             {
  3467.                 if(item.isAugmented() && !Config.ALT_ALLOW_DROP_AUGMENTED)
  3468.                 {
  3469.                     item.setVariationStoneId(0);
  3470.                     item.setVariation1Id(0);
  3471.                     item.setVariation2Id(0);
  3472.                 }
  3473.  
  3474.                 item = getInventory().removeItem(item);
  3475.                 Log.LogItem(this, Log.PvPDrop, item);
  3476.  
  3477.                 if(item.getEnchantLevel() > 0)
  3478.                     sendPacket(new SystemMessage(SystemMessage.DROPPED__S1_S2).addNumber(item.getEnchantLevel()).addItemName(item.getItemId()));
  3479.                 else
  3480.                     sendPacket(new SystemMessage(SystemMessage.YOU_HAVE_DROPPED_S1).addItemName(item.getItemId()));
  3481.  
  3482.                 if(killer.isPlayable() && ((Config.AUTO_LOOT && Config.AUTO_LOOT_PK) || isInFlyingTransform()))
  3483.                 {
  3484.                     killer.getPlayer().getInventory().addItem(item);
  3485.                     Log.LogItem(this, Log.Pickup, item);
  3486.  
  3487.                     killer.getPlayer().sendPacket(SystemMessagePacket.obtainItems(item));
  3488.                 }
  3489.                 else
  3490.                     item.dropToTheGround(this, Location.findAroundPosition(this, Config.KARMA_RANDOM_DROP_LOCATION_LIMIT));
  3491.             }
  3492.         }
  3493.         finally
  3494.         {
  3495.             getInventory().writeUnlock();
  3496.         }
  3497.     }
  3498.  
  3499.     @Override
  3500.     protected void onDeath(Creature killer)
  3501.     {
  3502.         if(isInStoreMode())
  3503.         {
  3504.             setPrivateStoreType(Player.STORE_PRIVATE_NONE);
  3505.             storePrivateStore();
  3506.         }
  3507.         if(isProcessingRequest())
  3508.         {
  3509.             Request request = getRequest();
  3510.             if(isInTrade())
  3511.             {
  3512.                 Player parthner = request.getOtherPlayer(this);
  3513.                 sendPacket(TradeDonePacket.FAIL);
  3514.                 parthner.sendPacket(TradeDonePacket.FAIL);
  3515.             }
  3516.             request.cancel();
  3517.         }
  3518.  
  3519.         setAgathion(0);
  3520.  
  3521.         boolean checkPvp = true;
  3522.         final Player killerPlayer = killer.getPlayer();
  3523.         if(killerPlayer != null)
  3524.         {
  3525.             for(SingleMatchEvent event : getEvents(SingleMatchEvent.class))
  3526.             {
  3527.                 if(!event.canIncreasePvPPKCounter(killerPlayer, this))
  3528.                 {
  3529.                     checkPvp = false;
  3530.                     break;
  3531.                 }
  3532.             }
  3533.         }
  3534.  
  3535.         if(checkPvp)
  3536.         {
  3537.             doPKPVPManage(killer);
  3538.             altDeathPenalty(killer);
  3539.         }
  3540.  
  3541.         setIncreasedForce(0);
  3542.  
  3543.         stopWaterTask();
  3544.  
  3545.         if(!isSalvation() && isInSiegeZone() && isCharmOfCourage())
  3546.         {
  3547.             ask(new ConfirmDlgPacket(SystemMsg.YOUR_CHARM_OF_COURAGE_IS_TRYING_TO_RESURRECT_YOU, 60000), new ReviveAnswerListener(this, 100, false));
  3548.             setCharmOfCourage(false);
  3549.         }
  3550.  
  3551.         for(QuestState qs : getAllQuestsStates())
  3552.             qs.getQuest().notifyTutorialEvent("CE", false, "200", qs);
  3553.  
  3554.         if(isMounted())
  3555.             _mount.onDeath();
  3556.  
  3557.         for(Servitor servitor : getServitors())
  3558.             servitor.notifyMasterDeath();
  3559.  
  3560.         for(ListenerHook hook : getListenerHooks(ListenerHookType.PLAYER_DIE))
  3561.             hook.onPlayerDie(this, killer);
  3562.  
  3563.         for(ListenerHook hook : ListenerHook.getGlobalListenerHooks(ListenerHookType.PLAYER_DIE))
  3564.             hook.onPlayerDie(this, killer);
  3565.            
  3566.         super.onDeath(killer);
  3567.     }
  3568.  
  3569.     public void restoreExp()
  3570.     {
  3571.         restoreExp(100.);
  3572.     }
  3573.  
  3574.     public void restoreExp(double percent)
  3575.     {
  3576.         if(percent == 0)
  3577.             return;
  3578.  
  3579.         long lostexp = 0;
  3580.  
  3581.         String lostexps = getVar("lostexp");
  3582.         if(lostexps != null)
  3583.         {
  3584.             lostexp = Long.parseLong(lostexps);
  3585.             unsetVar("lostexp");
  3586.         }
  3587.  
  3588.         if(lostexp != 0)
  3589.             addExpAndSp((long) (lostexp * percent / 100), 0);
  3590.     }
  3591.  
  3592.     public void deathPenalty(Creature killer)
  3593.     {
  3594.         if(killer == null)
  3595.             return;
  3596.  
  3597.         final boolean atwar = killer.getPlayer() != null && atWarWith(killer.getPlayer());
  3598.  
  3599.         final int level = getLevel();
  3600.  
  3601.         // The death steal you some Exp: 10-40 lvl 8% loose
  3602.         double percentLost = Config.PERCENT_LOST_ON_DEATH[getLevel()];
  3603.         if(isPK())
  3604.             percentLost *= Config.PERCENT_LOST_ON_DEATH_MOD_FOR_PK;
  3605.         else if(isInPeaceZone())
  3606.             percentLost *= Config.PERCENT_LOST_ON_DEATH_MOD_IN_PEACE_ZONE;
  3607.         else
  3608.         {
  3609.             if(atwar) // TODO: Проверить, должен ли влиÑ�Ñ‚ÑŒ данный подификатор на ПК!
  3610.                 percentLost *= Config.PERCENT_LOST_ON_DEATH_MOD_IN_WAR;
  3611.             else if(killer.getPlayer() != null && killer.getPlayer() != this)
  3612.                 percentLost *= Config.PERCENT_LOST_ON_DEATH_MOD_IN_PVP;
  3613.         }
  3614.  
  3615.         if(percentLost <= 0)
  3616.             return;
  3617.  
  3618.         // Calculate the Experience loss
  3619.         long lostexp = (long) ((Experience.getExpForLevel(level + 1) - Experience.getExpForLevel(level)) * percentLost / 100);
  3620.  
  3621.         lostexp = (long) calcStat(Stats.EXP_LOST, lostexp, killer, null);
  3622.  
  3623.         // Ð�а зарегиÑ�трированной оÑ�аде нет потери опыта, на чужой оÑ�аде - как при обычной Ñ�мерти от *моба*
  3624.         if(isInSiegeZone())
  3625.         {
  3626.             SiegeEvent<?, ?> siegeEvent = getEvent(SiegeEvent.class);
  3627.             if(siegeEvent != null)
  3628.                 lostexp = 0;
  3629.  
  3630.             if(siegeEvent != null)
  3631.             {
  3632.                 int syndromeLvl = 0;
  3633.                 for(Abnormal e : getAbnormalList())
  3634.                 {
  3635.                     if(e.getSkill().getId() == Skill.SKILL_BATTLEFIELD_DEATH_SYNDROME)
  3636.                     {
  3637.                         syndromeLvl = e.getSkill().getLevel();
  3638.                         break;
  3639.                     }
  3640.                 }
  3641.    
  3642.                 if(syndromeLvl == 0)
  3643.                 {
  3644.                     Skill skill = SkillHolder.getInstance().getSkill(Skill.SKILL_BATTLEFIELD_DEATH_SYNDROME, 1);
  3645.                     if(skill != null)
  3646.                         skill.getEffects(this, this);
  3647.                 }
  3648.                 else if(syndromeLvl < 5)
  3649.                 {
  3650.                     getAbnormalList().stop(Skill.SKILL_BATTLEFIELD_DEATH_SYNDROME);
  3651.                     Skill skill = SkillHolder.getInstance().getSkill(Skill.SKILL_BATTLEFIELD_DEATH_SYNDROME, syndromeLvl + 1);
  3652.                     skill.getEffects(this, this);
  3653.                 }
  3654.                 else if(syndromeLvl == 5)
  3655.                 {
  3656.                     getAbnormalList().stop(Skill.SKILL_BATTLEFIELD_DEATH_SYNDROME);
  3657.                     Skill skill = SkillHolder.getInstance().getSkill(Skill.SKILL_BATTLEFIELD_DEATH_SYNDROME, 5);
  3658.                     skill.getEffects(this, this);
  3659.                 }
  3660.             }
  3661.         }
  3662.  
  3663.         long before = getExp();
  3664.         addExpAndSp(-lostexp, 0);
  3665.         long lost = before - getExp();
  3666.  
  3667.         if(lost > 0)
  3668.             setVar("lostexp", lost);
  3669.     }
  3670.  
  3671.     public void setRequest(Request transaction)
  3672.     {
  3673.         _request = transaction;
  3674.     }
  3675.  
  3676.     public Request getRequest()
  3677.     {
  3678.         return _request;
  3679.     }
  3680.  
  3681.     /**
  3682.      * Проверка, занÑ�Ñ‚ ли игрок длÑ� ответа на зароÑ�
  3683.      *
  3684.      * @return true, еÑ�ли игрок не может ответить на запроÑ�
  3685.      */
  3686.     public boolean isBusy()
  3687.     {
  3688.         return isProcessingRequest() || isOutOfControl() || isInOlympiadMode() || getTeam() != TeamType.NONE || isInStoreMode() || isInDuel() || getMessageRefusal() || isBlockAll() || isInvisible(null);
  3689.     }
  3690.  
  3691.     public boolean isProcessingRequest()
  3692.     {
  3693.         if(_request == null)
  3694.             return false;
  3695.         if(!_request.isInProgress())
  3696.             return false;
  3697.         return true;
  3698.     }
  3699.  
  3700.     public boolean isInTrade()
  3701.     {
  3702.         return isProcessingRequest() && getRequest().isTypeOf(L2RequestType.TRADE);
  3703.     }
  3704.  
  3705.     public List<L2GameServerPacket> addVisibleObject(GameObject object, Creature dropper)
  3706.     {
  3707.         if(isLogoutStarted() || object == null || object.getObjectId() == getObjectId() || !object.isVisible() || object.isObservePoint())
  3708.             return Collections.emptyList();
  3709.  
  3710.         return object.addPacketList(this, dropper);
  3711.     }
  3712.  
  3713.     @Override
  3714.     public List<L2GameServerPacket> addPacketList(Player forPlayer, Creature dropper)
  3715.     {
  3716.         if(isInvisible(forPlayer) && forPlayer.getObjectId() != getObjectId())
  3717.             return Collections.emptyList();
  3718.  
  3719.         if(isInStoreMode() && forPlayer.getVarBoolean(NO_TRADERS_VAR))
  3720.             return Collections.emptyList();
  3721.  
  3722.         List<L2GameServerPacket> list = new ArrayList<L2GameServerPacket>();
  3723.         if(forPlayer.getObjectId() != getObjectId())
  3724.             list.add(isPolymorphed() ? new NpcInfoPoly(this) : new CIPacket(this, forPlayer));
  3725.  
  3726.         if(isSitting() && _chairObject != null)
  3727.             list.add(new ChairSitPacket(this, _chairObject));
  3728.  
  3729.         if(isInStoreMode())
  3730.             list.add(getPrivateStoreMsgPacket(forPlayer));
  3731.  
  3732.         if(isCastingNow())
  3733.         {
  3734.             Creature castingTarget = getCastingTarget();
  3735.             Skill castingSkill = getCastingSkill();
  3736.             long animationEndTime = getAnimationEndTime();
  3737.             if(castingSkill != null && !castingSkill.isNotBroadcastable() && castingTarget != null && castingTarget.isCreature() && animationEndTime > 0)
  3738.                 list.add(new MagicSkillUse(this, castingTarget, castingSkill.getId(), castingSkill.getLevel(), (int) (animationEndTime - System.currentTimeMillis()), 0));
  3739.         }
  3740.  
  3741.         if(isInCombat())
  3742.             list.add(new AutoAttackStartPacket(getObjectId()));
  3743.  
  3744.         list.add(new RelationChangedPacket(this, forPlayer));
  3745.  
  3746.         if(isInBoat())
  3747.             list.add(getBoat().getOnPacket(this, getInBoatPosition()));
  3748.         else
  3749.         {
  3750.             if(isMoving || isFollow)
  3751.                 list.add(movePacket());
  3752.         }
  3753.  
  3754.         // VISTALL: во времÑ� ездовой транÑ�формы, нужно поÑ�лать второй раз при поÑ�влении обьекта
  3755.         // DS: длÑ� магазина то же Ñ�амое, иначе иногда не виден поÑ�ле входа в игру
  3756.         if(/*isInMountTransform() || */(isInStoreMode() && entering))
  3757.         {
  3758.             list.add(new CIPacket(this, forPlayer));
  3759.             //list.add(new ExBR_ExtraUserInfo(this));
  3760.         }
  3761.  
  3762.         return list;
  3763.     }
  3764.  
  3765.     public List<L2GameServerPacket> removeVisibleObject(GameObject object, List<L2GameServerPacket> list)
  3766.     {
  3767.         if(isLogoutStarted() || object == null || object.getObjectId() == getObjectId() || object.isObservePoint()) // FIXME  || isTeleporting()
  3768.             return Collections.emptyList();
  3769.  
  3770.         List<L2GameServerPacket> result = list == null ? object.deletePacketList(this) : list;
  3771.  
  3772.         if(getParty() != null && object instanceof Creature)
  3773.             getParty().removeTacticalSign((Creature) object);
  3774.  
  3775.         if(!isInObserverMode())
  3776.             getAI().notifyEvent(CtrlEvent.EVT_FORGET_OBJECT, object);
  3777.         return result;
  3778.     }
  3779.  
  3780.     private void levelSet(int levels)
  3781.     {
  3782.         if(levels > 0)
  3783.         {
  3784.             final int level = getLevel();
  3785.  
  3786.             checkLevelUpReward(false);
  3787.  
  3788.             sendPacket(SystemMsg.YOUR_LEVEL_HAS_INCREASED);
  3789.             broadcastPacket(new SocialActionPacket(getObjectId(), SocialActionPacket.LEVEL_UP));
  3790.  
  3791.             setCurrentHpMp(getMaxHp(), getMaxMp());
  3792.             setCurrentCp(getMaxCp());
  3793.  
  3794.             for(QuestState qs : getAllQuestsStates())
  3795.                 qs.getQuest().notifyTutorialEvent("CE", false, "300", qs);
  3796.  
  3797.             // Give Expertise skill of this level
  3798.             rewardSkills(false);
  3799.             notifyNewSkills();
  3800.         }
  3801.         else if(levels < 0)
  3802.             checkSkills();
  3803.  
  3804.         sendUserInfo(true);
  3805.         sendSkillList();
  3806.  
  3807.         // Recalculate the party level
  3808.         if(isInParty())
  3809.             getParty().recalculatePartyData();
  3810.  
  3811.         if(_clan != null)
  3812.             _clan.broadcastToOnlineMembers(new PledgeShowMemberListUpdatePacket(this));
  3813.  
  3814.         if(_matchingRoom != null)
  3815.             _matchingRoom.broadcastPlayerUpdate(this);
  3816.     }
  3817.  
  3818.     public boolean notifyNewSkills()
  3819.     {
  3820.         final Collection<SkillLearn> skills = SkillAcquireHolder.getInstance().getAvailableSkills(this, AcquireType.NORMAL);
  3821.         for(SkillLearn s : skills)
  3822.         {
  3823.             if(s.isFreeAutoGet(AcquireType.NORMAL))
  3824.                 continue;
  3825.  
  3826.             Skill sk = SkillHolder.getInstance().getSkill(s.getId(), s.getLevel());
  3827.             if(sk == null)
  3828.                 continue;
  3829.  
  3830.             sendPacket(ExNewSkillToLearnByLevelUp.STATIC);
  3831.             return true;
  3832.         }
  3833.         return false;
  3834.     }
  3835.  
  3836.     /**
  3837.      * УдалÑ�ет вÑ�е Ñ�киллы, которые учатÑ�Ñ� на уровне большем, чем текущий+maxDiff
  3838.      */
  3839.     public boolean checkSkills()
  3840.     {
  3841.         boolean update = false;
  3842.         for(SkillEntry sk : getAllSkillsArray())
  3843.         {
  3844.             if(SkillUtils.checkSkill(this, sk))
  3845.                 update = true;
  3846.         }
  3847.         return update;
  3848.     }
  3849.  
  3850.     public void startTimers()
  3851.     {
  3852.         startAutoSaveTask();
  3853.         startPcBangPointsTask();
  3854.         startPremiumAccountTask();
  3855.         getInventory().startTimers();
  3856.         resumeQuestTimers();
  3857.         getAttendanceRewards().startTasks();
  3858.     }
  3859.  
  3860.     public void stopAllTimers()
  3861.     {
  3862.         setAgathion(0);
  3863.         stopWaterTask();
  3864.         stopPremiumAccountTask();
  3865.         stopHourlyTask();
  3866.         stopKickTask();
  3867.         stopPcBangPointsTask();
  3868.         stopTrainingCampTask();
  3869.         stopAutoSaveTask();
  3870.         getInventory().stopAllTimers();
  3871.         stopQuestTimers();
  3872.         stopEnableUserRelationTask();
  3873.         getHennaList().stopHennaRemoveTask();
  3874.         getAttendanceRewards().stopTasks();
  3875.     }
  3876.  
  3877.     @Override
  3878.     public boolean isMyServitor(int objId)
  3879.     {
  3880.         if(_summon != null && _summon.getObjectId() == objId)
  3881.             return true;
  3882.  
  3883.         if(_pet != null && _pet.getObjectId() == objId)
  3884.             return true;
  3885.  
  3886.         return false;
  3887.     }
  3888.  
  3889.     public int getServitorsCount()
  3890.     {
  3891.         int count = 0;
  3892.         if(_summon != null)
  3893.             count++;
  3894.         if(_pet != null)
  3895.             count++;
  3896.         return count;
  3897.     }
  3898.  
  3899.     public boolean hasServitor()
  3900.     {
  3901.         return getServitorsCount() > 0;
  3902.     }
  3903.  
  3904.     @Override
  3905.     public List<Servitor> getServitors()
  3906.     {
  3907.         List<Servitor> servitors = new ArrayList<Servitor>();
  3908.         if(_summon != null)
  3909.             servitors.add(_summon);
  3910.  
  3911.         if(_pet != null)
  3912.             servitors.add(_pet);
  3913.  
  3914.         Collections.sort(servitors, Servitor.ServitorComparator.getInstance());
  3915.         return servitors;
  3916.     }
  3917.  
  3918.     public Servitor getAnyServitor()
  3919.     {
  3920.         return getServitors().stream().findAny().orElse(null);
  3921.     }
  3922.  
  3923.     public Servitor getFirstServitor()
  3924.     {
  3925.         return getServitors().stream().findFirst().orElse(null);
  3926.     }
  3927.  
  3928.     public Servitor getServitor(int objId)
  3929.     {
  3930.         if(_summon != null && _summon.getObjectId() == objId)
  3931.             return _summon;
  3932.         if(_pet != null && _pet.getObjectId() == objId)
  3933.             return _pet;
  3934.  
  3935.         return null;
  3936.     }
  3937.  
  3938.     public boolean hasSummon()
  3939.     {
  3940.         return _summon != null;
  3941.     }
  3942.  
  3943.     public SummonInstance getSummon()
  3944.     {
  3945.         return _summon;
  3946.     }
  3947.  
  3948.     public void setSummon(SummonInstance summon)
  3949.     {
  3950.         if(_summon == summon)
  3951.             return;
  3952.  
  3953.         _summon = summon;
  3954.         if(_summon == null && _pet == null)
  3955.         {
  3956.             removeAutoShot(SoulShotType.BEAST_SOULSHOT);
  3957.             removeAutoShot(SoulShotType.BEAST_SPIRITSHOT);
  3958.         }
  3959.  
  3960.         autoShot();
  3961.         if(summon == null)
  3962.             getAbnormalList().stop(4140); //TODO: [Bonux] Ð�ужно ли у петов?
  3963.     }
  3964.  
  3965.     public void deleteServitor(int objId)
  3966.     {
  3967.         if(_summon != null && _summon.getObjectId() == objId)
  3968.             setSummon(null);
  3969.         else if(_pet != null && _pet.getObjectId() == objId)
  3970.             setPet(null);
  3971.     }
  3972.  
  3973.     public PetInstance getPet()
  3974.     {
  3975.         return _pet;
  3976.     }
  3977.  
  3978.     public void setPet(PetInstance pet)
  3979.     {
  3980.         boolean petDeleted = _pet != null;
  3981.         _pet = pet;
  3982.         unsetVar("pet");
  3983.  
  3984.         if(pet == null)
  3985.         {
  3986.             if(petDeleted)
  3987.             {
  3988.                 if(isLogoutStarted())
  3989.                 {
  3990.                     if(getPetControlItem() != null)
  3991.                         setVar("pet", getPetControlItem().getObjectId());
  3992.                 }
  3993.                 setPetControlItem(null);
  3994.                 if(_summon == null && _pet == null)
  3995.                 {
  3996.                     removeAutoShot(SoulShotType.BEAST_SOULSHOT);
  3997.                     removeAutoShot(SoulShotType.BEAST_SPIRITSHOT);
  3998.                 }
  3999.             }
  4000.             getAbnormalList().stop(4140);
  4001.         }
  4002.         autoShot();
  4003.     }
  4004.  
  4005.     public void scheduleDelete()
  4006.     {
  4007.         long time = 0L;
  4008.  
  4009.         if(Config.SERVICES_ENABLE_NO_CARRIER)
  4010.             time = NumberUtils.toInt(getVar("noCarrier"), Config.SERVICES_NO_CARRIER_DEFAULT_TIME);
  4011.  
  4012.         scheduleDelete(time * 1000L);
  4013.     }
  4014.  
  4015.     /**
  4016.      * Удалит перÑ�онажа из мира через указанное времÑ�, еÑ�ли на момент иÑ�течениÑ� времени он не будет приÑ�оединен.
  4017.      * <br><br>
  4018.      * TODO: через минуту делать его неуÑ�звимым.<br>
  4019.      * TODO: Ñ�делать привÑ�зку времени к контекÑ�ту, длÑ� зон Ñ� лимитом времени оÑ�тавлÑ�Ñ‚ÑŒ в игре на вÑ�е времÑ� в зоне.<br>
  4020.      * <br>
  4021.      *
  4022.      * @param time времÑ� в миллиÑ�екундах
  4023.      */
  4024.     public void scheduleDelete(long time)
  4025.     {
  4026.         if(isLogoutStarted() || isInOfflineMode())
  4027.             return;
  4028.  
  4029.         broadcastCharInfo();
  4030.  
  4031.         ThreadPoolManager.getInstance().schedule(() ->
  4032.         {
  4033.             if(!isConnected())
  4034.             {
  4035.                 prepareToLogout1();
  4036.                 prepareToLogout2();
  4037.                 deleteMe();
  4038.             }
  4039.         }, time);
  4040.     }
  4041.  
  4042.     @Override
  4043.     protected void onDelete()
  4044.     {
  4045.         deleteCubics();
  4046.         super.onDelete();
  4047.  
  4048.         // Убираем Ñ„Ñ�йк в точке наблюдениÑ�
  4049.         if(_observePoint != null)
  4050.             _observePoint.deleteMe();
  4051.  
  4052.         //Send friendlists to friends that this player has logged off
  4053.         _friendList.notifyFriends(false);
  4054.  
  4055.         getBookMarkList().clear();
  4056.  
  4057.         _inventory.clear();
  4058.         _warehouse.clear();
  4059.         _summon = null;
  4060.         _pet = null;
  4061.         _arrowItem = null;
  4062.         _fistsWeaponItem = null;
  4063.         _chars = null;
  4064.         _enchantScroll = null;
  4065.         _lastNpc = HardReferences.emptyRef();
  4066.         _observePoint = null;
  4067.     }
  4068.  
  4069.     public void setTradeList(List<TradeItem> list)
  4070.     {
  4071.         _tradeList = list;
  4072.     }
  4073.  
  4074.     public List<TradeItem> getTradeList()
  4075.     {
  4076.         return _tradeList;
  4077.     }
  4078.  
  4079.     public String getSellStoreName()
  4080.     {
  4081.         return _sellStoreName;
  4082.     }
  4083.  
  4084.     public void setSellStoreName(String name)
  4085.     {
  4086.         _sellStoreName = Strings.stripToSingleLine(name);
  4087.     }
  4088.  
  4089.     public String getPackageSellStoreName()
  4090.     {
  4091.         return _packageSellStoreName;
  4092.     }
  4093.  
  4094.     public void setPackageSellStoreName(String name)
  4095.     {
  4096.         _packageSellStoreName = Strings.stripToSingleLine(name);
  4097.     }
  4098.  
  4099.     public void setSellList(boolean packageSell, List<TradeItem> list)
  4100.     {
  4101.         if(packageSell)
  4102.             _packageSellList = list;
  4103.         else
  4104.             _sellList = list;
  4105.     }
  4106.  
  4107.     public List<TradeItem> getSellList()
  4108.     {
  4109.         return getSellList(_privatestore == STORE_PRIVATE_SELL_PACKAGE);
  4110.     }
  4111.  
  4112.     public List<TradeItem> getSellList(boolean packageSell)
  4113.     {
  4114.         return packageSell ? _packageSellList : _sellList;
  4115.     }
  4116.  
  4117.     public String getBuyStoreName()
  4118.     {
  4119.         return _buyStoreName;
  4120.     }
  4121.  
  4122.     public void setBuyStoreName(String name)
  4123.     {
  4124.         _buyStoreName = Strings.stripToSingleLine(name);
  4125.     }
  4126.  
  4127.     public void setBuyList(List<TradeItem> list)
  4128.     {
  4129.         _buyList = list;
  4130.     }
  4131.  
  4132.     public List<TradeItem> getBuyList()
  4133.     {
  4134.         return _buyList;
  4135.     }
  4136.  
  4137.     public void setManufactureName(String name)
  4138.     {
  4139.         _manufactureName = Strings.stripToSingleLine(name);
  4140.     }
  4141.  
  4142.     public String getManufactureName()
  4143.     {
  4144.         return _manufactureName;
  4145.     }
  4146.  
  4147.     public List<ManufactureItem> getCreateList()
  4148.     {
  4149.         return _createList;
  4150.     }
  4151.  
  4152.     public void setCreateList(List<ManufactureItem> list)
  4153.     {
  4154.         _createList = list;
  4155.     }
  4156.  
  4157.     public void setPrivateStoreType(final int type)
  4158.     {
  4159.         _privatestore = type;
  4160.     }
  4161.  
  4162.     public boolean isInStoreMode()
  4163.     {
  4164.         return _privatestore != STORE_PRIVATE_NONE;
  4165.     }
  4166.  
  4167.     public boolean isInBuffStore()
  4168.     {
  4169.         return _privatestore == STORE_PRIVATE_BUFF;
  4170.     }
  4171.  
  4172.     public int getPrivateStoreType()
  4173.     {
  4174.         return _privatestore;
  4175.     }
  4176.  
  4177.     public L2GameServerPacket getPrivateStoreMsgPacket(Player forPlayer)
  4178.     {
  4179.         switch(getPrivateStoreType())
  4180.         {
  4181.             case STORE_PRIVATE_BUY:
  4182.                 return new PrivateStoreBuyMsg(this, canTalkWith(forPlayer));
  4183.             case STORE_PRIVATE_SELL:
  4184.                 return new PrivateStoreMsg(this, canTalkWith(forPlayer));
  4185.             case STORE_PRIVATE_SELL_PACKAGE:
  4186.                 return new ExPrivateStoreWholeMsg(this, canTalkWith(forPlayer));
  4187.             case STORE_PRIVATE_MANUFACTURE:
  4188.                 return new RecipeShopMsgPacket(this, canTalkWith(forPlayer));
  4189.         }
  4190.  
  4191.         return null;
  4192.     }
  4193.  
  4194.     public void broadcastPrivateStoreInfo()
  4195.     {
  4196.         if(!isVisible() || _privatestore == STORE_PRIVATE_NONE)
  4197.             return;
  4198.  
  4199.         sendPacket(getPrivateStoreMsgPacket(this));
  4200.         for(Player target : World.getAroundObservers(this))
  4201.             target.sendPacket(getPrivateStoreMsgPacket(target));
  4202.     }
  4203.  
  4204.     /**
  4205.      * Set the _clan object, _clanId, _clanLeader Flag and title of the L2Player.<BR><BR>
  4206.      *
  4207.      * @param clan the clat to set
  4208.      */
  4209.     public void setClan(Clan clan)
  4210.     {
  4211.         if(_clan != clan && _clan != null)
  4212.             unsetVar("canWhWithdraw");
  4213.  
  4214.         Clan oldClan = _clan;
  4215.         if(oldClan != null && clan == null)
  4216.             for(SkillEntry skillEntry : oldClan.getAllSkills())
  4217.                 removeSkill(skillEntry, false);
  4218.  
  4219.         _clan = clan;
  4220.  
  4221.         if(clan == null)
  4222.         {
  4223.             _pledgeType = Clan.SUBUNIT_NONE;
  4224.             _pledgeRank = PledgeRank.VAGABOND;
  4225.             _powerGrade = 0;
  4226.             _apprentice = 0;
  4227.             _lvlJoinedAcademy = 0;
  4228.             getInventory().validateItems();
  4229.             return;
  4230.         }
  4231.  
  4232.         if(!clan.isAnyMember(getObjectId()))
  4233.         {
  4234.             setClan(null);
  4235.             setTitle("");
  4236.         }
  4237.     }
  4238.  
  4239.     @Override
  4240.     public Clan getClan()
  4241.     {
  4242.         return _clan;
  4243.     }
  4244.  
  4245.     public SubUnit getSubUnit()
  4246.     {
  4247.         return _clan == null ? null : _clan.getSubUnit(_pledgeType);
  4248.     }
  4249.  
  4250.     public ClanHall getClanHall()
  4251.     {
  4252.         int id = _clan != null ? _clan.getHasHideout() : 0;
  4253.         return ResidenceHolder.getInstance().getResidence(ClanHall.class, id);
  4254.     }
  4255.  
  4256.     public Castle getCastle()
  4257.     {
  4258.         int id = _clan != null ? _clan.getCastle() : 0;
  4259.         return ResidenceHolder.getInstance().getResidence(Castle.class, id);
  4260.     }
  4261.  
  4262.     public Alliance getAlliance()
  4263.     {
  4264.         return _clan == null ? null : _clan.getAlliance();
  4265.     }
  4266.  
  4267.     public boolean isClanLeader()
  4268.     {
  4269.         return _clan != null && getObjectId() == _clan.getLeaderId();
  4270.     }
  4271.  
  4272.     public boolean isAllyLeader()
  4273.     {
  4274.         return getAlliance() != null && getAlliance().getLeader().getLeaderId() == getObjectId();
  4275.     }
  4276.  
  4277.     @Override
  4278.     public void reduceArrowCount()
  4279.     {
  4280.         if(_arrowItem != null && _arrowItem.getTemplate().isQuiver())
  4281.             return;
  4282.  
  4283.         sendPacket(SystemMsg.YOU_CAREFULLY_NOCK_AN_ARROW);
  4284.         if(!getInventory().destroyItemByObjectId(getInventory().getPaperdollObjectId(Inventory.PAPERDOLL_LHAND), 1L))
  4285.         {
  4286.             getInventory().setPaperdollItem(Inventory.PAPERDOLL_LHAND, null);
  4287.             _arrowItem = null;
  4288.         }
  4289.     }
  4290.  
  4291.     /**
  4292.      * Equip arrows needed in left hand and send a Server->Client packet ItemListPacket to the L2Player then return True.
  4293.      */
  4294.     public boolean checkAndEquipArrows()
  4295.     {
  4296.         // Check if nothing is equipped in left hand
  4297.         if(getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND) == null)
  4298.         {
  4299.             ItemInstance activeWeapon = getActiveWeaponInstance();
  4300.             if(activeWeapon != null)
  4301.             {
  4302.                 if(activeWeapon.getItemType() == WeaponType.BOW)
  4303.                     _arrowItem = getInventory().findArrowForBow(activeWeapon.getTemplate());
  4304.                 else if(activeWeapon.getItemType() == WeaponType.CROSSBOW || activeWeapon.getItemType() == WeaponType.TWOHANDCROSSBOW)
  4305.                     _arrowItem = getInventory().findArrowForCrossbow(activeWeapon.getTemplate());
  4306.             }
  4307.  
  4308.             // Equip arrows needed in left hand
  4309.             if(_arrowItem != null)
  4310.                 getInventory().setPaperdollItem(Inventory.PAPERDOLL_LHAND, _arrowItem);
  4311.         }
  4312.         else
  4313.             // Get the L2ItemInstance of arrows equipped in left hand
  4314.             _arrowItem = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
  4315.  
  4316.         return _arrowItem != null;
  4317.     }
  4318.  
  4319.     public void setUptime(final long time)
  4320.     {
  4321.         _uptime = time;
  4322.     }
  4323.  
  4324.     public long getUptime()
  4325.     {
  4326.         return System.currentTimeMillis() - _uptime;
  4327.     }
  4328.  
  4329.     public boolean isInParty()
  4330.     {
  4331.         return _party != null;
  4332.     }
  4333.  
  4334.     public void setParty(final Party party)
  4335.     {
  4336.         _party = party;
  4337.     }
  4338.  
  4339.     public void joinParty(final Party party)
  4340.     {
  4341.         if(party != null)
  4342.             party.addPartyMember(this);
  4343.     }
  4344.  
  4345.     public void leaveParty()
  4346.     {
  4347.         if(isInParty())
  4348.             _party.removePartyMember(this, false);
  4349.     }
  4350.  
  4351.     public Party getParty()
  4352.     {
  4353.         return _party;
  4354.     }
  4355.  
  4356.     public void setLastPartyPosition(Location loc)
  4357.     {
  4358.         _lastPartyPosition = loc;
  4359.     }
  4360.  
  4361.     public Location getLastPartyPosition()
  4362.     {
  4363.         return _lastPartyPosition;
  4364.     }
  4365.  
  4366.     public boolean isGM()
  4367.     {
  4368.         return _playerAccess == null ? false : _playerAccess.IsGM;
  4369.     }
  4370.  
  4371.     /**
  4372.      * Ð�игде не иÑ�пользуетÑ�Ñ�, но может пригодитьÑ�Ñ� длÑ� БД
  4373.      */
  4374.     public void setAccessLevel(final int level)
  4375.     {
  4376.         _accessLevel = level;
  4377.     }
  4378.  
  4379.     /**
  4380.      * Ð�игде не иÑ�пользуетÑ�Ñ�, но может пригодитьÑ�Ñ� длÑ� БД
  4381.      */
  4382.     @Override
  4383.     public int getAccessLevel()
  4384.     {
  4385.         return _accessLevel;
  4386.     }
  4387.  
  4388.     public void setPlayerAccess(final PlayerAccess pa)
  4389.     {
  4390.         if(pa != null)
  4391.             _playerAccess = pa;
  4392.         else
  4393.             _playerAccess = new PlayerAccess();
  4394.  
  4395.         setAccessLevel(isGM() || _playerAccess.Menu ? 100 : 0);
  4396.     }
  4397.  
  4398.     public PlayerAccess getPlayerAccess()
  4399.     {
  4400.         return _playerAccess;
  4401.     }
  4402.  
  4403.     /**
  4404.      * Update Stats of the L2Player client side by sending Server->Client packet UserInfo/StatusUpdatePacket to this L2Player and CIPacket/StatusUpdatePacket to all players around (broadcast).<BR><BR>
  4405.      */
  4406.     @Override
  4407.     public void updateStats()
  4408.     {
  4409.         if(entering || isLogoutStarted())
  4410.             return;
  4411.  
  4412.         refreshOverloaded();
  4413.         refreshExpertisePenalty();
  4414.         super.updateStats();
  4415.         for(Servitor servitor : getServitors())
  4416.             servitor.updateStats();
  4417.     }
  4418.  
  4419.     @Override
  4420.     public void sendChanges()
  4421.     {
  4422.         if(entering || isLogoutStarted())
  4423.             return;
  4424.         super.sendChanges();
  4425.     }
  4426.  
  4427.     /**
  4428.      * Send a Server->Client StatusUpdatePacket packet with Karma to the L2Player and all L2Player to inform (broadcast).
  4429.      */
  4430.     public void updateKarma(boolean flagChanged)
  4431.     {
  4432.         sendStatusUpdate(true, true, StatusUpdatePacket.KARMA);
  4433.         if(flagChanged)
  4434.             broadcastRelation();
  4435.     }
  4436.  
  4437.     public boolean isOnline()
  4438.     {
  4439.         return _isOnline;
  4440.     }
  4441.  
  4442.     public void setIsOnline(boolean isOnline)
  4443.     {
  4444.         _isOnline = isOnline;
  4445.     }
  4446.  
  4447.     public void setOnlineStatus(boolean isOnline)
  4448.     {
  4449.         _isOnline = isOnline;
  4450.         updateOnlineStatus();
  4451.     }
  4452.  
  4453.     private void updateOnlineStatus()
  4454.     {
  4455.         Connection con = null;
  4456.         PreparedStatement statement = null;
  4457.         try
  4458.         {
  4459.             con = DatabaseFactory.getInstance().getConnection();
  4460.             statement = con.prepareStatement("UPDATE characters SET online=?, lastAccess=? WHERE obj_id=?");
  4461.             statement.setInt(1, isOnline() && !isInOfflineMode() ? 1 : 0);
  4462.             statement.setLong(2, System.currentTimeMillis() / 1000L);
  4463.             statement.setInt(3, getObjectId());
  4464.             statement.execute();
  4465.         }
  4466.         catch(final Exception e)
  4467.         {
  4468.             _log.error("", e);
  4469.         }
  4470.         finally
  4471.         {
  4472.             DbUtils.closeQuietly(con, statement);
  4473.         }
  4474.     }
  4475.  
  4476.     public void decreaseKarma(final long val)
  4477.     {
  4478.         boolean flagChanged = _karma >= 0;
  4479.         long new_karma = _karma - val;
  4480.  
  4481.         if(new_karma < Integer.MIN_VALUE)
  4482.             new_karma = Integer.MIN_VALUE;
  4483.  
  4484.         if(_karma >= 0 && new_karma < 0 && _pvpFlag > 0)
  4485.         {
  4486.             _pvpFlag = 0;
  4487.             if(_PvPRegTask != null)
  4488.             {
  4489.                 _PvPRegTask.cancel(true);
  4490.                 _PvPRegTask = null;
  4491.             }
  4492.             sendStatusUpdate(true, true, StatusUpdatePacket.PVP_FLAG);
  4493.         }
  4494.  
  4495.         setKarma((int) new_karma);
  4496.  
  4497.         updateKarma(flagChanged);
  4498.     }
  4499.  
  4500.     public void increaseKarma(final int val)
  4501.     {
  4502.         boolean flagChanged = _karma < 0;
  4503.         long new_karma = _karma + val;
  4504.         if(new_karma > Integer.MAX_VALUE)
  4505.             new_karma = Integer.MAX_VALUE;
  4506.  
  4507.         setKarma((int) new_karma);
  4508.         if(_karma > 0)
  4509.             updateKarma(flagChanged);
  4510.         else
  4511.             updateKarma(false);
  4512.     }
  4513.  
  4514.     public static Player create(int classId, int sex, String accountName, final String name, final int hairStyle, final int hairColor, final int face)
  4515.     {
  4516.         if(classId < 0 || classId >= ClassId.VALUES.length)
  4517.             return null;
  4518.  
  4519.         ClassId classID = ClassId.VALUES[classId];
  4520.         if(classID.isDummy() || !classID.isOfLevel(ClassLevel.NONE))
  4521.             return null;
  4522.  
  4523.         PlayerTemplate template = PlayerTemplateHolder.getInstance().getPlayerTemplate(classID.getRace(), classID, Sex.VALUES[sex]);
  4524.  
  4525.         // Create a new L2Player with an account name
  4526.         Player player = new Player(IdFactory.getInstance().getNextId(), template, accountName);
  4527.  
  4528.         player.setName(name);
  4529.         player.setTitle("");
  4530.         player.setHairStyle(hairStyle);
  4531.         player.setHairColor(hairColor);
  4532.         player.setFace(face);
  4533.         player.setCreateTime(System.currentTimeMillis());
  4534.  
  4535.         if(Config.PC_BANG_POINTS_BY_ACCOUNT)
  4536.             player.setPcBangPoints(Integer.parseInt(AccountVariablesDAO.getInstance().select(player.getAccountName(), PC_BANG_POINTS_VAR, "0")));
  4537.  
  4538.         // Add the player in the characters table of the database
  4539.         if(!CharacterDAO.getInstance().insert(player))
  4540.             return null;
  4541.  
  4542.         int level = Config.STARTING_LVL;
  4543.         double hp = classID.getBaseHp(level);
  4544.         double mp = classID.getBaseMp(level);
  4545.         double cp = classID.getBaseCp(level);
  4546.         long exp = Experience.getExpForLevel(level);
  4547.         long sp = Config.STARTING_SP;
  4548.         boolean active = true;
  4549.         SubClassType type = SubClassType.BASE_CLASS;
  4550.  
  4551.         // Add the player subclass in the character_subclasses table of the database
  4552.         if(!CharacterSubclassDAO.getInstance().insert(player.getObjectId(), classId, exp, sp, hp, mp, cp, hp, mp, cp, level, active, type))
  4553.             return null;
  4554.  
  4555.         return player;
  4556.     }
  4557.  
  4558.     public static Player restore(final int objectId, boolean fake)
  4559.     {
  4560.         Player player = null;
  4561.         Connection con = null;
  4562.         Statement statement = null;
  4563.         Statement statement2 = null;
  4564.         PreparedStatement statement3 = null;
  4565.         ResultSet rset = null;
  4566.         ResultSet rset2 = null;
  4567.         ResultSet rset3 = null;
  4568.         try
  4569.         {
  4570.             // Retrieve the L2Player from the characters table of the database
  4571.             con = DatabaseFactory.getInstance().getConnection();
  4572.             statement = con.createStatement();
  4573.             statement2 = con.createStatement();
  4574.             rset = statement.executeQuery("SELECT * FROM `characters` WHERE `obj_Id`=" + objectId + " LIMIT 1");
  4575.             rset2 = statement2.executeQuery("SELECT `class_id` FROM `character_subclasses` WHERE `char_obj_id`=" + objectId + " AND `type`=" + SubClassType.BASE_CLASS.ordinal() + " LIMIT 1");
  4576.  
  4577.             if(rset.next() && rset2.next())
  4578.             {
  4579.                 final ClassId classId = ClassId.VALUES[rset2.getInt("class_id")];
  4580.                 final PlayerTemplate template = PlayerTemplateHolder.getInstance().getPlayerTemplate(classId.getRace(), classId, Sex.VALUES[rset.getInt("sex")]);;
  4581.  
  4582.                 if(fake)
  4583.                 {
  4584.                     FakePlayerAITemplate fakeAiTemplate = FakePlayersHolder.getInstance().getAITemplate(classId.getRace(), classId.getType());
  4585.                     if(fakeAiTemplate == null)
  4586.                         return null;
  4587.  
  4588.                     player = new Player(fakeAiTemplate, objectId, template);
  4589.                 }
  4590.                 else
  4591.                     player = new Player(objectId, template);
  4592.  
  4593.                 player.getSubClassList().restore();
  4594.  
  4595.                 player.restoreVariables();
  4596.                 player.loadInstanceReuses();
  4597.                 player.getBookMarkList().setCapacity(rset.getInt("bookmarks"));
  4598.                 player.getBookMarkList().restore();
  4599.                 player.setBotRating(rset.getInt("bot_rating"));
  4600.                 player.getFriendList().restore();
  4601.                 player.getBlockList().restore();
  4602.                 player.getPremiumItemList().restore();
  4603.                 player.getProductHistoryList().restore();
  4604.                 player.setPostFriends(CharacterPostFriendDAO.getInstance().select(player));
  4605.                 CharacterGroupReuseDAO.getInstance().select(player);
  4606.  
  4607.                 player.setLogin(rset.getString("account_name"));
  4608.                 player.setName(rset.getString("char_name"));
  4609.  
  4610.                 player.setFace(rset.getInt("face"));
  4611.                 player.setBeautyFace(rset.getInt("beautyFace"));
  4612.                 player.setHairStyle(rset.getInt("hairStyle"));
  4613.                 player.setBeautyHairStyle(rset.getInt("beautyHairStyle"));
  4614.                 player.setHairColor(rset.getInt("hairColor"));
  4615.                 player.setBeautyHairColor(rset.getInt("beautyHairColor"));
  4616.                 player.setHeading(0);
  4617.  
  4618.                 player.setKarma(rset.getInt("karma"));
  4619.                 player.setPvpKills(rset.getInt("pvpkills"));
  4620.                 player.setPkKills(rset.getInt("pkkills"));
  4621.                 player.setLeaveClanTime(rset.getLong("leaveclan") * 1000L);
  4622.                 if(player.getLeaveClanTime() > 0 && player.canJoinClan())
  4623.                     player.setLeaveClanTime(0);
  4624.                 player.setDeleteClanTime(rset.getLong("deleteclan") * 1000L);
  4625.                 if(player.getDeleteClanTime() > 0 && player.canCreateClan())
  4626.                     player.setDeleteClanTime(0);
  4627.  
  4628.                 player.setNoChannel(rset.getLong("nochannel") * 1000L);
  4629.                 if(player.getNoChannel() > 0 && player.getNoChannelRemained() < 0)
  4630.                     player.setNoChannel(0);
  4631.  
  4632.                 player.setOnlineTime(rset.getLong("onlinetime") * 1000L);
  4633.  
  4634.                 final int clanId = rset.getInt("clanid");
  4635.                 if(clanId > 0)
  4636.                 {
  4637.                     player.setClan(ClanTable.getInstance().getClan(clanId));
  4638.                     player.setPledgeType(rset.getInt("pledge_type"));
  4639.                     player.setPowerGrade(rset.getInt("pledge_rank"));
  4640.                     player.setLvlJoinedAcademy(rset.getInt("lvl_joined_academy"));
  4641.                     player.setApprentice(rset.getInt("apprentice"));
  4642.                 }
  4643.  
  4644.                 player.setCreateTime(rset.getLong("createtime") * 1000L);
  4645.                 player.setDeleteTimer(rset.getInt("deletetime"));
  4646.  
  4647.                 player.setTitle(rset.getString("title"));
  4648.  
  4649.                 if(player.getVar("titlecolor") != null)
  4650.                     player.setTitleColor(Integer.decode("0x" + player.getVar("titlecolor")));
  4651.  
  4652.                 if(player.getVar("namecolor") == null)
  4653.                     if(player.isGM())
  4654.                         player.setNameColor(Config.GM_NAME_COLOUR);
  4655.                     else if(player.getClan() != null && player.getClan().getLeaderId() == player.getObjectId())
  4656.                         player.setNameColor(Config.CLANLEADER_NAME_COLOUR);
  4657.                     else
  4658.                         player.setNameColor(Config.NORMAL_NAME_COLOUR);
  4659.                 else
  4660.                     player.setNameColor(Integer.decode("0x" + player.getVar("namecolor")));
  4661.  
  4662.                 if(Config.AUTO_LOOT_INDIVIDUAL)
  4663.                 {
  4664.                     player._autoLoot = player.getVarBoolean("AutoLoot", Config.AUTO_LOOT);
  4665.                     player._autoLootOnlyAdena = player.getVarBoolean("AutoLootOnlyAdena", Config.AUTO_LOOT);
  4666.                     player.AutoLootHerbs = player.getVarBoolean("AutoLootHerbs", Config.AUTO_LOOT_HERBS);
  4667.                 }
  4668.  
  4669.                 player.setUptime(System.currentTimeMillis());
  4670.                 player.setLastAccess(rset.getLong("lastAccess"));
  4671.  
  4672.                 player.setRecomHave(rset.getInt("rec_have"));
  4673.                 player.setRecomLeft(rset.getInt("rec_left"));
  4674.  
  4675.                 if(!Config.USE_CLIENT_LANG)
  4676.                     player.setLanguage(player.getVar(Language.LANG_VAR));
  4677.  
  4678.                 player.setKeyBindings(rset.getBytes("key_bindings"));
  4679.                 if(Config.PC_BANG_POINTS_BY_ACCOUNT)
  4680.                     player.setPcBangPoints(Integer.parseInt(AccountVariablesDAO.getInstance().select(player.getAccountName(), PC_BANG_POINTS_VAR, "0")));
  4681.                 else
  4682.                     player.setPcBangPoints(rset.getInt("pcBangPoints"));
  4683.  
  4684.                 player.setFame(rset.getInt("fame"), null, false);
  4685.  
  4686.                 player.setUsedWorldChatPoints(rset.getInt("used_world_chat_points"));
  4687.  
  4688.                 player.setHideHeadAccessories(rset.getInt("hide_head_accessories") > 0);
  4689.  
  4690.                 player.restoreRecipeBook();
  4691.  
  4692.                 if(Config.ENABLE_OLYMPIAD)
  4693.                     player.setHero(Hero.getInstance().isHero(player.getObjectId()));
  4694.  
  4695.                 if(!player.isHero())
  4696.                     player.setHero(CustomHeroDAO.getInstance().isCustomHero(player.getObjectId()));
  4697.  
  4698.                 player.updatePledgeRank();
  4699.  
  4700.                 player.setXYZ(rset.getInt("x"), rset.getInt("y"), rset.getInt("z"));
  4701.  
  4702.                 int reflection = 0;
  4703.  
  4704.                 long jailExpireTime = player.getVarExpireTime(JAILED_VAR);
  4705.                 if(jailExpireTime > System.currentTimeMillis())
  4706.                 {
  4707.                     reflection = ReflectionManager.JAIL.getId();
  4708.                     if(!player.isInZone("[gm_prison]"))
  4709.                         player.setLoc(Location.findPointToStay(player, AdminFunctions.JAIL_SPAWN, 50, 200));
  4710.                     player.setIsInJail(true);
  4711.                     player.startUnjailTask(player, (int) (jailExpireTime - System.currentTimeMillis() / 60000));
  4712.                 }
  4713.                 else
  4714.                 {
  4715.                     //ЕÑ�ли игрок вышел во времÑ� прыжка, то возвращаем его в Ñ�табильную точку (Ñ�тартовую).
  4716.                     String jumpSafeLoc = player.getVar("@safe_jump_loc");
  4717.                     if(jumpSafeLoc != null)
  4718.                     {
  4719.                         player.setLoc(Location.parseLoc(jumpSafeLoc));
  4720.                         player.unsetVar("@safe_jump_loc");
  4721.                     }
  4722.  
  4723.                     String ref = player.getVar("reflection");
  4724.                     if(ref != null)
  4725.                     {
  4726.                         reflection = Integer.parseInt(ref);
  4727.                         if(reflection != ReflectionManager.PARNASSUS.getId() && reflection != ReflectionManager.GIRAN_HARBOR.getId()) // не портаем назад из ГХ, парнаÑ�а
  4728.                         {
  4729.                             String back = player.getVar("backCoords");
  4730.                             if(back != null)
  4731.                             {
  4732.                                 player.setLoc(Location.parseLoc(back));
  4733.                                 player.unsetVar("backCoords");
  4734.                             }
  4735.                             reflection = 0;
  4736.                         }
  4737.                     }
  4738.                 }
  4739.  
  4740.                 player.setReflection(reflection);
  4741.  
  4742.                 EventHolder.getInstance().findEvent(player);
  4743.  
  4744.                 //TODO [G1ta0] запуÑ�кать на входе
  4745.                 Quest.restoreQuestStates(player);
  4746.  
  4747.                 player.getInventory().restore();
  4748.  
  4749.                 player.setActiveSubClass(player.getActiveClassId(), false, true);
  4750.  
  4751.                 player.getAttendanceRewards().restore();
  4752.  
  4753.                 player.restoreSummons();
  4754.  
  4755.                 try
  4756.                 {
  4757.                     String var = player.getVar("ExpandInventory");
  4758.                     if(var != null)
  4759.                         player.setExpandInventory(Integer.parseInt(var));
  4760.                 }
  4761.                 catch(Exception e)
  4762.                 {
  4763.                     _log.error("", e);
  4764.                 }
  4765.  
  4766.                 try
  4767.                 {
  4768.                     String var = player.getVar("ExpandWarehouse");
  4769.                     if(var != null)
  4770.                         player.setExpandWarehouse(Integer.parseInt(var));
  4771.                 }
  4772.                 catch(Exception e)
  4773.                 {
  4774.                     _log.error("", e);
  4775.                 }
  4776.  
  4777.                 try
  4778.                 {
  4779.                     String var = player.getVar(NO_ANIMATION_OF_CAST_VAR);
  4780.                     if(var != null)
  4781.                         player.setNotShowBuffAnim(Boolean.parseBoolean(var));
  4782.                 }
  4783.                 catch(Exception e)
  4784.                 {
  4785.                     _log.error("", e);
  4786.                 }
  4787.  
  4788.                 try
  4789.                 {
  4790.                     String var = player.getVar(NO_TRADERS_VAR);
  4791.                     if(var != null)
  4792.                         player.setNotShowTraders(Boolean.parseBoolean(var));
  4793.                 }
  4794.                 catch(Exception e)
  4795.                 {
  4796.                     _log.error("", e);
  4797.                 }
  4798.  
  4799.                 try
  4800.                 {
  4801.                     String var = player.getVar("pet");
  4802.                     if(var != null)
  4803.                         player.setPetControlItem(Integer.parseInt(var));
  4804.                 }
  4805.                 catch(Exception e)
  4806.                 {
  4807.                     _log.error("", e);
  4808.                 }
  4809.  
  4810.                 statement3 = con.prepareStatement("SELECT obj_Id, char_name FROM characters WHERE account_name=? AND obj_Id!=?");
  4811.                 statement3.setString(1, player._login);
  4812.                 statement3.setInt(2, objectId);
  4813.                 rset3 = statement3.executeQuery();
  4814.                 while(rset3.next())
  4815.                 {
  4816.                     final Integer charId = rset3.getInt("obj_Id");
  4817.                     final String charName = rset3.getString("char_name");
  4818.                     player._chars.put(charId, charName);
  4819.                 }
  4820.  
  4821.                 DbUtils.close(statement3, rset3);
  4822.  
  4823.                 //if(!player.isGM())
  4824.                 {
  4825.                     LazyArrayList<Zone> zones = LazyArrayList.newInstance();
  4826.  
  4827.                     World.getZones(zones, player.getLoc(), player.getReflection());
  4828.  
  4829.                     if(!zones.isEmpty())
  4830.                         for(Zone zone : zones)
  4831.                             if(zone.getType() == ZoneType.no_restart)
  4832.                             {
  4833.                                 if(System.currentTimeMillis() / 1000L - player.getLastAccess() > zone.getRestartTime())
  4834.                                 {
  4835.                                     player.sendMessage(new CustomMessage("l2s.gameserver.network.l2.c2s.EnterWorld.TeleportedReasonNoRestart"));
  4836.                                     player.setLoc(TeleportUtils.getRestartPoint(player, RestartType.TO_VILLAGE).getLoc());
  4837.                                 }
  4838.                             }
  4839.                             else if(zone.getType() == ZoneType.SIEGE)
  4840.                             {
  4841.                                 SiegeEvent<?, ?> siegeEvent = player.getEvent(SiegeEvent.class);
  4842.                                 if(siegeEvent != null)
  4843.                                     player.setLoc(siegeEvent.getEnterLoc(player, zone));
  4844.                                 else
  4845.                                 {
  4846.                                     Residence r = ResidenceHolder.getInstance().getResidence(zone.getParams().getInteger("residence"));
  4847.                                     player.setLoc(r.getNotOwnerRestartPoint(player));
  4848.                                 }
  4849.                             }
  4850.  
  4851.                     LazyArrayList.recycle(zones);
  4852.                 }
  4853.  
  4854.                 player.getMacroses().restore();
  4855.  
  4856.                 //FIXME [VISTALL] нужно ли?
  4857.                 player.refreshExpertisePenalty();
  4858.                 player.refreshOverloaded();
  4859.  
  4860.                 player.getWarehouse().restore();
  4861.                 player.getFreight().restore();
  4862.  
  4863.                 player.restorePrivateStore();
  4864.  
  4865.                 player.updateKetraVarka();
  4866.                 player.updateRam();
  4867.                 player.checkDailyCounters();
  4868.                 player.checkWeeklyCounters();
  4869.             }
  4870.         }
  4871.         catch(final Exception e)
  4872.         {
  4873.             _log.error("Could not restore char data!", e);
  4874.         }
  4875.         finally
  4876.         {
  4877.             DbUtils.closeQuietly(statement2, rset2);
  4878.             DbUtils.closeQuietly(statement3, rset3);
  4879.             DbUtils.closeQuietly(con, statement, rset);
  4880.         }
  4881.         return player;
  4882.     }
  4883.  
  4884.     /**
  4885.      * Update L2Player stats in the characters table of the database.
  4886.      */
  4887.     public void store(boolean fast)
  4888.     {
  4889.         if(!_storeLock.tryLock())
  4890.             return;
  4891.  
  4892.         try
  4893.         {
  4894.             Connection con = null;
  4895.             PreparedStatement statement = null;
  4896.             try
  4897.             {
  4898.                 con = DatabaseFactory.getInstance().getConnection();
  4899.                 statement = con.prepareStatement(//
  4900.                 "UPDATE characters SET face=?,beautyFace=?,hairStyle=?,beautyHairStyle=?,hairColor=?,beautyHairColor=?,sex=?,x=?,y=?,z=?" + //
  4901.                 ",karma=?,pvpkills=?,pkkills=?,rec_have=?,rec_left=?,clanid=?,deletetime=?," + //
  4902.                 "title=?,accesslevel=?,online=?,leaveclan=?,deleteclan=?,nochannel=?," + //
  4903.                 "onlinetime=?,pledge_type=?,pledge_rank=?,lvl_joined_academy=?,apprentice=?,key_bindings=?,pcBangPoints=?,char_name=?,fame=?,bookmarks=?,bot_rating=?,used_world_chat_points=?,hide_head_accessories=? WHERE obj_Id=? LIMIT 1");
  4904.                 statement.setInt(1, getFace());
  4905.                 statement.setInt(2, getBeautyFace());
  4906.                 statement.setInt(3, getHairStyle());
  4907.                 statement.setInt(4, getBeautyHairStyle());
  4908.                 statement.setInt(5, getHairColor());
  4909.                 statement.setInt(6, getBeautyHairColor());
  4910.                 statement.setInt(7, getSex().ordinal());
  4911.                 if(_stablePoint == null) // еÑ�ли игрок находитÑ�Ñ� в точке в которой его Ñ�охранÑ�Ñ‚ÑŒ не Ñ�тоит (например на виверне) то Ñ�охранÑ�ÑŽÑ‚Ñ�Ñ� поÑ�ледние координаты
  4912.                 {
  4913.                     statement.setInt(8, getX());
  4914.                     statement.setInt(9, getY());
  4915.                     statement.setInt(10, getZ());
  4916.                 }
  4917.                 else
  4918.                 {
  4919.                     statement.setInt(8, _stablePoint.x);
  4920.                     statement.setInt(9, _stablePoint.y);
  4921.                     statement.setInt(10, _stablePoint.z);
  4922.                 }
  4923.                 statement.setInt(11, getKarma());
  4924.                 statement.setInt(12, getPvpKills());
  4925.                 statement.setInt(13, getPkKills());
  4926.                 statement.setInt(14, getRecomHave());
  4927.                 statement.setInt(15, getRecomLeft());
  4928.                 statement.setInt(16, getClanId());
  4929.                 statement.setInt(17, getDeleteTimer());
  4930.                 statement.setString(18, _title);
  4931.                 statement.setInt(19, _accessLevel);
  4932.                 statement.setInt(20, isOnline() && !isInOfflineMode() ? 1 : 0);
  4933.                 statement.setLong(21, getLeaveClanTime() / 1000L);
  4934.                 statement.setLong(22, getDeleteClanTime() / 1000L);
  4935.                 statement.setLong(23, _NoChannel > 0 ? getNoChannelRemained() / 1000 : _NoChannel);
  4936.                 statement.setInt(24, getOnlineTime());
  4937.                 statement.setInt(25, getPledgeType());
  4938.                 statement.setInt(26, getPowerGrade());
  4939.                 statement.setInt(27, getLvlJoinedAcademy());
  4940.                 statement.setInt(28, getApprentice());
  4941.                 statement.setBytes(29, getKeyBindings());
  4942.                 statement.setInt(30, Config.PC_BANG_POINTS_BY_ACCOUNT ? 0 : getPcBangPoints());
  4943.                 statement.setString(31, getName());
  4944.                 statement.setInt(32, getFame());
  4945.                 statement.setInt(33, getBookMarkList().getCapacity());
  4946.                 statement.setInt(34, getBotRating());
  4947.                 statement.setInt(35, getUsedWorldChatPoints());
  4948.                 statement.setInt(36, hideHeadAccessories() ? 1 : 0);
  4949.                 statement.setInt(37, getObjectId());
  4950.  
  4951.                 statement.executeUpdate();
  4952.                 GameStats.increaseUpdatePlayerBase();
  4953.  
  4954.                 if(!fast)
  4955.                 {
  4956.                     EffectsDAO.getInstance().insert(this);
  4957.                     CharacterGroupReuseDAO.getInstance().insert(this);
  4958.                     storeDisableSkills();
  4959.                 }
  4960.  
  4961.                 storeCharSubClasses();
  4962.                 getBookMarkList().store();
  4963.  
  4964.                 getDailyMissionList().store();
  4965.                 if(Config.PC_BANG_POINTS_BY_ACCOUNT)
  4966.                     AccountVariablesDAO.getInstance().insert(getAccountName(), PC_BANG_POINTS_VAR, String.valueOf(getPcBangPoints()));
  4967.             }
  4968.             catch(Exception e)
  4969.             {
  4970.                 _log.error("Could not store char data: " + this + "!", e);
  4971.             }
  4972.             finally
  4973.             {
  4974.                 DbUtils.closeQuietly(con, statement);
  4975.             }
  4976.         }
  4977.         finally
  4978.         {
  4979.             _storeLock.unlock();
  4980.         }
  4981.     }
  4982.  
  4983.     /**
  4984.      * Add a skill to the L2Player _skills and its Func objects to the calculator set of the L2Player and save update in the character_skills table of the database.
  4985.      *
  4986.      * @return The L2Skill replaced or null if just added a new L2Skill
  4987.      */
  4988.     public SkillEntry addSkill(SkillEntry newSkillEntry, final boolean store)
  4989.     {
  4990.         if(newSkillEntry == null)
  4991.             return null;
  4992.  
  4993.         // Add a skill to the L2Player _skills and its Func objects to the calculator set of the L2Player
  4994.         SkillEntry oldSkillEntry = addSkill(newSkillEntry);
  4995.  
  4996.         if(newSkillEntry.equals(oldSkillEntry))
  4997.             return oldSkillEntry;
  4998.  
  4999.         // Add or update a L2Player skill in the character_skills table of the database
  5000.         if(store)
  5001.             storeSkill(newSkillEntry);
  5002.  
  5003.         return oldSkillEntry;
  5004.     }
  5005.  
  5006.     public SkillEntry removeSkill(SkillEntry skillEntry, boolean fromDB)
  5007.     {
  5008.         if(skillEntry == null)
  5009.             return null;
  5010.         return removeSkill(skillEntry.getId(), fromDB);
  5011.     }
  5012.  
  5013.     /**
  5014.      * 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.
  5015.      *
  5016.      * @return The L2Skill removed
  5017.      */
  5018.     public SkillEntry removeSkill(int id, boolean fromDB)
  5019.     {
  5020.         // Remove a skill from the L2Character and its Func objects from calculator set of the L2Character
  5021.         SkillEntry oldSkillEntry = removeSkillById(id);
  5022.  
  5023.         if(!fromDB)
  5024.             return oldSkillEntry;
  5025.  
  5026.         if(oldSkillEntry != null)
  5027.         {
  5028.             Connection con = null;
  5029.             PreparedStatement statement = null;
  5030.             try
  5031.             {
  5032.                 // Remove or update a L2Player skill from the character_skills table of the database
  5033.                 con = DatabaseFactory.getInstance().getConnection();
  5034.                 statement = con.prepareStatement("DELETE FROM character_skills WHERE skill_id=? AND char_obj_id=? AND (class_index=? OR class_index=-1 OR class_index=-2)");
  5035.                 statement.setInt(1, oldSkillEntry.getId());
  5036.                 statement.setInt(2, getObjectId());
  5037.                 statement.setInt(3, getActiveClassId());
  5038.                 statement.execute();
  5039.             }
  5040.             catch(final Exception e)
  5041.             {
  5042.                 _log.error("Could not delete skill!", e);
  5043.             }
  5044.             finally
  5045.             {
  5046.                 DbUtils.closeQuietly(con, statement);
  5047.             }
  5048.         }
  5049.  
  5050.         return oldSkillEntry;
  5051.     }
  5052.  
  5053.     /**
  5054.      * Add or update a L2Player skill in the character_skills table of the database.
  5055.      */
  5056.     private void storeSkill(final SkillEntry newSkillEntry)
  5057.     {
  5058.         if(newSkillEntry == null) // вообще-то невозможно
  5059.         {
  5060.             _log.warn("could not store new skill. its NULL");
  5061.             return;
  5062.         }
  5063.  
  5064.         Connection con = null;
  5065.         PreparedStatement statement = null;
  5066.         try
  5067.         {
  5068.             con = DatabaseFactory.getInstance().getConnection();
  5069.  
  5070.             statement = con.prepareStatement("REPLACE INTO character_skills (char_obj_id,skill_id,skill_level,class_index) values(?,?,?,?)");
  5071.             statement.setInt(1, getObjectId());
  5072.             statement.setInt(2, newSkillEntry.getId());
  5073.             statement.setInt(3, newSkillEntry.getLevel());
  5074.             // Скиллы Ñ�ертификации доÑ�тупны на вÑ�ех Ñ�аб-клаÑ�Ñ�ах.
  5075.             statement.setInt(4, getActiveClassId());
  5076.  
  5077.             statement.execute();
  5078.         }
  5079.         catch(final Exception e)
  5080.         {
  5081.             _log.error("Error could not store skills!", e);
  5082.         }
  5083.         finally
  5084.         {
  5085.             DbUtils.closeQuietly(con, statement);
  5086.         }
  5087.     }
  5088.  
  5089.     private void restoreSkills()
  5090.     {
  5091.         Connection con = null;
  5092.         PreparedStatement statement = null;
  5093.         ResultSet rset = null;
  5094.         try
  5095.         {
  5096.             con = DatabaseFactory.getInstance().getConnection();
  5097.             statement = con.prepareStatement("SELECT skill_id,skill_level FROM character_skills WHERE char_obj_id=? AND (class_index=? OR class_index=-1 OR class_index=-2)");
  5098.             statement.setInt(1, getObjectId());
  5099.             statement.setInt(2, getActiveClassId());
  5100.             rset = statement.executeQuery();
  5101.  
  5102.             while(rset.next())
  5103.             {
  5104.                 final SkillEntry skillEntry = SkillHolder.getInstance().getSkillEntry(rset.getInt("skill_id"), rset.getInt("skill_level"));
  5105.                 if(skillEntry == null)
  5106.                     continue;
  5107.  
  5108.                 if(!isGM())
  5109.                 {
  5110.                     Skill skill = skillEntry.getTemplate();
  5111.                     if(!SkillAcquireHolder.getInstance().isSkillPossible(this, skill))
  5112.                     {
  5113.                         removeSkill(skillEntry, true);
  5114.                         //removeSkillFromShortCut(skill.getId());
  5115.                         //TODO audit
  5116.                         continue;
  5117.                     }
  5118.                 }
  5119.                 addSkill(skillEntry);
  5120.             }
  5121.  
  5122.             // Restore Hero skills at main class only
  5123.             checkHeroSkills();
  5124.  
  5125.             // Restore clan skills
  5126.             if(_clan != null)
  5127.                 _clan.addSkillsQuietly(this);
  5128.  
  5129.             if(Config.UNSTUCK_SKILL && getSkillLevel(1050) < 0)
  5130.                 addSkill(SkillHolder.getInstance().getSkillEntry(2099, 1));
  5131.  
  5132.             if(isGM())
  5133.                 giveGMSkills();
  5134.         }
  5135.         catch(final Exception e)
  5136.         {
  5137.             _log.warn("Could not restore skills for player objId: " + getObjectId());
  5138.             _log.error("", e);
  5139.         }
  5140.         finally
  5141.         {
  5142.             DbUtils.closeQuietly(con, statement, rset);
  5143.         }
  5144.     }
  5145.  
  5146.     public void storeDisableSkills()
  5147.     {
  5148.         Connection con = null;
  5149.         Statement statement = null;
  5150.         try
  5151.         {
  5152.             con = DatabaseFactory.getInstance().getConnection();
  5153.             statement = con.createStatement();
  5154.             statement.executeUpdate("DELETE FROM character_skills_save WHERE char_obj_id = " + getObjectId() + " AND class_index=" + getActiveClassId() + " AND `end_time` < " + System.currentTimeMillis());
  5155.  
  5156.             if(_skillReuses.isEmpty())
  5157.                 return;
  5158.  
  5159.             SqlBatch b = new SqlBatch("REPLACE INTO `character_skills_save` (`char_obj_id`,`skill_id`,`skill_level`,`class_index`,`end_time`,`reuse_delay_org`) VALUES");
  5160.             synchronized (_skillReuses)
  5161.             {
  5162.                 StringBuilder sb;
  5163.                 for(TimeStamp timeStamp : _skillReuses.values())
  5164.                 {
  5165.                     if(timeStamp.hasNotPassed())
  5166.                     {
  5167.                         sb = new StringBuilder("(");
  5168.                         sb.append(getObjectId()).append(",");
  5169.                         sb.append(timeStamp.getId()).append(",");
  5170.                         sb.append(timeStamp.getLevel()).append(",");
  5171.                         sb.append(getActiveClassId()).append(",");
  5172.                         sb.append(timeStamp.getEndTime()).append(",");
  5173.                         sb.append(timeStamp.getReuseBasic()).append(")");
  5174.                         b.write(sb.toString());
  5175.                     }
  5176.                 }
  5177.             }
  5178.             if(!b.isEmpty())
  5179.                 statement.executeUpdate(b.close());
  5180.         }
  5181.         catch(final Exception e)
  5182.         {
  5183.             _log.warn("Could not store disable skills data: " + e);
  5184.         }
  5185.         finally
  5186.         {
  5187.             DbUtils.closeQuietly(con, statement);
  5188.         }
  5189.     }
  5190.  
  5191.     public void restoreDisableSkills()
  5192.     {
  5193.         _skillReuses.clear();
  5194.  
  5195.         Connection con = null;
  5196.         Statement statement = null;
  5197.         ResultSet rset = null;
  5198.         try
  5199.         {
  5200.             con = DatabaseFactory.getInstance().getConnection();
  5201.             statement = con.createStatement();
  5202.             rset = statement.executeQuery("SELECT skill_id,skill_level,end_time,reuse_delay_org FROM character_skills_save WHERE char_obj_id=" + getObjectId() + " AND class_index=" + getActiveClassId());
  5203.             while(rset.next())
  5204.             {
  5205.                 int skillId = rset.getInt("skill_id");
  5206.                 int skillLevel = rset.getInt("skill_level");
  5207.                 long endTime = rset.getLong("end_time");
  5208.                 long rDelayOrg = rset.getLong("reuse_delay_org");
  5209.                 long curTime = System.currentTimeMillis();
  5210.  
  5211.                 Skill skill = SkillHolder.getInstance().getSkill(skillId, skillLevel);
  5212.  
  5213.                 if(skill != null && endTime - curTime > 500)
  5214.                     _skillReuses.put(skill.getReuseHash(), new TimeStamp(skill, endTime, rDelayOrg));
  5215.             }
  5216.             DbUtils.close(statement);
  5217.  
  5218.             statement = con.createStatement();
  5219.             statement.executeUpdate("DELETE FROM character_skills_save WHERE char_obj_id = " + getObjectId() + " AND class_index=" + getActiveClassId() + " AND `end_time` < " + System.currentTimeMillis());
  5220.         }
  5221.         catch(Exception e)
  5222.         {
  5223.             _log.error("Could not restore active skills data!", e);
  5224.         }
  5225.         finally
  5226.         {
  5227.             DbUtils.closeQuietly(con, statement, rset);
  5228.         }
  5229.     }
  5230.  
  5231.     @Override
  5232.     public boolean consumeItem(int itemConsumeId, long itemCount, boolean sendMessage)
  5233.     {
  5234.         return ItemFunctions.deleteItem(this, itemConsumeId, itemCount, sendMessage);
  5235.     }
  5236.  
  5237.     @Override
  5238.     public boolean consumeItemMp(int itemId, int mp)
  5239.     {
  5240.         for(ItemInstance item : getInventory().getPaperdollItems())
  5241.             if(item != null && item.getItemId() == itemId)
  5242.             {
  5243.                 final int newMp = item.getLifeTime() - mp;
  5244.                 if(newMp >= 0)
  5245.                 {
  5246.                     item.setLifeTime(newMp);
  5247.                     sendPacket(new InventoryUpdatePacket().addModifiedItem(this, item));
  5248.                     return true;
  5249.                 }
  5250.                 break;
  5251.             }
  5252.         return false;
  5253.     }
  5254.  
  5255.     /**
  5256.      * @return True if the L2Player is a Mage.<BR><BR>
  5257.      */
  5258.     @Override
  5259.     public boolean isMageClass()
  5260.     {
  5261.         return getClassId().isMage();
  5262.     }
  5263.  
  5264.     /**
  5265.      * ПроверÑ�ет, можно ли приземлитьÑ�Ñ� в Ñ�той зоне.
  5266.      *
  5267.      * @return можно ли приземлитÑ�Ñ�
  5268.      */
  5269.     public boolean checkLandingState()
  5270.     {
  5271.         if(isInZone(ZoneType.no_landing))
  5272.             return false;
  5273.  
  5274.         SiegeEvent<?, ?> siege = getEvent(SiegeEvent.class);
  5275.         if(siege != null)
  5276.         {
  5277.             Residence unit = siege.getResidence();
  5278.             if(unit != null && getClan() != null && isClanLeader() && getClan().getCastle() == unit.getId())
  5279.                 return true;
  5280.             return false;
  5281.         }
  5282.  
  5283.         return true;
  5284.     }
  5285.  
  5286.     public void setMount(int controlItemObjId, int npcId, int level, int currentFeed)
  5287.     {
  5288.         Mount mount = Mount.create(this, controlItemObjId, npcId, level, currentFeed);
  5289.         if(mount != null)
  5290.             setMount(mount);
  5291.     }
  5292.  
  5293.     public void setMount(Mount mount)
  5294.     {
  5295.         if(_mount == mount)
  5296.             return;
  5297.  
  5298.         Mount oldMount = _mount;
  5299.         _mount = null;
  5300.         if(oldMount != null) // Dismount
  5301.             oldMount.onUnride();
  5302.  
  5303.         if(mount != null)
  5304.         {
  5305.             _mount = mount;
  5306.             _mount.onRide();
  5307.         }
  5308.     }
  5309.  
  5310.     public boolean isMounted()
  5311.     {
  5312.         return _mount != null;
  5313.     }
  5314.  
  5315.     public Mount getMount()
  5316.     {
  5317.         return _mount;
  5318.     }
  5319.  
  5320.     public int getMountControlItemObjId()
  5321.     {
  5322.         return isMounted() ? _mount.getControlItemObjId() : 0;
  5323.     }
  5324.  
  5325.     public int getMountNpcId()
  5326.     {
  5327.         return isMounted() ? _mount.getNpcId() : 0;
  5328.     }
  5329.  
  5330.     public int getMountLevel()
  5331.     {
  5332.         return isMounted() ? _mount.getLevel() : 0;
  5333.     }
  5334.  
  5335.     public int getMountCurrentFeed()
  5336.     {
  5337.         return isMounted() ? _mount.getCurrentFeed() : 0;
  5338.     }
  5339.  
  5340.     public void unEquipWeapon()
  5341.     {
  5342.         ItemInstance wpn = getSecondaryWeaponInstance();
  5343.         if(wpn != null)
  5344.         {
  5345.             sendDisarmMessage(wpn);
  5346.             getInventory().unEquipItem(wpn);
  5347.         }
  5348.  
  5349.         wpn = getActiveWeaponInstance();
  5350.         if(wpn != null)
  5351.         {
  5352.             sendDisarmMessage(wpn);
  5353.             getInventory().unEquipItem(wpn);
  5354.         }
  5355.  
  5356.         abortAttack(true, true);
  5357.         abortCast(true, true);
  5358.     }
  5359.  
  5360.     public void sendDisarmMessage(ItemInstance wpn)
  5361.     {
  5362.         if(wpn.getEnchantLevel() > 0)
  5363.         {
  5364.             SystemMessage sm = new SystemMessage(SystemMessage.EQUIPMENT_OF__S1_S2_HAS_BEEN_REMOVED);
  5365.             sm.addNumber(wpn.getEnchantLevel());
  5366.             sm.addItemName(wpn.getItemId());
  5367.             sendPacket(sm);
  5368.         }
  5369.         else
  5370.         {
  5371.             SystemMessage sm = new SystemMessage(SystemMessage.S1__HAS_BEEN_DISARMED);
  5372.             sm.addItemName(wpn.getItemId());
  5373.             sendPacket(sm);
  5374.         }
  5375.     }
  5376.  
  5377.     /**
  5378.      * УÑ�танавливает тип иÑ�пользуемого Ñ�клада.
  5379.      *
  5380.      * @param type тип Ñ�клада:<BR>
  5381.      *             <ul>
  5382.      *             <li>WarehouseType.PRIVATE
  5383.      *             <li>WarehouseType.CLAN
  5384.      *             <li>WarehouseType.CASTLE
  5385.      *             </ul>
  5386.      */
  5387.     public void setUsingWarehouseType(final WarehouseType type)
  5388.     {
  5389.         _usingWHType = type;
  5390.     }
  5391.  
  5392.     /**
  5393.      * Возвращает тип используемого склада.
  5394.      *
  5395.      * @return null или тип склада:<br>
  5396.      *         <ul>
  5397.      *         <li>WarehouseType.PRIVATE
  5398.      *         <li>WarehouseType.CLAN
  5399.      *         <li>WarehouseType.CASTLE
  5400.      *         </ul>
  5401.      */
  5402.     public WarehouseType getUsingWarehouseType()
  5403.     {
  5404.         return _usingWHType;
  5405.     }
  5406.  
  5407.     public Collection<Cubic> getCubics()
  5408.     {
  5409.         return _cubics == null ? Collections.<Cubic>emptyList() : _cubics.values();
  5410.     }
  5411.  
  5412.     @Override
  5413.     public void deleteCubics()
  5414.     {
  5415.         for(Cubic cubic : getCubics())
  5416.             cubic.delete();
  5417.     }
  5418.  
  5419.     public void addCubic(Cubic cubic)
  5420.     {
  5421.         if(_cubics == null)
  5422.             _cubics = new CHashIntObjectMap<Cubic>(3);
  5423.         Cubic oldCubic = _cubics.get(cubic.getSlot());
  5424.         if(oldCubic != null)
  5425.             oldCubic.delete();
  5426.  
  5427.         _cubics.put(cubic.getSlot(), cubic);
  5428.  
  5429.         sendPacket(new ExUserInfoCubic(this));
  5430.     }
  5431.  
  5432.     public void removeCubic(int slot)
  5433.     {
  5434.         if(_cubics != null)
  5435.             _cubics.remove(slot);
  5436.  
  5437.         sendPacket(new ExUserInfoCubic(this));
  5438.     }
  5439.  
  5440.     public Cubic getCubic(int slot)
  5441.     {
  5442.         return _cubics == null ? null : _cubics.get(slot);
  5443.     }
  5444.  
  5445.     @Override
  5446.     public String toString()
  5447.     {
  5448.         return getName() + "[" + getObjectId() + "]";
  5449.     }
  5450.  
  5451.     /**
  5452.      * @return the modifier corresponding to the Enchant Effect of the Active Weapon (Min : 127).<BR><BR>
  5453.      */
  5454.     @Override
  5455.     public int getEnchantEffect()
  5456.     {
  5457.         final ItemInstance wpn = getActiveWeaponInstance();
  5458.  
  5459.         if(wpn == null)
  5460.             return 0;
  5461.  
  5462.         return Math.min(127, wpn.getFixedEnchantLevel(this));
  5463.     }
  5464.  
  5465.     /**
  5466.      * Set the _lastFolkNpc of the L2Player corresponding to the last Folk witch one the player talked.<BR><BR>
  5467.      */
  5468.     public void setLastNpc(final NpcInstance npc)
  5469.     {
  5470.         if(npc == null)
  5471.             _lastNpc = HardReferences.emptyRef();
  5472.         else
  5473.             _lastNpc = npc.getRef();
  5474.     }
  5475.  
  5476.     /**
  5477.      * @return the _lastFolkNpc of the L2Player corresponding to the last Folk witch one the player talked.<BR><BR>
  5478.      */
  5479.     public NpcInstance getLastNpc()
  5480.     {
  5481.         return _lastNpc.get();
  5482.     }
  5483.  
  5484.     public void setMultisell(MultiSellListContainer multisell)
  5485.     {
  5486.         _multisell = multisell;
  5487.     }
  5488.  
  5489.     public MultiSellListContainer getMultisell()
  5490.     {
  5491.         return _multisell;
  5492.     }
  5493.  
  5494.     @Override
  5495.     public boolean unChargeShots(boolean spirit)
  5496.     {
  5497.         ItemInstance weapon = getActiveWeaponInstance();
  5498.         if(weapon == null)
  5499.             return false;
  5500.  
  5501.         if(spirit)
  5502.             weapon.setChargedSpiritshotPower(0);
  5503.         else
  5504.             weapon.setChargedSoulshotPower(0);
  5505.  
  5506.         autoShot();
  5507.         return true;
  5508.     }
  5509.  
  5510.     public boolean unChargeFishShot()
  5511.     {
  5512.         ItemInstance weapon = getActiveWeaponInstance();
  5513.         if(weapon == null)
  5514.             return false;
  5515.  
  5516.         weapon.setChargedFishshotPower(0);
  5517.  
  5518.         autoShot();
  5519.         return true;
  5520.     }
  5521.  
  5522.     public void autoShot()
  5523.     {
  5524.         for(IntObjectPair<SoulShotType> entry : _activeAutoShots.entrySet())
  5525.         {
  5526.             int shotId = entry.getKey();
  5527.  
  5528.             ItemInstance item = getInventory().getItemByItemId(shotId);
  5529.             if(item == null)
  5530.             {
  5531.                 removeAutoShot(shotId, false, entry.getValue());
  5532.                 continue;
  5533.             }
  5534.             useItem(item, false, false);
  5535.         }
  5536.     }
  5537.  
  5538.     @Override
  5539.     public double getChargedSoulshotPower()
  5540.     {
  5541.         ItemInstance weapon = getActiveWeaponInstance();
  5542.         if(weapon != null && weapon.getChargedSoulshotPower() > 0)
  5543.             return calcStat(Stats.SOULSHOT_POWER, weapon.getChargedSoulshotPower());
  5544.         return 0;
  5545.     }
  5546.  
  5547.     @Override
  5548.     public void setChargedSoulshotPower(double val)
  5549.     {
  5550.         ItemInstance weapon = getActiveWeaponInstance();
  5551.         if(weapon != null)
  5552.             weapon.setChargedSoulshotPower(val);
  5553.     }
  5554.  
  5555.     @Override
  5556.     public double getChargedSpiritshotPower()
  5557.     {
  5558.         ItemInstance weapon = getActiveWeaponInstance();
  5559.         if(weapon != null && weapon.getChargedSpiritshotPower() > 0)
  5560.             return calcStat(Stats.SPIRITSHOT_POWER, weapon.getChargedSpiritshotPower());
  5561.         return 0;
  5562.     }
  5563.  
  5564.     @Override
  5565.     public void setChargedSpiritshotPower(double val)
  5566.     {
  5567.         ItemInstance weapon = getActiveWeaponInstance();
  5568.         if(weapon != null)
  5569.             weapon.setChargedSpiritshotPower(val);
  5570.     }
  5571.  
  5572.     public double getChargedFishshotPower()
  5573.     {
  5574.         ItemInstance weapon = getActiveWeaponInstance();
  5575.         if(weapon != null)
  5576.             return weapon.getChargedFishshotPower();
  5577.         return 0;
  5578.     }
  5579.  
  5580.     public void setChargedFishshotPower(double val)
  5581.     {
  5582.         ItemInstance weapon = getActiveWeaponInstance();
  5583.         if(weapon != null)
  5584.             weapon.setChargedFishshotPower(val);
  5585.     }
  5586.  
  5587.     public boolean addAutoShot(int itemId, boolean sendMessage, SoulShotType type)
  5588.     {
  5589.         if(Config.EX_USE_AUTO_SOUL_SHOT)
  5590.         {
  5591.             for(IntObjectPair<SoulShotType> entry : _activeAutoShots.entrySet())
  5592.             {
  5593.                 if(entry.getValue() == type)
  5594.                     _activeAutoShots.remove(entry.getKey());
  5595.             }
  5596.             if(type == SoulShotType.SOULSHOT || type == SoulShotType.SPIRITSHOT)
  5597.             {
  5598.                 WeaponTemplate weaponTemplate = getActiveWeaponTemplate();
  5599.                 if(weaponTemplate == null)
  5600.                     return false;
  5601.  
  5602.                 ItemTemplate shotTemplate = ItemHolder.getInstance().getTemplate(itemId);
  5603.                 if(shotTemplate == null)
  5604.                     return false;
  5605.  
  5606.                 if(shotTemplate.getGrade().extGrade() != weaponTemplate.getGrade().extGrade())
  5607.                     return false;
  5608.             }
  5609.             else if((type == SoulShotType.BEAST_SOULSHOT || type == SoulShotType.BEAST_SPIRITSHOT) && getServitorsCount() == 0)
  5610.                 return false;
  5611.         }
  5612.  
  5613.         if(_activeAutoShots.put(itemId, type) != type)
  5614.         {
  5615.             if(!Config.EX_USE_AUTO_SOUL_SHOT)
  5616.                 sendPacket(new ExAutoSoulShot(itemId, 1, type));
  5617.  
  5618.             if(sendMessage)
  5619.                 sendPacket(new SystemMessagePacket(SystemMsg.THE_AUTOMATIC_USE_OF_S1_HAS_BEEN_ACTIVATED).addItemName(itemId));
  5620.  
  5621.             return true;
  5622.         }
  5623.         return false;
  5624.     }
  5625.  
  5626.     public boolean manuallyAddAutoShot(int itemId, SoulShotType type, boolean save)
  5627.     {
  5628.         if(addAutoShot(itemId, true, type))
  5629.         {
  5630.             if(Config.EX_USE_AUTO_SOUL_SHOT)
  5631.             {
  5632.                 if(save)
  5633.                     setVar(ACTIVE_SHOT_ID_VAR + "_" + type.ordinal(), itemId);
  5634.                 else
  5635.                     unsetVar(ACTIVE_SHOT_ID_VAR + "_" + type.ordinal());
  5636.             }
  5637.             return true;
  5638.         }
  5639.         return false;
  5640.     }
  5641.  
  5642.     public void sendActiveAutoShots()
  5643.     {
  5644.         if(Config.EX_USE_AUTO_SOUL_SHOT)
  5645.             return;
  5646.  
  5647.         for(IntObjectPair<SoulShotType> entry : _activeAutoShots.entrySet())
  5648.             sendPacket(new ExAutoSoulShot(entry.getKey(), 1, entry.getValue()));
  5649.     }
  5650.  
  5651.     public void initActiveAutoShots()
  5652.     {
  5653.         if(!Config.EX_USE_AUTO_SOUL_SHOT)
  5654.             return;
  5655.  
  5656.         for(SoulShotType type : SoulShotType.VALUES)
  5657.         {
  5658.             if(!initSavedActiveShot(type))
  5659.                 sendPacket(new ExAutoSoulShot(0, 1, type));
  5660.         }
  5661.     }
  5662.  
  5663.     public boolean initSavedActiveShot(SoulShotType type)
  5664.     {
  5665.         if(!Config.EX_USE_AUTO_SOUL_SHOT)
  5666.             return false;
  5667.  
  5668.         int shotId = getVarInt(ACTIVE_SHOT_ID_VAR + "_" + type.ordinal(), 0);
  5669.         if(shotId > 0)
  5670.         {
  5671.             ItemInstance item = getInventory().getItemByItemId(shotId);
  5672.             if(item != null)
  5673.             {
  5674.                 IItemHandler handler = item.getTemplate().getHandler();
  5675.                 if(handler != null && handler.isAutoUse() && addAutoShot(shotId, true, type))
  5676.                 {
  5677.                     sendPacket(new ExAutoSoulShot(shotId, 3, type));
  5678.                     ItemFunctions.useItem(this, item, false, false);
  5679.                     return true;
  5680.                 }
  5681.             }
  5682.         }
  5683.         else if(shotId == -1)
  5684.         {
  5685.             sendPacket(new ExAutoSoulShot(0, 2, type));
  5686.             return true;
  5687.         }
  5688.         return false;
  5689.     }
  5690.  
  5691.     public void removeAutoShots(boolean uncharge)
  5692.     {
  5693.         if(Config.EX_USE_AUTO_SOUL_SHOT)
  5694.             return;
  5695.  
  5696.         for(IntObjectPair<SoulShotType> entry : _activeAutoShots.entrySet())
  5697.             removeAutoShot(entry.getKey(), false, entry.getValue());
  5698.  
  5699.         if(uncharge)
  5700.         {
  5701.             ItemInstance weapon = getActiveWeaponInstance();
  5702.             if(weapon != null)
  5703.             {
  5704.                 weapon.setChargedSoulshotPower(0);
  5705.                 weapon.setChargedSpiritshotPower(0);
  5706.                 weapon.setChargedFishshotPower(0);
  5707.             }
  5708.         }
  5709.     }
  5710.  
  5711.     public boolean removeAutoShot(int itemId, boolean sendMessage, SoulShotType type)
  5712.     {
  5713.         if(_activeAutoShots.remove(itemId) != null)
  5714.         {
  5715.             if(!Config.EX_USE_AUTO_SOUL_SHOT)
  5716.                 sendPacket(new ExAutoSoulShot(itemId, 0, type));
  5717.  
  5718.             if(sendMessage)
  5719.                 sendPacket(new SystemMessagePacket(SystemMsg.THE_AUTOMATIC_USE_OF_S1_HAS_BEEN_DEACTIVATED).addItemName(itemId));
  5720.  
  5721.             return true;
  5722.         }
  5723.         return false;
  5724.     }
  5725.  
  5726.     public boolean manuallyRemoveAutoShot(int itemId, SoulShotType type, boolean save)
  5727.     {
  5728.         if(removeAutoShot(itemId, true, type))
  5729.         {
  5730.             if(Config.EX_USE_AUTO_SOUL_SHOT)
  5731.             {
  5732.                 if(save)
  5733.                     setVar(ACTIVE_SHOT_ID_VAR + "_" + type.ordinal(), -1);
  5734.                 else
  5735.                     unsetVar(ACTIVE_SHOT_ID_VAR + "_" + type.ordinal());
  5736.             }
  5737.             return true;
  5738.         }
  5739.         return false;
  5740.     }
  5741.  
  5742.     public void removeAutoShot(SoulShotType type)
  5743.     {
  5744.         if(!Config.EX_USE_AUTO_SOUL_SHOT)
  5745.             return;
  5746.  
  5747.         for(IntObjectPair<SoulShotType> entry : _activeAutoShots.entrySet())
  5748.         {
  5749.             if(entry.getValue() == type)
  5750.             {
  5751.                 removeAutoShot(entry.getKey(), false, entry.getValue());
  5752.                 sendPacket(new ExAutoSoulShot(entry.getKey(), 1, entry.getValue()));
  5753.             }
  5754.         }
  5755.     }
  5756.  
  5757.     public boolean isAutoShot(int itemId)
  5758.     {
  5759.         return _activeAutoShots.containsKey(itemId);
  5760.     }
  5761.  
  5762.     public boolean isAutoShot(SoulShotType type)
  5763.     {
  5764.         return _activeAutoShots.containsValue( type);
  5765.     }
  5766.  
  5767.     @Override
  5768.     public boolean isInvisible(GameObject observer)
  5769.     {
  5770.         if(observer != null)
  5771.         {
  5772.             if(isMyServitor(observer.getObjectId()))
  5773.                 return false;
  5774.  
  5775.             if(observer.isPlayer())
  5776.             {
  5777.                 Player observPlayer = (Player) observer;
  5778.                 if(isInSameParty(observPlayer))
  5779.                     return false;
  5780.             }
  5781.         }
  5782.         return super.isInvisible(observer) || isGMInvisible();
  5783.     }
  5784.  
  5785.     @Override
  5786.     public boolean startInvisible(Object owner, boolean withServitors)
  5787.     {
  5788.         if(super.startInvisible(owner, withServitors))
  5789.         {
  5790.             sendUserInfo(true);
  5791.             return true;
  5792.         }
  5793.         return false;
  5794.     }
  5795.  
  5796.     @Override
  5797.     public boolean stopInvisible(Object owner, boolean withServitors)
  5798.     {
  5799.         if(super.stopInvisible(owner, withServitors))
  5800.         {
  5801.             sendUserInfo(true);
  5802.             return true;
  5803.         }
  5804.         return false;
  5805.     }
  5806.  
  5807.     public boolean isGMInvisible()
  5808.     {
  5809.         return getPlayerAccess().GodMode && _gmInvisible.get();
  5810.     }
  5811.  
  5812.     public boolean setGMInvisible(boolean value)
  5813.     {
  5814.         if(value)
  5815.             return _gmInvisible.getAndSet(true);
  5816.         return _gmInvisible.setAndGet(false);
  5817.     }
  5818.  
  5819.     @Override
  5820.     public boolean isUndying()
  5821.     {
  5822.         return super.isUndying() || isGMUndying();
  5823.     }
  5824.  
  5825.     public boolean isGMUndying()
  5826.     {
  5827.         return getPlayerAccess().GodMode && _gmUndying.get();
  5828.     }
  5829.  
  5830.     public boolean setGMUndying(boolean value)
  5831.     {
  5832.         if(value)
  5833.             return _gmUndying.getAndSet(true);
  5834.         return _gmUndying.setAndGet(false);
  5835.     }
  5836.  
  5837.     public int getClanPrivileges()
  5838.     {
  5839.         if(_clan == null)
  5840.             return 0;
  5841.         if(isClanLeader())
  5842.             return Clan.CP_ALL;
  5843.         if(_powerGrade < 1 || _powerGrade > 9)
  5844.             return 0;
  5845.         RankPrivs privs = _clan.getRankPrivs(_powerGrade);
  5846.         if(privs != null)
  5847.             return privs.getPrivs();
  5848.         return 0;
  5849.     }
  5850.  
  5851.     public void teleToClosestTown()
  5852.     {
  5853.         TeleportPoint teleportPoint = TeleportUtils.getRestartPoint(this, RestartType.TO_VILLAGE);
  5854.         teleToLocation(teleportPoint.getLoc(), teleportPoint.getReflection());
  5855.     }
  5856.  
  5857.     public void teleToCastle()
  5858.     {
  5859.         TeleportPoint teleportPoint = TeleportUtils.getRestartPoint(this, RestartType.TO_CASTLE);
  5860.         teleToLocation(teleportPoint.getLoc(), teleportPoint.getReflection());
  5861.     }
  5862.  
  5863.     public void teleToClanhall()
  5864.     {
  5865.         TeleportPoint teleportPoint = TeleportUtils.getRestartPoint(this, RestartType.TO_CLANHALL);
  5866.         teleToLocation(teleportPoint.getLoc(), teleportPoint.getReflection());
  5867.     }
  5868.  
  5869.     @Override
  5870.     public void sendMessage(CustomMessage message)
  5871.     {
  5872.         sendPacket(message);
  5873.     }
  5874.  
  5875.     public void teleToLocation(Location loc, boolean replace)
  5876.     {
  5877.         _isInReplaceTeleport = replace;
  5878.  
  5879.         teleToLocation(loc);
  5880.  
  5881.         _isInReplaceTeleport = false;
  5882.     }
  5883.  
  5884.     @Override
  5885.     public boolean onTeleported()
  5886.     {
  5887.         if(!super.onTeleported())
  5888.             return false;
  5889.  
  5890.         if(isFakeDeath())
  5891.             breakFakeDeath();
  5892.  
  5893.         if(isInBoat())
  5894.             setLoc(getBoat().getLoc());
  5895.  
  5896.         // 15 Ñ�екунд поÑ�ле телепорта на перÑ�онажа не агрÑ�Ñ‚Ñ�Ñ� мобы
  5897.         setNonAggroTime(System.currentTimeMillis() + Config.NONAGGRO_TIME_ONTELEPORT);
  5898.         setNonPvpTime(System.currentTimeMillis() + Config.NONPVP_TIME_ONTELEPORT);
  5899.  
  5900.         spawnMe();
  5901.  
  5902.         setLastClientPosition(getLoc());
  5903.         setLastServerPosition(getLoc());
  5904.  
  5905.         if(isPendingRevive())
  5906.             doRevive();
  5907.  
  5908.         sendActionFailed();
  5909.  
  5910.         getAI().notifyEvent(CtrlEvent.EVT_TELEPORTED);
  5911.  
  5912.         if(isLockedTarget() && getTarget() != null)
  5913.             sendPacket(new MyTargetSelectedPacket(this, getTarget()));
  5914.  
  5915.         sendUserInfo(true);
  5916.  
  5917.         if(!_isInReplaceTeleport)
  5918.         {
  5919.             for(Servitor servitor : getServitors())
  5920.                 servitor.teleportToOwner();
  5921.         }
  5922.  
  5923.         getListeners().onTeleported();
  5924.  
  5925.         for(ListenerHook hook : getListenerHooks(ListenerHookType.PLAYER_TELEPORT))
  5926.             hook.onPlayerTeleport(this, getReflectionId());
  5927.  
  5928.         for(ListenerHook hook : ListenerHook.getGlobalListenerHooks(ListenerHookType.PLAYER_TELEPORT))
  5929.             hook.onPlayerTeleport(this, getReflectionId());
  5930.  
  5931.         return true;
  5932.     }
  5933.  
  5934.     public boolean enterObserverMode(Location loc)
  5935.     {
  5936.         WorldRegion observerRegion = World.getRegion(loc);
  5937.         if(observerRegion == null)
  5938.             return false;
  5939.         if(!_observerMode.compareAndSet(OBSERVER_NONE, OBSERVER_STARTING))
  5940.             return false;
  5941.  
  5942.         setTarget(null);
  5943.         stopMove();
  5944.         sitDown(null);
  5945.         setFlying(true);
  5946.  
  5947.         // Очищаем вÑ�е видимые обьекты
  5948.         World.removeObjectsFromPlayer(this);
  5949.  
  5950.         _observePoint = new ObservePoint(this);
  5951.         _observePoint.setLoc(loc);
  5952.         _observePoint.getFlags().getImmobilized().start();
  5953.  
  5954.         // Отображаем надпиÑ�ÑŒ над головой
  5955.         broadcastCharInfoImpl();
  5956.  
  5957.         // Переходим в режим обÑ�ервинга
  5958.         sendPacket(new ObserverStartPacket(loc));
  5959.  
  5960.         return true;
  5961.     }
  5962.  
  5963.     public boolean enterArenaObserverMode(ObservableArena arena)
  5964.     {
  5965.         Location enterPoint = arena.getObserverEnterPoint(this);
  5966.         WorldRegion observerRegion = World.getRegion(enterPoint);
  5967.         if(observerRegion == null)
  5968.             return false;
  5969.  
  5970.         if(!_observerMode.compareAndSet(isInArenaObserverMode() ? 3 : 0, 1))
  5971.             return false;
  5972.  
  5973.         sendPacket(new TeleportToLocationPacket(this, enterPoint));
  5974.         setTarget(null);
  5975.         stopMove();
  5976.  
  5977.         World.removeObjectsFromPlayer(this);
  5978.  
  5979.         if(_observableArena != null)
  5980.         {
  5981.             _observableArena.removeObserver(_observePoint);
  5982.             _observableArena.onChangeObserverArena(this);
  5983.             _observePoint.decayMe();
  5984.         }
  5985.         else
  5986.         {
  5987.             broadcastCharInfoImpl();
  5988.             arena.onEnterObserverArena(this);
  5989.             _observePoint = new ObservePoint(this);
  5990.         }
  5991.  
  5992.         _observePoint.setLoc(enterPoint);
  5993.         _observePoint.setReflection(arena.getReflection());
  5994.  
  5995.         _observableArena = arena;
  5996.  
  5997.         sendPacket(new ExTeleportToLocationActivate(this, enterPoint));
  5998.  
  5999.         return true;
  6000.     }
  6001.  
  6002.     public void appearObserverMode()
  6003.     {
  6004.         if(!_observerMode.compareAndSet(OBSERVER_STARTING, OBSERVER_STARTED))
  6005.             return;
  6006.  
  6007.         _observePoint.spawnMe();
  6008.         sendUserInfo(true);
  6009.         if(_observableArena != null)
  6010.         {
  6011.             _observableArena.addObserver(_observePoint);
  6012.             _observableArena.onAppearObserver(_observePoint);
  6013.         }
  6014.     }
  6015.  
  6016.     public void leaveObserverMode()
  6017.     {
  6018.         if(!_observerMode.compareAndSet(OBSERVER_STARTED, OBSERVER_LEAVING))
  6019.             return;
  6020.  
  6021.         ObservableArena arena = _observableArena;
  6022.         if(arena != null)
  6023.         {
  6024.             sendPacket(new TeleportToLocationPacket(this, getLoc()));
  6025.             _observableArena.removeObserver(_observePoint);
  6026.             _observableArena = null;
  6027.         }
  6028.  
  6029.         _observePoint.deleteMe();
  6030.         _observePoint = null;
  6031.  
  6032.         setTarget(null);
  6033.         stopMove();
  6034.  
  6035.         if(arena != null)
  6036.         {
  6037.             arena.onExitObserverArena(this);
  6038.             sendPacket(new ExTeleportToLocationActivate(this, getLoc()));
  6039.         }
  6040.         else // Выходим из режима обÑ�ервинга
  6041.             sendPacket(new ObserverEndPacket(getLoc()));
  6042.     }
  6043.  
  6044.     public void returnFromObserverMode()
  6045.     {
  6046.         if(!_observerMode.compareAndSet(OBSERVER_LEAVING, OBSERVER_NONE))
  6047.             return;
  6048.  
  6049.         // Ð�ужно при телепорте Ñ� более выÑ�окой точки на более низкую, иначе наноÑ�итÑ�Ñ� вред от "падениÑ�"
  6050.         setLastClientPosition(null);
  6051.         setLastServerPosition(null);
  6052.  
  6053.         standUp();
  6054.         setFlying(false);
  6055.  
  6056.         broadcastUserInfo(true);
  6057.  
  6058.         World.showObjectsToPlayer(this);
  6059.     }
  6060.  
  6061.     public void setOlympiadSide(final int i)
  6062.     {
  6063.         _olympiadSide = i;
  6064.     }
  6065.  
  6066.     public int getOlympiadSide()
  6067.     {
  6068.         return _olympiadSide;
  6069.     }
  6070.  
  6071.     public boolean isInObserverMode()
  6072.     {
  6073.         return getObserverMode() > 0;
  6074.     }
  6075.  
  6076.     public boolean isInArenaObserverMode()
  6077.     {
  6078.         return _observableArena != null;
  6079.     }
  6080.  
  6081.     public ObservableArena getObservableArena()
  6082.     {
  6083.         return _observableArena;
  6084.     }
  6085.  
  6086.     public int getObserverMode()
  6087.     {
  6088.         return _observerMode.get();
  6089.     }
  6090.  
  6091.     public ObservePoint getObservePoint()
  6092.     {
  6093.         return _observePoint;
  6094.     }
  6095.  
  6096.     public int getTeleMode()
  6097.     {
  6098.         return _telemode;
  6099.     }
  6100.  
  6101.     public void setTeleMode(final int mode)
  6102.     {
  6103.         _telemode = mode;
  6104.     }
  6105.  
  6106.     public void setLoto(final int i, final int val)
  6107.     {
  6108.         _loto[i] = val;
  6109.     }
  6110.  
  6111.     public int getLoto(final int i)
  6112.     {
  6113.         return _loto[i];
  6114.     }
  6115.  
  6116.     public void setRace(final int i, final int val)
  6117.     {
  6118.         _race[i] = val;
  6119.     }
  6120.  
  6121.     public int getRace(final int i)
  6122.     {
  6123.         return _race[i];
  6124.     }
  6125.  
  6126.     public boolean getMessageRefusal()
  6127.     {
  6128.         return _messageRefusal;
  6129.     }
  6130.  
  6131.     public void setMessageRefusal(final boolean mode)
  6132.     {
  6133.         _messageRefusal = mode;
  6134.     }
  6135.  
  6136.     public void setTradeRefusal(final boolean mode)
  6137.     {
  6138.         _tradeRefusal = mode;
  6139.     }
  6140.  
  6141.     public boolean getTradeRefusal()
  6142.     {
  6143.         return _tradeRefusal;
  6144.     }
  6145.  
  6146.     public boolean isBlockAll()
  6147.     {
  6148.         return _blockAll;
  6149.     }
  6150.  
  6151.     public void setBlockAll(final boolean state)
  6152.     {
  6153.         _blockAll = state;
  6154.     }
  6155.  
  6156.     public void setHero(final boolean hero)
  6157.     {
  6158.         _hero = hero;
  6159.     }
  6160.  
  6161.     @Override
  6162.     public boolean isHero()
  6163.     {
  6164.         return _hero;
  6165.     }
  6166.  
  6167.     public void setIsInOlympiadMode(final boolean b)
  6168.     {
  6169.         _inOlympiadMode = b;
  6170.     }
  6171.  
  6172.     public boolean isInOlympiadMode()
  6173.     {
  6174.         return _inOlympiadMode;
  6175.     }
  6176.  
  6177.     public boolean isOlympiadGameStart()
  6178.     {
  6179.         return _olympiadGame != null && _olympiadGame.getState() == 1;
  6180.     }
  6181.  
  6182.     public boolean isOlympiadCompStart()
  6183.     {
  6184.         return _olympiadGame != null && _olympiadGame.getState() == 2;
  6185.     }
  6186.  
  6187.     public int getSubLevel()
  6188.     {
  6189.         return isBaseClassActive() ? 0 : getLevel();
  6190.     }
  6191.  
  6192.     /* varka silenos and ketra orc quests related functions */
  6193.     public void updateKetraVarka()
  6194.     {
  6195.         if(ItemFunctions.getItemCount(this, 7215) > 0)
  6196.             _ketra = 5;
  6197.         else if(ItemFunctions.getItemCount(this, 7214) > 0)
  6198.             _ketra = 4;
  6199.         else if(ItemFunctions.getItemCount(this, 7213) > 0)
  6200.             _ketra = 3;
  6201.         else if(ItemFunctions.getItemCount(this, 7212) > 0)
  6202.             _ketra = 2;
  6203.         else if(ItemFunctions.getItemCount(this, 7211) > 0)
  6204.             _ketra = 1;
  6205.         else if(ItemFunctions.getItemCount(this, 7225) > 0)
  6206.             _varka = 5;
  6207.         else if(ItemFunctions.getItemCount(this, 7224) > 0)
  6208.             _varka = 4;
  6209.         else if(ItemFunctions.getItemCount(this, 7223) > 0)
  6210.             _varka = 3;
  6211.         else if(ItemFunctions.getItemCount(this, 7222) > 0)
  6212.             _varka = 2;
  6213.         else if(ItemFunctions.getItemCount(this, 7221) > 0)
  6214.             _varka = 1;
  6215.         else
  6216.         {
  6217.             _varka = 0;
  6218.             _ketra = 0;
  6219.         }
  6220.     }
  6221.  
  6222.     public int getVarka()
  6223.     {
  6224.         return _varka;
  6225.     }
  6226.  
  6227.     public int getKetra()
  6228.     {
  6229.         return _ketra;
  6230.     }
  6231.  
  6232.     public void updateRam()
  6233.     {
  6234.         if(ItemFunctions.getItemCount(this, 7247) > 0)
  6235.             _ram = 2;
  6236.         else if(ItemFunctions.getItemCount(this, 7246) > 0)
  6237.             _ram = 1;
  6238.         else
  6239.             _ram = 0;
  6240.     }
  6241.  
  6242.     public int getRam()
  6243.     {
  6244.         return _ram;
  6245.     }
  6246.  
  6247.     public void setPledgeType(final int typeId)
  6248.     {
  6249.         _pledgeType = typeId;
  6250.     }
  6251.  
  6252.     public int getPledgeType()
  6253.     {
  6254.         return _pledgeType;
  6255.     }
  6256.  
  6257.     public void setLvlJoinedAcademy(int lvl)
  6258.     {
  6259.         _lvlJoinedAcademy = lvl;
  6260.     }
  6261.  
  6262.     public int getLvlJoinedAcademy()
  6263.     {
  6264.         return _lvlJoinedAcademy;
  6265.     }
  6266.  
  6267.     public PledgeRank getPledgeRank()
  6268.     {
  6269.         return _pledgeRank;
  6270.     }
  6271.  
  6272.     public void updatePledgeRank()
  6273.     {
  6274.         if(isGM()) // Хай вÑ�е ГМы будут императорами мира Lineage 2 ;)
  6275.         {
  6276.             _pledgeRank = PledgeRank.EMPEROR;
  6277.             return;
  6278.         }
  6279.  
  6280.         int CLAN_LEVEL = _clan == null ? -1 : _clan.getLevel();
  6281.         boolean IN_ACADEMY = _clan != null && Clan.isAcademy(_pledgeType);
  6282.         boolean IS_GUARD = _clan != null && Clan.isRoyalGuard(_pledgeType);
  6283.         boolean IS_KNIGHT = _clan != null && Clan.isOrderOfKnights(_pledgeType);
  6284.  
  6285.         boolean IS_GUARD_CAPTAIN = false, IS_KNIGHT_COMMANDER = false, IS_LEADER = false;
  6286.  
  6287.         SubUnit unit = getSubUnit();
  6288.         if(unit != null)
  6289.         {
  6290.             UnitMember unitMember = unit.getUnitMember(getObjectId());
  6291.             if(unitMember == null)
  6292.             {
  6293.                 _log.warn("Player: unitMember null, clan: " + _clan.getClanId() + "; pledgeType: " + unit.getType());
  6294.                 return;
  6295.             }
  6296.             IS_GUARD_CAPTAIN = Clan.isRoyalGuard(unitMember.isLeaderOf());
  6297.             IS_KNIGHT_COMMANDER = Clan.isOrderOfKnights(unitMember.isLeaderOf());
  6298.             IS_LEADER = unitMember.isLeaderOf() == Clan.SUBUNIT_MAIN_CLAN;
  6299.         }
  6300.  
  6301.         switch(CLAN_LEVEL)
  6302.         {
  6303.             case -1:
  6304.                 _pledgeRank = PledgeRank.VAGABOND;
  6305.                 break;
  6306.             case 0:
  6307.             case 1:
  6308.             case 2:
  6309.             case 3:
  6310.                 _pledgeRank = PledgeRank.VASSAL;
  6311.                 break;
  6312.             case 4:
  6313.                 if(IS_LEADER)
  6314.                     _pledgeRank = PledgeRank.KNIGHT;
  6315.                 else
  6316.                     _pledgeRank = PledgeRank.VASSAL;
  6317.                 break;
  6318.             case 5:
  6319.                 if(IS_LEADER)
  6320.                     _pledgeRank = PledgeRank.WISEMAN;
  6321.                 else if(IN_ACADEMY)
  6322.                     _pledgeRank = PledgeRank.VASSAL;
  6323.                 else
  6324.                     _pledgeRank = PledgeRank.HEIR;
  6325.                 break;
  6326.             case 6:
  6327.                 if(IS_LEADER)
  6328.                     _pledgeRank = PledgeRank.BARON;
  6329.                 else if(IN_ACADEMY)
  6330.                     _pledgeRank = PledgeRank.VASSAL;
  6331.                 else if(IS_GUARD_CAPTAIN)
  6332.                     _pledgeRank = PledgeRank.WISEMAN;
  6333.                 else if(IS_GUARD)
  6334.                     _pledgeRank = PledgeRank.HEIR;
  6335.                 else
  6336.                     _pledgeRank = PledgeRank.KNIGHT;
  6337.                 break;
  6338.             case 7:
  6339.                 if(IS_LEADER)
  6340.                     _pledgeRank = PledgeRank.COUNT;
  6341.                 else if(IN_ACADEMY)
  6342.                     _pledgeRank = PledgeRank.VASSAL;
  6343.                 else if(IS_GUARD_CAPTAIN)
  6344.                     _pledgeRank = PledgeRank.VISCOUNT;
  6345.                 else if(IS_GUARD)
  6346.                     _pledgeRank = PledgeRank.KNIGHT;
  6347.                 else if(IS_KNIGHT_COMMANDER)
  6348.                     _pledgeRank = PledgeRank.BARON;
  6349.                 else if(IS_KNIGHT)
  6350.                     _pledgeRank = PledgeRank.HEIR;
  6351.                 else
  6352.                     _pledgeRank = PledgeRank.WISEMAN;
  6353.                 break;
  6354.             case 8:
  6355.                 if(IS_LEADER)
  6356.                     _pledgeRank = PledgeRank.MARQUIS;
  6357.                 else if(IN_ACADEMY)
  6358.                     _pledgeRank = PledgeRank.VASSAL;
  6359.                 else if(IS_GUARD_CAPTAIN)
  6360.                     _pledgeRank = PledgeRank.COUNT;
  6361.                 else if(IS_GUARD)
  6362.                     _pledgeRank = PledgeRank.WISEMAN;
  6363.                 else if(IS_KNIGHT_COMMANDER)
  6364.                     _pledgeRank = PledgeRank.VISCOUNT;
  6365.                 else if(IS_KNIGHT)
  6366.                     _pledgeRank = PledgeRank.KNIGHT;
  6367.                 else
  6368.                     _pledgeRank = PledgeRank.BARON;
  6369.                 break;
  6370.             case 9:
  6371.                 if(IS_LEADER)
  6372.                     _pledgeRank = PledgeRank.DUKE;
  6373.                 else if(IN_ACADEMY)
  6374.                     _pledgeRank = PledgeRank.VASSAL;
  6375.                 else if(IS_GUARD_CAPTAIN)
  6376.                     _pledgeRank = PledgeRank.MARQUIS;
  6377.                 else if(IS_GUARD)
  6378.                     _pledgeRank = PledgeRank.BARON;
  6379.                 else if(IS_KNIGHT_COMMANDER)
  6380.                     _pledgeRank = PledgeRank.COUNT;
  6381.                 else if(IS_KNIGHT)
  6382.                     _pledgeRank = PledgeRank.WISEMAN;
  6383.                 else
  6384.                     _pledgeRank = PledgeRank.VISCOUNT;
  6385.                 break;
  6386.             case 10:
  6387.                 if(IS_LEADER)
  6388.                     _pledgeRank = PledgeRank.GRAND_DUKE;
  6389.                 else if(IN_ACADEMY)
  6390.                     _pledgeRank = PledgeRank.VASSAL;
  6391.                 else if(IS_GUARD)
  6392.                     _pledgeRank = PledgeRank.VISCOUNT;
  6393.                 else if(IS_KNIGHT)
  6394.                     _pledgeRank = PledgeRank.BARON;
  6395.                 else if(IS_GUARD_CAPTAIN)
  6396.                     _pledgeRank = PledgeRank.DUKE;
  6397.                 else if(IS_KNIGHT_COMMANDER)
  6398.                     _pledgeRank = PledgeRank.MARQUIS;
  6399.                 else
  6400.                     _pledgeRank = PledgeRank.COUNT;
  6401.                 break;
  6402.             case 11:
  6403.                 if(IS_LEADER)
  6404.                     _pledgeRank = PledgeRank.DISTINGUISHED_KING;
  6405.                 else if(IN_ACADEMY)
  6406.                     _pledgeRank = PledgeRank.VASSAL;
  6407.                 else if(IS_GUARD)
  6408.                     _pledgeRank = PledgeRank.COUNT;
  6409.                 else if(IS_KNIGHT)
  6410.                     _pledgeRank = PledgeRank.VISCOUNT;
  6411.                 else if(IS_GUARD_CAPTAIN)
  6412.                     _pledgeRank = PledgeRank.GRAND_DUKE;
  6413.                 else if(IS_KNIGHT_COMMANDER)
  6414.                     _pledgeRank = PledgeRank.DUKE;
  6415.                 else
  6416.                     _pledgeRank = PledgeRank.MARQUIS;
  6417.                 break;
  6418.         }
  6419.  
  6420.         if(isHero() && _pledgeRank.ordinal() < PledgeRank.MARQUIS.ordinal())
  6421.             _pledgeRank = PledgeRank.MARQUIS;
  6422.     }
  6423.  
  6424.     public void setPowerGrade(final int grade)
  6425.     {
  6426.         _powerGrade = grade;
  6427.     }
  6428.  
  6429.     public int getPowerGrade()
  6430.     {
  6431.         return _powerGrade;
  6432.     }
  6433.  
  6434.     public void setApprentice(final int apprentice)
  6435.     {
  6436.         _apprentice = apprentice;
  6437.     }
  6438.  
  6439.     public int getApprentice()
  6440.     {
  6441.         return _apprentice;
  6442.     }
  6443.  
  6444.     public int getSponsor()
  6445.     {
  6446.         return _clan == null ? 0 : _clan.getAnyMember(getObjectId()).getSponsor();
  6447.     }
  6448.    
  6449.     @Override
  6450.     public int getNameColor()
  6451.     {
  6452.         if(isInObserverMode())
  6453.             return Color.black.getRGB();
  6454.  
  6455.         return _nameColor;
  6456.     }
  6457.  
  6458.     public void setNameColor(final int nameColor)
  6459.     {
  6460.         if(nameColor != Config.NORMAL_NAME_COLOUR && nameColor != Config.CLANLEADER_NAME_COLOUR && nameColor != Config.GM_NAME_COLOUR && nameColor != Config.SERVICES_OFFLINE_TRADE_NAME_COLOR)
  6461.             setVar("namecolor", Integer.toHexString(nameColor));
  6462.         else if(nameColor == Config.NORMAL_NAME_COLOUR)
  6463.             unsetVar("namecolor");
  6464.         _nameColor = nameColor;
  6465.     }
  6466.  
  6467.     public void setNameColor(final int red, final int green, final int blue)
  6468.     {
  6469.         _nameColor = (red & 0xFF) + ((green & 0xFF) << 8) + ((blue & 0xFF) << 16);
  6470.         if(_nameColor != Config.NORMAL_NAME_COLOUR && _nameColor != Config.CLANLEADER_NAME_COLOUR && _nameColor != Config.GM_NAME_COLOUR && _nameColor != Config.SERVICES_OFFLINE_TRADE_NAME_COLOR)
  6471.             setVar("namecolor", Integer.toHexString(_nameColor));
  6472.         else
  6473.             unsetVar("namecolor");
  6474.     }
  6475.  
  6476.     private void restoreVariables()
  6477.     {
  6478.         List<CharacterVariable> variables = CharacterVariablesDAO.getInstance().restore(getObjectId());
  6479.         for(CharacterVariable var : variables)
  6480.             _variables.put(var.getName(), var);
  6481.     }
  6482.  
  6483.     public Collection<CharacterVariable> getVariables()
  6484.     {
  6485.         return _variables.values();
  6486.     }
  6487.  
  6488.     public boolean setVar(String name, String value)
  6489.     {
  6490.         return setVar(name, value, -1);
  6491.     }
  6492.  
  6493.     public boolean setVar(String name, String value, long expirationTime)
  6494.     {
  6495.         CharacterVariable var = new CharacterVariable(name, value, expirationTime);
  6496.         if(CharacterVariablesDAO.getInstance().insert(getObjectId(), var))
  6497.         {
  6498.             _variables.put(name, var);
  6499.             return true;
  6500.         }
  6501.         return false;
  6502.     }
  6503.  
  6504.     public boolean setVar(String name, int value)
  6505.     {
  6506.         return setVar(name, value, -1);
  6507.     }
  6508.  
  6509.     public boolean setVar(String name, int value, long expirationTime)
  6510.     {
  6511.         return setVar(name, String.valueOf(value), expirationTime);
  6512.     }
  6513.  
  6514.     public boolean setVar(String name, long value)
  6515.     {
  6516.         return setVar(name, value, -1);
  6517.     }
  6518.  
  6519.     public boolean setVar(String name, long value, long expirationTime)
  6520.     {
  6521.         return setVar(name, String.valueOf(value), expirationTime);
  6522.     }
  6523.  
  6524.     public boolean setVar(String name, double value)
  6525.     {
  6526.         return setVar(name, value, -1);
  6527.     }
  6528.  
  6529.     public boolean setVar(String name, double value, long expirationTime)
  6530.     {
  6531.         return setVar(name, String.valueOf(value), expirationTime);
  6532.     }
  6533.  
  6534.     public boolean setVar(String name, boolean value)
  6535.     {
  6536.         return setVar(name, value, -1);
  6537.     }
  6538.  
  6539.     public boolean setVar(String name, boolean value, long expirationTime)
  6540.     {
  6541.         return setVar(name, String.valueOf(value), expirationTime);
  6542.     }
  6543.  
  6544.     public boolean unsetVar(String name)
  6545.     {
  6546.         if(name == null || name.isEmpty())
  6547.             return false;
  6548.  
  6549.         if(_variables.containsKey(name) && CharacterVariablesDAO.getInstance().delete(getObjectId(), name))
  6550.             return _variables.remove(name) != null;
  6551.  
  6552.         return false;
  6553.     }
  6554.  
  6555.     public String getVar(String name)
  6556.     {
  6557.         return getVar(name, null);
  6558.     }
  6559.  
  6560.     public String getVar(String name, String defaultValue)
  6561.     {
  6562.         CharacterVariable var = _variables.get(name);
  6563.         if(var != null && !var.isExpired())
  6564.             return var.getValue();
  6565.  
  6566.         return defaultValue;
  6567.     }
  6568.  
  6569.     public long getVarExpireTime(String name)
  6570.     {
  6571.         CharacterVariable var = _variables.get(name);
  6572.         if(var != null)
  6573.             return var.getExpireTime();
  6574.  
  6575.         return 0;
  6576.     }
  6577.  
  6578.     public int getVarInt(String name)
  6579.     {
  6580.         return getVarInt(name, 0);
  6581.     }
  6582.  
  6583.     public int getVarInt(String name, int defaultValue)
  6584.     {
  6585.         String var = getVar(name);
  6586.         if(var != null)
  6587.             return Integer.parseInt(var);
  6588.  
  6589.         return defaultValue;
  6590.     }
  6591.  
  6592.     public long getVarLong(String name)
  6593.     {
  6594.         return getVarLong(name, 0L);
  6595.     }
  6596.  
  6597.     public long getVarLong(String name, long defaultValue)
  6598.     {
  6599.         String var = getVar(name);
  6600.         if(var != null)
  6601.             return Long.parseLong(var);
  6602.  
  6603.         return defaultValue;
  6604.     }
  6605.  
  6606.     public double getVarDouble(String name)
  6607.     {
  6608.         return getVarDouble(name, 0.);
  6609.     }
  6610.  
  6611.     public double getVarDouble(String name, double defaultValue)
  6612.     {
  6613.         String var = getVar(name);
  6614.         if(var != null)
  6615.             return Double.parseDouble(var);
  6616.  
  6617.         return defaultValue;
  6618.     }
  6619.  
  6620.     public boolean getVarBoolean(String name)
  6621.     {
  6622.         return getVarBoolean(name, false);
  6623.     }
  6624.  
  6625.     public boolean getVarBoolean(String name, boolean defaultValue)
  6626.     {
  6627.         String var = getVar(name);
  6628.         if(var != null)
  6629.             return !(var.equals("0") || var.equalsIgnoreCase("false"));
  6630.  
  6631.         return defaultValue;
  6632.     }
  6633.  
  6634.     public void setLanguage(String val)
  6635.     {
  6636.         _language = Language.getLanguage(val);
  6637.         setVar(Language.LANG_VAR, _language.getShortName(), -1);
  6638.     }
  6639.  
  6640.     public Language getLanguage()
  6641.     {
  6642.         if(Config.USE_CLIENT_LANG && getNetConnection() != null)
  6643.             return getNetConnection().getLanguage();
  6644.         return _language;
  6645.     }
  6646.  
  6647.     public int getLocationId()
  6648.     {
  6649.         if(getNetConnection() != null)
  6650.             return getNetConnection().getLanguage().getId();
  6651.         return -1;
  6652.     }
  6653.  
  6654.     public boolean isLangRus()
  6655.     {
  6656.         return getLanguage() == Language.RUSSIAN;
  6657.     }
  6658.  
  6659.     public int isAtWarWith(int id)
  6660.     {
  6661.         return _clan == null || !_clan.isAtWarWith(id) ? 0 : 1;
  6662.     }
  6663.  
  6664.     public void stopWaterTask()
  6665.     {
  6666.         if(_taskWater != null)
  6667.         {
  6668.             _taskWater.cancel(false);
  6669.             _taskWater = null;
  6670.             sendPacket(new SetupGaugePacket(this, SetupGaugePacket.Colors.BLUE, 0));
  6671.             sendChanges();
  6672.         }
  6673.     }
  6674.  
  6675.     public void startWaterTask()
  6676.     {
  6677.         if(isDead())
  6678.             stopWaterTask();
  6679.         else if(Config.ALLOW_WATER && _taskWater == null)
  6680.         {
  6681.             int timeinwater = (int) (calcStat(Stats.BREATH, getBaseStats().getBreathBonus(), null, null) * 1000L);
  6682.             sendPacket(new SetupGaugePacket(this, SetupGaugePacket.Colors.BLUE, timeinwater));
  6683.             if(isTransformed() && !getTransform().isCanSwim())
  6684.                 setTransform(null);
  6685.  
  6686.             _taskWater = ThreadPoolManager.getInstance().scheduleAtFixedRate(new WaterTask(this), timeinwater, 1000L);
  6687.             sendChanges();
  6688.         }
  6689.     }
  6690.  
  6691.     public void doRevive(double percent)
  6692.     {
  6693.         restoreExp(percent);
  6694.         doRevive();
  6695.     }
  6696.  
  6697.     @Override
  6698.     public void doRevive()
  6699.     {
  6700.         super.doRevive();
  6701.         unsetVar("lostexp");
  6702.         updateAbnormalIcons();
  6703.         autoShot();
  6704.         if(isMounted())
  6705.             _mount.onRevive();
  6706.     }
  6707.  
  6708.     public void reviveRequest(Player reviver, double percent, boolean pet)
  6709.     {
  6710.         ReviveAnswerListener reviveAsk = _askDialog != null && _askDialog.getValue() instanceof ReviveAnswerListener ? (ReviveAnswerListener) _askDialog.getValue() : null;
  6711.         if(reviveAsk != null)
  6712.         {
  6713.             if(reviveAsk.isForPet() == pet && reviveAsk.getPower() >= percent)
  6714.             {
  6715.                 reviver.sendPacket(SystemMsg.RESURRECTION_HAS_ALREADY_BEEN_PROPOSED);
  6716.                 return;
  6717.             }
  6718.             if(pet && !reviveAsk.isForPet())
  6719.             {
  6720.                 reviver.sendPacket(SystemMsg.A_PET_CANNOT_BE_RESURRECTED_WHILE_ITS_OWNER_IS_IN_THE_PROCESS_OF_RESURRECTING);
  6721.                 return;
  6722.             }
  6723.             if(pet && isDead())
  6724.             {
  6725.                 reviver.sendPacket(SystemMsg.WHILE_A_PET_IS_BEING_RESURRECTED_IT_CANNOT_HELP_IN_RESURRECTING_ITS_MASTER);
  6726.                 return;
  6727.             }
  6728.         }
  6729.  
  6730.         if(pet && getPet() != null && getPet().isDead() || !pet && isDead())
  6731.         {
  6732.  
  6733.             ConfirmDlgPacket pkt = new ConfirmDlgPacket(SystemMsg.C1_IS_MAKING_AN_ATTEMPT_TO_RESURRECT_YOU_IF_YOU_CHOOSE_THIS_PATH_S2_EXPERIENCE_WILL_BE_RETURNED_FOR_YOU, 0);
  6734.             pkt.addName(reviver).addInteger(Math.round(percent));
  6735.  
  6736.             ask(pkt, new ReviveAnswerListener(this, percent, pet));
  6737.         }
  6738.     }
  6739.  
  6740.     public void requestCheckBot()
  6741.     {
  6742.         BotCheckQuestion question = BotCheckManager.generateRandomQuestion();
  6743.         int qId = question.getId();
  6744.         String qDescr = question.getDescr(isLangRus());
  6745.        
  6746.         ConfirmDlgPacket pkt = new ConfirmDlgPacket(SystemMsg.S1, 60000).addString(qDescr);
  6747.         //ConfirmDlgPacket pkt = new ConfirmDlgPacket(qDescr, 60000);
  6748.         ask(pkt, new BotCheckAnswerListner(this, qId));
  6749.     }
  6750.    
  6751.     public void increaseBotRating()
  6752.     {
  6753.         int bot_points = getBotRating();
  6754.         if(bot_points + 1 >= Config.MAX_BOT_POINTS)
  6755.             return;
  6756.         setBotRating(bot_points + 1);  
  6757.     }
  6758.    
  6759.     public void decreaseBotRating()
  6760.     {
  6761.         int bot_points = getBotRating();
  6762.         if(bot_points - 1 <= Config.MINIMAL_BOT_RATING_TO_BAN)
  6763.         {
  6764.             if(toJail(Config.AUTO_BOT_BAN_JAIL_TIME))
  6765.             {
  6766.                 sendMessage("You moved to jail, time to escape - " + Config.AUTO_BOT_BAN_JAIL_TIME + " minutes, reason - botting .");
  6767.                 if(Config.ANNOUNCE_AUTO_BOT_BAN)
  6768.                     Announcements.announceToAll("Player " + getName() + " jailed for botting!");
  6769.             }
  6770.         }
  6771.         else
  6772.         {
  6773.             setBotRating(bot_points - 1);
  6774.             if(Config.ON_WRONG_QUESTION_KICK)
  6775.                 kick();
  6776.         }  
  6777.     }
  6778.    
  6779.     public void setBotRating(int rating)
  6780.     {
  6781.         _botRating = rating;
  6782.     }
  6783.    
  6784.     public int getBotRating()
  6785.     {
  6786.         return _botRating;
  6787.     }
  6788.  
  6789.     public boolean isInJail()
  6790.     {
  6791.         return _isInJail;
  6792.     }
  6793.  
  6794.     public void setIsInJail(boolean value)
  6795.     {
  6796.         _isInJail = value;
  6797.     }
  6798.  
  6799.     public boolean toJail(int time)
  6800.     {
  6801.         if(isInJail())
  6802.             return false;
  6803.  
  6804.         setIsInJail(true);
  6805.         setVar(JAILED_VAR, true, System.currentTimeMillis() + (time * 60000));
  6806.         startUnjailTask(this, time);
  6807.  
  6808.         if(getReflection().isMain())
  6809.             setVar("backCoords", getLoc().toXYZString(), -1);
  6810.  
  6811.         if(isInStoreMode())
  6812.         {
  6813.             setPrivateStoreType(Player.STORE_PRIVATE_NONE);
  6814.             storePrivateStore();
  6815.         }
  6816.  
  6817.         teleToLocation(Location.findPointToStay(this, AdminFunctions.JAIL_SPAWN, 50, 200), ReflectionManager.JAIL);
  6818.  
  6819.         return true;
  6820.     }
  6821.  
  6822.     public boolean fromJail()
  6823.     {
  6824.         if(!isInJail())
  6825.             return false;
  6826.  
  6827.         setIsInJail(false);
  6828.         unsetVar(JAILED_VAR);
  6829.         stopUnjailTask();
  6830.  
  6831.         String back = getVar("backCoords");
  6832.         if(back != null)
  6833.         {
  6834.             teleToLocation(Location.parseLoc(back), ReflectionManager.MAIN);
  6835.             unsetVar("backCoords");
  6836.         }
  6837.         return true;
  6838.     }
  6839.  
  6840.     public void summonCharacterRequest(final Creature summoner, final Location loc, final int summonConsumeCrystal)
  6841.     {
  6842.         ConfirmDlgPacket cd = new ConfirmDlgPacket(SystemMsg.C1_WISHES_TO_SUMMON_YOU_FROM_S2, 60000);
  6843.         cd.addName(summoner).addZoneName(loc);
  6844.  
  6845.         ask(cd, new SummonAnswerListener(this, loc, summonConsumeCrystal));
  6846.     }
  6847.  
  6848.     public void updateNoChannel(final long time)
  6849.     {
  6850.         setNoChannel(time);
  6851.  
  6852.         Connection con = null;
  6853.         PreparedStatement statement = null;
  6854.         try
  6855.         {
  6856.             con = DatabaseFactory.getInstance().getConnection();
  6857.  
  6858.             final String stmt = "UPDATE characters SET nochannel = ? WHERE obj_Id=?";
  6859.             statement = con.prepareStatement(stmt);
  6860.             statement.setLong(1, _NoChannel > 0 ? _NoChannel / 1000 : _NoChannel);
  6861.             statement.setInt(2, getObjectId());
  6862.             statement.executeUpdate();
  6863.         }
  6864.         catch(final Exception e)
  6865.         {
  6866.             _log.warn("Could not activate nochannel:" + e);
  6867.         }
  6868.         finally
  6869.         {
  6870.             DbUtils.closeQuietly(con, statement);
  6871.         }
  6872.  
  6873.         sendPacket(new EtcStatusUpdatePacket(this));
  6874.     }
  6875.  
  6876.     public boolean canTalkWith(Player player)
  6877.     {
  6878.         return _NoChannel >= 0 || player == this;
  6879.     }
  6880.  
  6881.     private void checkDailyCounters()
  6882.     {
  6883.         Calendar temp = Calendar.getInstance();
  6884.         temp.set(Calendar.HOUR_OF_DAY, 6);
  6885.         temp.set(Calendar.MINUTE, 30);
  6886.         temp.set(Calendar.SECOND, 0);
  6887.         temp.set(Calendar.MILLISECOND, 0);
  6888.         long daysPassed = Math.round((System.currentTimeMillis() / 1000 - _lastAccess) / 86400);
  6889.         if(daysPassed == 0 && _lastAccess < temp.getTimeInMillis() / 1000 && System.currentTimeMillis() > temp.getTimeInMillis())
  6890.             daysPassed++;
  6891.  
  6892.         if(daysPassed > 0)
  6893.             restartDailyCounters(true);
  6894.     }
  6895.  
  6896.     public void restartDailyCounters(boolean onRestore)
  6897.     {
  6898.         if(Config.ALLOW_WORLD_CHAT)
  6899.         {
  6900.             setUsedWorldChatPoints(0);
  6901.             if(!onRestore)
  6902.                 sendPacket(new ExWorldChatCnt(this));
  6903.         }
  6904.     }
  6905.  
  6906.     private void checkWeeklyCounters()
  6907.     {
  6908.         Calendar temp = Calendar.getInstance();
  6909.         if(temp.get(Calendar.DAY_OF_WEEK) > Calendar.WEDNESDAY)
  6910.             temp.add(Calendar.DAY_OF_MONTH, 7);
  6911.  
  6912.         temp.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
  6913.         temp.set(Calendar.HOUR_OF_DAY, 6);
  6914.         temp.set(Calendar.MINUTE, 30);
  6915.         temp.set(Calendar.SECOND, 0);
  6916.         temp.set(Calendar.MILLISECOND, 0);
  6917.         if(_lastAccess < temp.getTimeInMillis() / 1000 && System.currentTimeMillis() > temp.getTimeInMillis())
  6918.             restartWeeklyCounters(true);
  6919.     }
  6920.  
  6921.     public void restartWeeklyCounters(boolean onRestore)
  6922.     {
  6923.         //
  6924.     }
  6925.  
  6926.     public SubClassList getSubClassList()
  6927.     {
  6928.         return _subClassList;
  6929.     }
  6930.  
  6931.     public SubClass getBaseSubClass()
  6932.     {
  6933.         return _subClassList.getBaseSubClass();
  6934.     }
  6935.  
  6936.     public int getBaseClassId()
  6937.     {
  6938.         if(getBaseSubClass() != null)
  6939.             return getBaseSubClass().getClassId();
  6940.  
  6941.         return -1;
  6942.     }
  6943.  
  6944.     public SubClass getActiveSubClass()
  6945.     {
  6946.         if(_subClassList != null)
  6947.             return _subClassList.getActiveSubClass();
  6948.         return null;
  6949.     }
  6950.  
  6951.     public int getActiveClassId()
  6952.     {
  6953.         if(getActiveSubClass() != null)
  6954.             return getActiveSubClass().getClassId();
  6955.  
  6956.         return -1;
  6957.     }
  6958.  
  6959.     public boolean isBaseClassActive()
  6960.     {
  6961.         return getActiveSubClass().isBase();
  6962.     }
  6963.  
  6964.     public ClassId getClassId()
  6965.     {
  6966.         return ClassId.VALUES[getActiveClassId()];
  6967.     }
  6968.  
  6969.     public int getMaxLevel()
  6970.     {
  6971.         if(getActiveSubClass() != null)
  6972.             return getActiveSubClass().getMaxLevel();
  6973.  
  6974.         return Experience.getMaxLevel();
  6975.     }
  6976.  
  6977.     /**
  6978.      * Changing index of class in DB, used for changing class when finished professional quests
  6979.      *
  6980.      * @param oldclass
  6981.      * @param newclass
  6982.      */
  6983.     private synchronized void changeClassInDb(final int oldclass, final int newclass)
  6984.     {
  6985.         Connection con = null;
  6986.         PreparedStatement statement = null;
  6987.         try
  6988.         {
  6989.             con = DatabaseFactory.getInstance().getConnection();
  6990.             statement = con.prepareStatement("UPDATE character_subclasses SET class_id=? WHERE char_obj_id=? AND class_id=?");
  6991.             statement.setInt(1, newclass);
  6992.             statement.setInt(2, getObjectId());
  6993.             statement.setInt(3, oldclass);
  6994.             statement.executeUpdate();
  6995.             DbUtils.close(statement);
  6996.  
  6997.             statement = con.prepareStatement("DELETE FROM character_hennas WHERE char_obj_id=? AND class_index=?");
  6998.             statement.setInt(1, getObjectId());
  6999.             statement.setInt(2, newclass);
  7000.             statement.executeUpdate();
  7001.             DbUtils.close(statement);
  7002.  
  7003.             statement = con.prepareStatement("UPDATE character_hennas SET class_index=? WHERE char_obj_id=? AND class_index=?");
  7004.             statement.setInt(1, newclass);
  7005.             statement.setInt(2, getObjectId());
  7006.             statement.setInt(3, oldclass);
  7007.             statement.executeUpdate();
  7008.             DbUtils.close(statement);
  7009.  
  7010.             statement = con.prepareStatement("DELETE FROM character_shortcuts WHERE object_id=? AND class_index=?");
  7011.             statement.setInt(1, getObjectId());
  7012.             statement.setInt(2, newclass);
  7013.             statement.executeUpdate();
  7014.             DbUtils.close(statement);
  7015.  
  7016.             statement = con.prepareStatement("UPDATE character_shortcuts SET class_index=? WHERE object_id=? AND class_index=?");
  7017.             statement.setInt(1, newclass);
  7018.             statement.setInt(2, getObjectId());
  7019.             statement.setInt(3, oldclass);
  7020.             statement.executeUpdate();
  7021.             DbUtils.close(statement);
  7022.  
  7023.             statement = con.prepareStatement("DELETE FROM character_skills WHERE char_obj_id=? AND class_index=?");
  7024.             statement.setInt(1, getObjectId());
  7025.             statement.setInt(2, newclass);
  7026.             statement.executeUpdate();
  7027.             DbUtils.close(statement);
  7028.  
  7029.             statement = con.prepareStatement("UPDATE character_skills SET class_index=? WHERE char_obj_id=? AND class_index=?");
  7030.             statement.setInt(1, newclass);
  7031.             statement.setInt(2, getObjectId());
  7032.             statement.setInt(3, oldclass);
  7033.             statement.executeUpdate();
  7034.             DbUtils.close(statement);
  7035.  
  7036.             statement = con.prepareStatement("DELETE FROM character_effects_save WHERE object_id=? AND id=?");
  7037.             statement.setInt(1, getObjectId());
  7038.             statement.setInt(2, newclass);
  7039.             statement.executeUpdate();
  7040.             DbUtils.close(statement);
  7041.  
  7042.             statement = con.prepareStatement("UPDATE character_effects_save SET id=? WHERE object_id=? AND id=?");
  7043.             statement.setInt(1, newclass);
  7044.             statement.setInt(2, getObjectId());
  7045.             statement.setInt(3, oldclass);
  7046.             statement.executeUpdate();
  7047.             DbUtils.close(statement);
  7048.  
  7049.             statement = con.prepareStatement("DELETE FROM character_skills_save WHERE char_obj_id=? AND class_index=?");
  7050.             statement.setInt(1, getObjectId());
  7051.             statement.setInt(2, newclass);
  7052.             statement.executeUpdate();
  7053.             DbUtils.close(statement);
  7054.  
  7055.             statement = con.prepareStatement("UPDATE character_skills_save SET class_index=? WHERE char_obj_id=? AND class_index=?");
  7056.             statement.setInt(1, newclass);
  7057.             statement.setInt(2, getObjectId());
  7058.             statement.setInt(3, oldclass);
  7059.             statement.executeUpdate();
  7060.             DbUtils.close(statement);
  7061.         }
  7062.         catch(final SQLException e)
  7063.         {
  7064.             _log.error("", e);
  7065.         }
  7066.         finally
  7067.         {
  7068.             DbUtils.closeQuietly(con, statement);
  7069.         }
  7070.     }
  7071.  
  7072.     /**
  7073.      * СохранÑ�ет информацию о клаÑ�Ñ�ах в БД
  7074.      */
  7075.     public void storeCharSubClasses()
  7076.     {
  7077.         SubClass main = getActiveSubClass();
  7078.         if(main != null)
  7079.         {
  7080.             main.setCp(getCurrentCp());
  7081.             main.setHp(getCurrentHp());
  7082.             main.setMp(getCurrentMp());
  7083.         }
  7084.         else
  7085.             _log.warn("Could not store char sub data, main class " + getActiveClassId() + " not found for " + this);
  7086.  
  7087.         CharacterSubclassDAO.getInstance().store(this);
  7088.     }
  7089.  
  7090.     /**
  7091.      * Добавить клаÑ�Ñ�, иÑ�пользуетÑ�Ñ� только длÑ� Ñ�абклаÑ�Ñ�ов
  7092.      *
  7093.      * @param storeOld
  7094.      */
  7095.     public boolean addSubClass(final int classId, boolean storeOld, long exp, long sp)
  7096.     {
  7097.         return addSubClass(classId, storeOld, SubClassType.SUBCLASS, exp, sp);
  7098.     }
  7099.  
  7100.     public boolean addSubClass(final int classId, boolean storeOld, SubClassType type, long exp, long sp)
  7101.     {
  7102.         return addSubClass(-1, classId, storeOld, type, exp, sp);
  7103.     }
  7104.  
  7105.     private boolean addSubClass(final int oldClassId, final int classId, boolean storeOld, SubClassType type, long exp, long sp)
  7106.     {
  7107.         final ClassId newId = ClassId.VALUES[classId];
  7108.         if(newId.isDummy() || newId.isOfLevel(ClassLevel.NONE) || newId.isOfLevel(ClassLevel.FIRST))
  7109.             return false;
  7110.  
  7111.         final SubClass newClass = new SubClass(this);
  7112.         newClass.setType(type);
  7113.         newClass.setClassId(classId);
  7114.         if(exp > 0L)
  7115.             newClass.setExp(exp, true);
  7116.         if(sp > 0)
  7117.             newClass.setSp(sp);
  7118.         if(!getSubClassList().add(newClass))
  7119.             return false;
  7120.  
  7121.         final int level = newClass.getLevel();
  7122.         final double hp = newId.getBaseHp(level);
  7123.         final double mp = newId.getBaseMp(level);
  7124.         final double cp = newId.getBaseCp(level);
  7125.         if(!CharacterSubclassDAO.getInstance().insert(getObjectId(), newClass.getClassId(), newClass.getExp(), newClass.getSp(), hp, mp, cp, hp, mp, cp, level, false, type))
  7126.             return false;
  7127.  
  7128.         setActiveSubClass(classId, storeOld, false);
  7129.  
  7130.         rewardSkills(true, false, true, false);
  7131.  
  7132.         sendSkillList();
  7133.  
  7134.         sendSkillList();
  7135.         setCurrentHpMp(getMaxHp(), getMaxMp(), true);
  7136.         setCurrentCp(getMaxCp());
  7137.  
  7138.         final ClassId oldId = oldClassId >= 0 ? ClassId.VALUES[oldClassId] : null;
  7139.         onReceiveNewClassId(oldId, newId);
  7140.  
  7141.         return true;
  7142.     }
  7143.  
  7144.     /**
  7145.      * УдалÑ�ет вÑ�ÑŽ информацию о клаÑ�Ñ�е и добавлÑ�ет новую, только длÑ� Ñ�абклаÑ�Ñ�ов
  7146.      */
  7147.     public boolean modifySubClass(final int oldClassId, final int newClassId, final boolean safeExpSp)
  7148.     {
  7149.         final SubClass originalClass = getSubClassList().getByClassId(oldClassId);
  7150.         if(originalClass == null || originalClass.isBase())
  7151.             return false;
  7152.  
  7153.         final SubClassType type = originalClass.getType();
  7154.         long exp = 0L;
  7155.         long sp = 0;
  7156.         if(safeExpSp)
  7157.         {
  7158.             exp = originalClass.getExp();
  7159.             sp = originalClass.getSp();
  7160.         }
  7161.  
  7162.         TrainingCamp trainingCamp = TrainingCampManager.getInstance().getTrainingCamp(this);
  7163.         if(trainingCamp != null && trainingCamp.getClassIndex() == originalClass.getIndex())
  7164.             TrainingCampManager.getInstance().removeTrainingCamp(this);
  7165.  
  7166.         Connection con = null;
  7167.         PreparedStatement statement = null;
  7168.         try
  7169.         {
  7170.             con = DatabaseFactory.getInstance().getConnection();
  7171.             // Remove all basic info stored about this sub-class.
  7172.             statement = con.prepareStatement("DELETE FROM character_subclasses WHERE char_obj_id=? AND class_id=? AND type != " + SubClassType.BASE_CLASS.ordinal());
  7173.             statement.setInt(1, getObjectId());
  7174.             statement.setInt(2, oldClassId);
  7175.             statement.execute();
  7176.             DbUtils.close(statement);
  7177.  
  7178.             // Remove all skill info stored for this sub-class.
  7179.             statement = con.prepareStatement("DELETE FROM character_skills WHERE char_obj_id=? AND class_index=? ");
  7180.             statement.setInt(1, getObjectId());
  7181.             statement.setInt(2, oldClassId);
  7182.             statement.execute();
  7183.             DbUtils.close(statement);
  7184.  
  7185.             // Remove all saved skills info stored for this sub-class.
  7186.             statement = con.prepareStatement("DELETE FROM character_skills_save WHERE char_obj_id=? AND class_index=? ");
  7187.             statement.setInt(1, getObjectId());
  7188.             statement.setInt(2, oldClassId);
  7189.             statement.execute();
  7190.             DbUtils.close(statement);
  7191.  
  7192.             // Remove all saved effects stored for this sub-class.
  7193.             statement = con.prepareStatement("DELETE FROM character_effects_save WHERE object_id=? AND id=? ");
  7194.             statement.setInt(1, getObjectId());
  7195.             statement.setInt(2, oldClassId);
  7196.             statement.execute();
  7197.             DbUtils.close(statement);
  7198.  
  7199.             // Remove all henna info stored for this sub-class.
  7200.             statement = con.prepareStatement("DELETE FROM character_hennas WHERE char_obj_id=? AND class_index=? ");
  7201.             statement.setInt(1, getObjectId());
  7202.             statement.setInt(2, oldClassId);
  7203.             statement.execute();
  7204.             DbUtils.close(statement);
  7205.  
  7206.             // Remove all shortcuts info stored for this sub-class.
  7207.             statement = con.prepareStatement("DELETE FROM character_shortcuts WHERE object_id=? AND class_index=? ");
  7208.             statement.setInt(1, getObjectId());
  7209.             statement.setInt(2, oldClassId);
  7210.             statement.execute();
  7211.             DbUtils.close(statement);
  7212.         }
  7213.         catch(final Exception e)
  7214.         {
  7215.             _log.warn("Could not delete char sub-class: " + e);
  7216.             _log.error("", e);
  7217.         }
  7218.         finally
  7219.         {
  7220.             DbUtils.closeQuietly(con, statement);
  7221.         }
  7222.         getSubClassList().removeByClassId(oldClassId);
  7223.  
  7224.         return newClassId <= 0 || addSubClass(oldClassId, newClassId, false, type, exp, sp);
  7225.     }
  7226.  
  7227.     public void setActiveSubClass(final int subId, final boolean store, final boolean onRestore)
  7228.     {
  7229.         if(!onRestore)
  7230.         {
  7231.             SubClass oldActiveSub = getActiveSubClass();
  7232.             if(oldActiveSub != null)
  7233.             {
  7234.                 storeDisableSkills();
  7235.  
  7236.                 if(store)
  7237.                 {
  7238.                     oldActiveSub.setCp(getCurrentCp());
  7239.                     oldActiveSub.setHp(getCurrentHp());
  7240.                     oldActiveSub.setMp(getCurrentMp());
  7241.                 }
  7242.             }
  7243.         }
  7244.  
  7245.         SubClass newActiveSub = _subClassList.changeActiveSubClass(subId);
  7246.  
  7247.         setClassId(subId, false);
  7248.  
  7249.         removeAllSkills();
  7250.  
  7251.         getAbnormalList().stopAll();
  7252.         deleteCubics();
  7253.  
  7254.         for(Servitor servitor : getServitors())
  7255.         {
  7256.             if(servitor != null && servitor.isSummon())
  7257.                 servitor.unSummon(false);
  7258.         }
  7259.  
  7260.         restoreSkills();
  7261.         rewardSkills(false);
  7262.  
  7263.         checkSkills();
  7264.  
  7265.         refreshExpertisePenalty();
  7266.  
  7267.         getInventory().refreshEquip();
  7268.         getInventory().validateItems();
  7269.  
  7270.         getHennaList().restore();
  7271.  
  7272.         getDailyMissionList().restore();
  7273.  
  7274.         EffectsDAO.getInstance().restoreEffects(this);
  7275.         restoreDisableSkills();
  7276.  
  7277.         setCurrentHpMp(newActiveSub.getHp(), newActiveSub.getMp());
  7278.         setCurrentCp(newActiveSub.getCp());
  7279.  
  7280.         _shortCuts.restore();
  7281.         sendPacket(new ShortCutInitPacket(this));
  7282.         sendActiveAutoShots();
  7283.  
  7284.         broadcastPacket(new SocialActionPacket(getObjectId(), SocialActionPacket.LEVEL_UP));
  7285.  
  7286.         setIncreasedForce(0);
  7287.  
  7288.         startHourlyTask();
  7289.  
  7290.         sendSkillList();
  7291.  
  7292.         broadcastCharInfo();
  7293.         updateAbnormalIcons();
  7294.         updateStats();
  7295.     }
  7296.  
  7297.     /**
  7298.      * Через delay миллиÑ�екунд выброÑ�ит игрока из игры
  7299.      */
  7300.     public void startKickTask(long delayMillis)
  7301.     {
  7302.         stopKickTask();
  7303.         _kickTask = ThreadPoolManager.getInstance().schedule(new KickTask(this), delayMillis);
  7304.     }
  7305.  
  7306.     public void stopKickTask()
  7307.     {
  7308.         if(_kickTask != null)
  7309.         {
  7310.             _kickTask.cancel(false);
  7311.             _kickTask = null;
  7312.         }
  7313.     }
  7314.  
  7315.     public boolean givePremiumAccount(PremiumAccountTemplate premiumAccount, int delay)
  7316.     {
  7317.         if(getNetConnection() == null)
  7318.             return false;
  7319.  
  7320.         int type = premiumAccount.getType();
  7321.         if(type == 0)
  7322.             return false;
  7323.  
  7324.         int expireTime = (delay > 0) ? (int) ((delay * 60 * 60) + (System.currentTimeMillis() / 1000)) : Integer.MAX_VALUE;
  7325.         boolean extended = false;
  7326.         int oldAccountType = getNetConnection().getPremiumAccountType();
  7327.         int oldAccountExpire = getNetConnection().getPremiumAccountExpire();
  7328.         if(oldAccountType == type && oldAccountExpire > (System.currentTimeMillis() / 1000))
  7329.         {
  7330.             expireTime += (int) (oldAccountExpire - (System.currentTimeMillis() / 1000));
  7331.             extended = true;
  7332.         }
  7333.  
  7334.         if(Config.PREMIUM_ACCOUNT_BASED_ON_GAMESERVER)
  7335.             PremiumAccountDAO.getInstance().insert(getAccountName(), type, expireTime);
  7336.         else
  7337.         {
  7338.             if(AuthServerCommunication.getInstance().isShutdown())
  7339.                 return false;
  7340.  
  7341.             AuthServerCommunication.getInstance().sendPacket(new BonusRequest(getAccountName(), type, expireTime));
  7342.         }
  7343.  
  7344.         getNetConnection().setPremiumAccountType(type);
  7345.         getNetConnection().setPremiumAccountExpire(expireTime);
  7346.  
  7347.         if(startPremiumAccountTask())
  7348.         {
  7349.             if(!extended)
  7350.             {
  7351.                 if(getParty() != null)
  7352.                     getParty().recalculatePartyData();
  7353.  
  7354.                 getAttendanceRewards().onReceivePremiumAccount();
  7355.                 sendPacket(new ExBR_PremiumStatePacket(this, hasPremiumAccount()));
  7356.             }
  7357.             return true;
  7358.         }
  7359.         return false;
  7360.     }
  7361.  
  7362.     public boolean removePremiumAccount()
  7363.     {
  7364.         PremiumAccountTemplate oldPremiumAccount = getPremiumAccount();
  7365.         if(oldPremiumAccount.getType() == 0)
  7366.             return false;
  7367.  
  7368.         double currentHpRatio = getCurrentHpRatio();
  7369.         double currentMpRatio = getCurrentMpRatio();
  7370.         double currentCpRatio = getCurrentCpRatio();
  7371.  
  7372.         removeStatsOwner(oldPremiumAccount);
  7373.         removeTriggers(oldPremiumAccount);
  7374.  
  7375.         SkillEntry[] skills = _premiumAccount.getAttachedSkills();
  7376.         for(SkillEntry skill : skills)
  7377.             removeSkill(skill);
  7378.  
  7379.         if(skills.length > 0)
  7380.             sendSkillList();
  7381.  
  7382.         setCurrentHp(getMaxHp() * currentHpRatio, false);
  7383.         setCurrentMp(getMaxMp() * currentMpRatio);
  7384.         setCurrentCp(getMaxCp() * currentCpRatio);
  7385.  
  7386.         updateStats();
  7387.  
  7388.         _premiumAccount = PremiumAccountHolder.getInstance().getPremiumAccount(0);
  7389.  
  7390.         if(getParty() != null)
  7391.             getParty().recalculatePartyData();
  7392.  
  7393.         if(Config.PREMIUM_ACCOUNT_BASED_ON_GAMESERVER)
  7394.             PremiumAccountDAO.getInstance().delete(getAccountName());
  7395.         else
  7396.             AuthServerCommunication.getInstance().sendPacket(new BonusRequest(getAccountName(), 0, 0));
  7397.  
  7398.         if(getNetConnection() != null)
  7399.         {
  7400.             getNetConnection().setPremiumAccountType(0);
  7401.             getNetConnection().setPremiumAccountExpire(0);
  7402.         }
  7403.  
  7404.         stopPremiumAccountTask();
  7405.         removePremiumAccountItems(true);
  7406.         sendPacket(new ExBR_PremiumStatePacket(this, hasPremiumAccount()));
  7407.         getAttendanceRewards().onRemovePremiumAccount();
  7408.         return true;
  7409.     }
  7410.  
  7411.     private boolean tryGiveFreePremiumAccount()
  7412.     {
  7413.         if(Config.FREE_PA_TYPE == 0 || Config.FREE_PA_DELAY <= 0)
  7414.             return false;
  7415.  
  7416.         PremiumAccountTemplate premiumAccount = PremiumAccountHolder.getInstance().getPremiumAccount(Config.FREE_PA_TYPE);
  7417.         if(premiumAccount == null)
  7418.             return false;
  7419.  
  7420.         boolean recieved = Boolean.parseBoolean(AccountVariablesDAO.getInstance().select(getAccountName(), FREE_PA_RECIEVED, "false"));
  7421.         if(recieved)
  7422.             return false;
  7423.  
  7424.         if(givePremiumAccount(premiumAccount, Config.FREE_PA_DELAY))
  7425.         {
  7426.             AccountVariablesDAO.getInstance().insert(getAccountName(), FREE_PA_RECIEVED, "true");
  7427.             if(Config.ENABLE_FREE_PA_NOTIFICATION)
  7428.             {
  7429.                 CustomMessage message = null;
  7430.                 int accountExpire = getNetConnection().getPremiumAccountExpire();
  7431.                 if(accountExpire != Integer.MAX_VALUE)
  7432.                 {
  7433.                     message = new CustomMessage("l2s.gameserver.model.Player.GiveFreePA");
  7434.                     message.addString(TimeUtils.toSimpleFormat(accountExpire * 1000L));
  7435.                 }
  7436.                 else
  7437.                     message = new CustomMessage("l2s.gameserver.model.Player.GiveUnlimFreePA");
  7438.  
  7439.                 sendPacket(new ExShowScreenMessage(message.toString(this), 15000, ExShowScreenMessage.ScreenMessageAlign.TOP_CENTER, true));
  7440.             }
  7441.             return true;
  7442.         }
  7443.         return false;
  7444.     }
  7445.  
  7446.     private boolean startPremiumAccountTask()
  7447.     {
  7448.         if(!Config.PREMIUM_ACCOUNT_ENABLED)
  7449.             return false;
  7450.  
  7451.         stopPremiumAccountTask();
  7452.  
  7453.         if(getNetConnection() == null)
  7454.             return false;
  7455.  
  7456.         int accountType = getNetConnection().getPremiumAccountType();
  7457.  
  7458.         PremiumAccountTemplate premiumAccount = accountType == 0 ? null : PremiumAccountHolder.getInstance().getPremiumAccount(accountType);
  7459.         if(premiumAccount != null)
  7460.         {
  7461.             int accountExpire = getNetConnection().getPremiumAccountExpire();
  7462.             if(accountExpire > System.currentTimeMillis() / 1000L)
  7463.             {
  7464.                 _premiumAccount = premiumAccount;
  7465.  
  7466.                 double currentHpRatio = getCurrentHpRatio();
  7467.                 double currentMpRatio = getCurrentMpRatio();
  7468.                 double currentCpRatio = getCurrentCpRatio();
  7469.  
  7470.                 addTriggers(_premiumAccount);
  7471.                 addStatFuncs(_premiumAccount.getStatFuncs());
  7472.  
  7473.                 SkillEntry[] skills = _premiumAccount.getAttachedSkills();
  7474.                 for(SkillEntry skill : skills)
  7475.                     addSkill(skill);
  7476.  
  7477.                 if(skills.length > 0)
  7478.                     sendSkillList();
  7479.  
  7480.                 setCurrentHp(getMaxHp() * currentHpRatio, false);
  7481.                 setCurrentMp(getMaxMp() * currentMpRatio);
  7482.                 setCurrentCp(getMaxCp() * currentCpRatio);
  7483.  
  7484.                 updateStats();
  7485.  
  7486.                 int itemsReceivedType = getVarInt(PA_ITEMS_RECIEVED);
  7487.                 if(itemsReceivedType != premiumAccount.getType())
  7488.                 {
  7489.                     removePremiumAccountItems(false);
  7490.                     ItemData[] items = premiumAccount.getGiveItemsOnStart();
  7491.                     if(items.length > 0)
  7492.                     {
  7493.                         if(!isInventoryFull())
  7494.                         {
  7495.                             sendPacket(SystemMsg.THE_PREMIUM_ITEM_FOR_THIS_ACCOUNT_WAS_PROVIDED_IF_THE_PREMIUM_ACCOUNT_IS_TERMINATED_THIS_ITEM_WILL_BE_DELETED);
  7496.                             for(ItemData item : items)
  7497.                                 ItemFunctions.addItem(this, item.getId(), item.getCount(), true);
  7498.  
  7499.                             setVar(PA_ITEMS_RECIEVED, accountType);
  7500.                         }
  7501.                         else
  7502.                             sendPacket(SystemMsg.THE_PREMIUM_ITEM_CANNOT_BE_RECEIVED_BECAUSE_THE_INVENTORY_WEIGHTQUANTITY_LIMIT_HAS_BEEN_EXCEEDED);
  7503.                     }
  7504.                 }
  7505.                 if(accountExpire != Integer.MAX_VALUE)
  7506.                     _premiumAccountExpirationTask = LazyPrecisionTaskManager.getInstance().startPremiumAccountExpirationTask(this, accountExpire);
  7507.  
  7508.                 return true;
  7509.             }
  7510.             if(!Config.PREMIUM_ACCOUNT_BASED_ON_GAMESERVER)
  7511.                 AuthServerCommunication.getInstance().sendPacket(new BonusRequest(getAccountName(), 0, 0));
  7512.         }
  7513.  
  7514.         removePremiumAccountItems(true);
  7515.         if(tryGiveFreePremiumAccount())
  7516.             return false;
  7517.  
  7518.         if(Config.PREMIUM_ACCOUNT_BASED_ON_GAMESERVER)
  7519.             PremiumAccountDAO.getInstance().delete(getAccountName());
  7520.  
  7521.         if(getNetConnection() != null)
  7522.         {
  7523.             getNetConnection().setPremiumAccountType(0);
  7524.             getNetConnection().setPremiumAccountExpire(0);
  7525.         }
  7526.  
  7527.         return false;
  7528.     }
  7529.  
  7530.     private void stopPremiumAccountTask()
  7531.     {
  7532.         if(_premiumAccountExpirationTask != null)
  7533.         {
  7534.             _premiumAccountExpirationTask.cancel(false);
  7535.             _premiumAccountExpirationTask = null;
  7536.         }
  7537.     }
  7538.  
  7539.     private void removePremiumAccountItems(boolean notify)
  7540.     {
  7541.         PremiumAccountTemplate premiumAccount = PremiumAccountHolder.getInstance().getPremiumAccount(getVarInt(PA_ITEMS_RECIEVED));
  7542.         if(premiumAccount != null)
  7543.         {
  7544.             ItemData[] items = premiumAccount.getTakeItemsOnEnd();
  7545.             if(items.length > 0)
  7546.             {
  7547.                 if(notify)
  7548.                     sendPacket(SystemMsg.THE_PREMIUM_ACCOUNT_HAS_BEEN_TERMINATED_THE_PROVIDED_PREMIUM_ITEM_WAS_DELETED);
  7549.  
  7550.                 for(ItemData item : items)
  7551.                     ItemFunctions.deleteItem(this, item.getId(), item.getCount(), notify);
  7552.  
  7553.                 for(ItemData item : items)
  7554.                     ItemFunctions.deleteItemsEverywhere(this, item.getId());
  7555.             }
  7556.         }
  7557.  
  7558.         unsetVar(PA_ITEMS_RECIEVED);
  7559.     }
  7560.  
  7561.     @Override
  7562.     public int getInventoryLimit()
  7563.     {
  7564.         return (int) calcStat(Stats.INVENTORY_LIMIT, 0, null, null);
  7565.     }
  7566.  
  7567.     public int getWarehouseLimit()
  7568.     {
  7569.         return (int) calcStat(Stats.STORAGE_LIMIT, 0, null, null);
  7570.     }
  7571.  
  7572.     public int getTradeLimit()
  7573.     {
  7574.         return (int) calcStat(Stats.TRADE_LIMIT, 0, null, null);
  7575.     }
  7576.  
  7577.     public int getDwarvenRecipeLimit()
  7578.     {
  7579.         return (int) calcStat(Stats.DWARVEN_RECIPE_LIMIT, 50, null, null) + Config.ALT_ADD_RECIPES;
  7580.     }
  7581.  
  7582.     public int getCommonRecipeLimit()
  7583.     {
  7584.         return (int) calcStat(Stats.COMMON_RECIPE_LIMIT, 50, null, null) + Config.ALT_ADD_RECIPES;
  7585.     }
  7586.  
  7587.     public boolean getAndSetLastItemAuctionRequest()
  7588.     {
  7589.         if(_lastItemAuctionInfoRequest + 2000L < System.currentTimeMillis())
  7590.         {
  7591.             _lastItemAuctionInfoRequest = System.currentTimeMillis();
  7592.             return true;
  7593.         }
  7594.         else
  7595.         {
  7596.             _lastItemAuctionInfoRequest = System.currentTimeMillis();
  7597.             return false;
  7598.         }
  7599.     }
  7600.  
  7601.     @Override
  7602.     public int getNpcId()
  7603.     {
  7604.         return -2;
  7605.     }
  7606.  
  7607.     public GameObject getVisibleObject(int id)
  7608.     {
  7609.         if(getObjectId() == id)
  7610.             return this;
  7611.  
  7612.         GameObject target = null;
  7613.  
  7614.         if(getTargetId() == id)
  7615.             target = getTarget();
  7616.  
  7617.         if(target == null && isInParty())
  7618.             for(Player p : _party.getPartyMembers())
  7619.                 if(p != null && p.getObjectId() == id)
  7620.                 {
  7621.                     target = p;
  7622.                     break;
  7623.                 }
  7624.  
  7625.         if(target == null)
  7626.             target = World.getAroundObjectById(this, id);
  7627.  
  7628.         return target == null || target.isInvisible(this) ? null : target;
  7629.     }
  7630.  
  7631.     @Override
  7632.     public String getTitle()
  7633.     {
  7634.         return super.getTitle();
  7635.     }
  7636.  
  7637.     public int getTitleColor()
  7638.     {
  7639.         return _titlecolor;
  7640.     }
  7641.  
  7642.     public void setTitleColor(final int titlecolor)
  7643.     {
  7644.         if(titlecolor != DEFAULT_TITLE_COLOR)
  7645.             setVar("titlecolor", Integer.toHexString(titlecolor), -1);
  7646.         else
  7647.             unsetVar("titlecolor");
  7648.         _titlecolor = titlecolor;
  7649.     }
  7650.  
  7651.     @Override
  7652.     public boolean isImmobilized()
  7653.     {
  7654.         return super.isImmobilized() || isOverloaded() || isSitting() || isFishing() || isInTrainingCamp();
  7655.     }
  7656.  
  7657.     @Override
  7658.     public boolean isBlocked()
  7659.     {
  7660.         return super.isBlocked() || isInMovie() || isInObserverMode() || isTeleporting() || isLogoutStarted() || isInTrainingCamp();
  7661.     }
  7662.  
  7663.     @Override
  7664.     public boolean isInvulnerable()
  7665.     {
  7666.         return super.isInvulnerable() || isInMovie() || isInTrainingCamp();
  7667.     }
  7668.  
  7669.     /**
  7670.      * if True, the L2Player can't take more item
  7671.      */
  7672.     public void setOverloaded(boolean overloaded)
  7673.     {
  7674.         _overloaded = overloaded;
  7675.     }
  7676.  
  7677.     public boolean isOverloaded()
  7678.     {
  7679.         return _overloaded;
  7680.     }
  7681.  
  7682.     public boolean isFishing()
  7683.     {
  7684.         return _fishing.inStarted();
  7685.     }
  7686.  
  7687.     public Fishing getFishing()
  7688.     {
  7689.         return _fishing;
  7690.     }
  7691.  
  7692.     public PremiumAccountTemplate getPremiumAccount()
  7693.     {
  7694.         return _premiumAccount;
  7695.     }
  7696.  
  7697.     public boolean hasPremiumAccount()
  7698.     {
  7699.         return _premiumAccount.getType() > 0;
  7700.     }
  7701.  
  7702.     public int getPremiumAccountLeftTime()
  7703.     {
  7704.         if(hasPremiumAccount())
  7705.         {
  7706.             GameClient client = this.getNetConnection();
  7707.             if(client != null)
  7708.                 return (int) Math.max(0, client.getPremiumAccountExpire() - System.currentTimeMillis() / 1000L);
  7709.         }
  7710.         return 0;
  7711.     }
  7712.  
  7713.     public double getRateAdena()
  7714.     {
  7715.         double rate = Config.RATE_DROP_ADENA_BY_LVL[getLevel()];
  7716.         rate *= isInParty() ? _party._rateAdena : getPremiumAccount().getRates().getAdena();
  7717.         rate *= 1. + calcStat(Stats.ADENA_RATE_MULTIPLIER, 0, null, null);
  7718.         return rate;
  7719.     }
  7720.  
  7721.     public double getRateItems()
  7722.     {
  7723.         double rate = Config.RATE_DROP_ITEMS_BY_LVL[getLevel()];
  7724.         rate *= isInParty() ? _party._rateDrop : getPremiumAccount().getRates().getDrop();
  7725.         rate *= 1. + calcStat(Stats.DROP_RATE_MULTIPLIER, 0, null, null);
  7726.         return rate;
  7727.     }
  7728.  
  7729.     public double getRateExp()
  7730.     {
  7731.         final double baseRate = Config.RATE_XP_BY_LVL[getLevel()] * (isInParty() ? _party._rateExp : getPremiumAccount().getRates().getExp());
  7732.         double rate = baseRate;
  7733.         rate += baseRate * calcStat(Stats.EXP_RATE_MULTIPLIER, 0, null, null);
  7734.         return rate;
  7735.     }
  7736.  
  7737.     public double getRateSp()
  7738.     {
  7739.         final double baseRate = Config.RATE_SP_BY_LVL[getLevel()] * (isInParty() ? _party._rateSp : getPremiumAccount().getRates().getSp());
  7740.         double rate = baseRate;
  7741.         rate += baseRate * calcStat(Stats.SP_RATE_MULTIPLIER, 0, null, null);
  7742.         return rate;
  7743.     }
  7744.  
  7745.     public double getRateSpoil()
  7746.     {
  7747.         double rate = Config.RATE_DROP_SPOIL_BY_LVL[getLevel()];
  7748.         rate *= isInParty() ? _party._rateSpoil : getPremiumAccount().getRates().getSpoil();
  7749.         rate *= 1. + calcStat(Stats.SPOIL_RATE_MULTIPLIER, 0, null, null);
  7750.         return rate;
  7751.     }
  7752.  
  7753.     public double getRateQuestsDrop()
  7754.     {
  7755.         double rate = Config.RATE_QUESTS_DROP;
  7756.         rate *= getPremiumAccount().getRates().getQuestDrop();
  7757.         return rate;
  7758.     }
  7759.  
  7760.     public double getRateQuestsReward()
  7761.     {
  7762.         double rate = Config.RATE_QUESTS_REWARD;
  7763.         rate *= getPremiumAccount().getRates().getQuestReward();
  7764.         return rate;
  7765.     }
  7766.  
  7767.     public double getDropChanceMod()
  7768.     {
  7769.         double mod = Config.DROP_CHANCE_MODIFIER;
  7770.         mod *= isInParty() ? _party._dropChanceMod : getPremiumAccount().getModifiers().getDropChance();
  7771.         mod *= 1. + calcStat(Stats.DROP_CHANCE_MODIFIER, 0, null, null);
  7772.         return mod;
  7773.     }
  7774.  
  7775.     public double getSpoilChanceMod()
  7776.     {
  7777.         double mod = Config.SPOIL_CHANCE_MODIFIER;
  7778.         mod *= isInParty() ? _party._spoilChanceMod : getPremiumAccount().getModifiers().getSpoilChance();
  7779.         mod *= 1. + calcStat(Stats.SPOIL_CHANCE_MODIFIER, 0, null, null);
  7780.         return mod;
  7781.     }
  7782.  
  7783.     private boolean _maried = false;
  7784.     private int _partnerId = 0;
  7785.     private int _coupleId = 0;
  7786.     private boolean _maryrequest = false;
  7787.     private boolean _maryaccepted = false;
  7788.  
  7789.     public boolean isMaried()
  7790.     {
  7791.         return _maried;
  7792.     }
  7793.  
  7794.     public void setMaried(boolean state)
  7795.     {
  7796.         _maried = state;
  7797.     }
  7798.  
  7799.     public void setMaryRequest(boolean state)
  7800.     {
  7801.         _maryrequest = state;
  7802.     }
  7803.  
  7804.     public boolean isMaryRequest()
  7805.     {
  7806.         return _maryrequest;
  7807.     }
  7808.  
  7809.     public void setMaryAccepted(boolean state)
  7810.     {
  7811.         _maryaccepted = state;
  7812.     }
  7813.  
  7814.     public boolean isMaryAccepted()
  7815.     {
  7816.         return _maryaccepted;
  7817.     }
  7818.  
  7819.     public int getPartnerId()
  7820.     {
  7821.         return _partnerId;
  7822.     }
  7823.  
  7824.     public void setPartnerId(int partnerid)
  7825.     {
  7826.         _partnerId = partnerid;
  7827.     }
  7828.  
  7829.     public int getCoupleId()
  7830.     {
  7831.         return _coupleId;
  7832.     }
  7833.  
  7834.     public void setCoupleId(int coupleId)
  7835.     {
  7836.         _coupleId = coupleId;
  7837.     }
  7838.  
  7839.     private OnPlayerChatMessageReceive _snoopListener = null;
  7840.     private List<Player> _snoopListenerPlayers = new ArrayList<Player>();
  7841.  
  7842.     public void addSnooper(Player pci)
  7843.     {
  7844.         if(!_snoopListenerPlayers.contains(pci))
  7845.             _snoopListenerPlayers.add(pci);
  7846.  
  7847.         if(!_snoopListenerPlayers.isEmpty() && _snoopListener == null)
  7848.             addListener(_snoopListener = new SnoopListener());
  7849.     }
  7850.  
  7851.     public void removeSnooper(Player pci)
  7852.     {
  7853.         _snoopListenerPlayers.remove(pci);
  7854.         if(_snoopListenerPlayers.isEmpty() && _snoopListener != null)
  7855.         {
  7856.             removeListener(_snoopListener);
  7857.             _snoopListener = null;
  7858.         }
  7859.     }
  7860.  
  7861.     private class SnoopListener implements OnPlayerChatMessageReceive
  7862.     {
  7863.         @Override
  7864.         public void onChatMessageReceive(Player player, ChatType type, String charName, String text)
  7865.         {
  7866.             if(_snoopListenerPlayers.size() > 0)
  7867.             {
  7868.                 SnoopPacket sn = new SnoopPacket(getObjectId(), getName(), type.ordinal(), charName, text);
  7869.                 for(Player pci : _snoopListenerPlayers)
  7870.                 {
  7871.                     if(pci != null)
  7872.                         pci.sendPacket(sn);
  7873.                 }
  7874.             }
  7875.         }
  7876.     }
  7877.  
  7878.     /**
  7879.      * СброÑ� реюза вÑ�ех Ñ�килов перÑ�онажа.
  7880.      */
  7881.     public void resetReuse()
  7882.     {
  7883.         _skillReuses.clear();
  7884.         _sharedGroupReuses.clear();
  7885.     }
  7886.  
  7887.     private boolean _charmOfCourage = false;
  7888.  
  7889.     public boolean isCharmOfCourage()
  7890.     {
  7891.         return _charmOfCourage;
  7892.     }
  7893.  
  7894.     public void setCharmOfCourage(boolean val)
  7895.     {
  7896.         _charmOfCourage = val;
  7897.  
  7898.         sendEtcStatusUpdate();
  7899.     }
  7900.  
  7901.     private int _increasedForce = 0;
  7902.     private int _consumedSouls = 0;
  7903.  
  7904.     @Override
  7905.     public int getIncreasedForce()
  7906.     {
  7907.         return _increasedForce;
  7908.     }
  7909.  
  7910.     @Override
  7911.     public int getConsumedSouls()
  7912.     {
  7913.         return _consumedSouls;
  7914.     }
  7915.  
  7916.     @Override
  7917.     public void setConsumedSouls(int i, NpcInstance monster)
  7918.     {
  7919.         if(i == _consumedSouls)
  7920.             return;
  7921.  
  7922.         int max = (int) calcStat(Stats.SOULS_LIMIT, 0, monster, null);
  7923.  
  7924.         if(i > max)
  7925.             i = max;
  7926.  
  7927.         if(i <= 0)
  7928.         {
  7929.             _consumedSouls = 0;
  7930.             sendEtcStatusUpdate();
  7931.             return;
  7932.         }
  7933.  
  7934.         if(_consumedSouls != i)
  7935.         {
  7936.             int diff = i - _consumedSouls;
  7937.             if(diff > 0)
  7938.             {
  7939.                 SystemMessage sm = new SystemMessage(SystemMessage.YOUR_SOUL_HAS_INCREASED_BY_S1_SO_IT_IS_NOW_AT_S2);
  7940.                 sm.addNumber(diff);
  7941.                 sm.addNumber(i);
  7942.                 sendPacket(sm);
  7943.             }
  7944.         }
  7945.         else if(max == i)
  7946.         {
  7947.             sendPacket(SystemMsg.SOUL_CANNOT_BE_ABSORBED_ANYMORE);
  7948.             return;
  7949.         }
  7950.  
  7951.         _consumedSouls = i;
  7952.         sendPacket(new EtcStatusUpdatePacket(this));
  7953.     }
  7954.  
  7955.     @Override
  7956.     public void setIncreasedForce(int i)
  7957.     {
  7958.         i = Math.min(i, getMaxIncreasedForce());
  7959.         i = Math.max(i, 0);
  7960.  
  7961.         if(i != 0 && i > _increasedForce)
  7962.             sendPacket(new SystemMessage(SystemMessage.YOUR_FORCE_HAS_INCREASED_TO_S1_LEVEL).addNumber(i));
  7963.  
  7964.         _increasedForce = i;
  7965.         sendEtcStatusUpdate();
  7966.     }
  7967.  
  7968.     private long _lastFalling;
  7969.  
  7970.     public boolean isFalling()
  7971.     {
  7972.         return System.currentTimeMillis() - _lastFalling < 5000;
  7973.     }
  7974.  
  7975.     public void falling(int height)
  7976.     {
  7977.         if(!Config.DAMAGE_FROM_FALLING || isDead() || isFlying() || isInWater() || isInBoat())
  7978.             return;
  7979.            
  7980.         _lastFalling = System.currentTimeMillis();
  7981.         int damage = (int) calcStat(Stats.FALL, getMaxHp() / 2000. * height, null, null);
  7982.         if(damage > 0)
  7983.         {
  7984.             int curHp = (int) getCurrentHp();
  7985.             if(curHp - damage < 1)
  7986.                 setCurrentHp(1, false);
  7987.             else
  7988.                 setCurrentHp(curHp - damage, false);
  7989.             sendPacket(new SystemMessage(SystemMessage.YOU_RECEIVED_S1_DAMAGE_FROM_TAKING_A_HIGH_FALL).addNumber(damage));
  7990.         }
  7991.     }
  7992.  
  7993.     /**
  7994.      * СиÑ�темные Ñ�ообщениÑ� о текущем Ñ�оÑ�тоÑ�нии хп
  7995.      */
  7996.     @Override
  7997.     public void checkHpMessages(double curHp, double newHp)
  7998.     {
  7999.         //Ñ�юда паÑ�ивные Ñ�киллы
  8000.         int[] _hp = { 30, 30 };
  8001.         int[] skills = { 290, 291 };
  8002.  
  8003.         //Ñ�юда активные Ñ�ффекты
  8004.         int[] _effects_skills_id = { 139, 176, 292, 292, 420 };
  8005.         int[] _effects_hp = { 30, 30, 30, 60, 30 };
  8006.  
  8007.         double percent = getMaxHp() / 100;
  8008.         double _curHpPercent = curHp / percent;
  8009.         double _newHpPercent = newHp / percent;
  8010.         boolean needsUpdate = false;
  8011.  
  8012.         //check for passive skills
  8013.         for(int i = 0; i < skills.length; i++)
  8014.         {
  8015.             int level = getSkillLevel(skills[i]);
  8016.             if(level > 0)
  8017.                 if(_curHpPercent > _hp[i] && _newHpPercent <= _hp[i])
  8018.                 {
  8019.                     sendPacket(new SystemMessage(SystemMessage.SINCE_HP_HAS_DECREASED_THE_EFFECT_OF_S1_CAN_BE_FELT).addSkillName(skills[i], level));
  8020.                     needsUpdate = true;
  8021.                 }
  8022.                 else if(_curHpPercent <= _hp[i] && _newHpPercent > _hp[i])
  8023.                 {
  8024.                     sendPacket(new SystemMessage(SystemMessage.SINCE_HP_HAS_INCREASED_THE_EFFECT_OF_S1_WILL_DISAPPEAR).addSkillName(skills[i], level));
  8025.                     needsUpdate = true;
  8026.                 }
  8027.         }
  8028.  
  8029.         //check for active effects
  8030.         for(Integer i = 0; i < _effects_skills_id.length; i++)
  8031.             if(getAbnormalList().contains(_effects_skills_id[i]))
  8032.                 if(_curHpPercent > _effects_hp[i] && _newHpPercent <= _effects_hp[i])
  8033.                 {
  8034.                     sendPacket(new SystemMessage(SystemMessage.SINCE_HP_HAS_DECREASED_THE_EFFECT_OF_S1_CAN_BE_FELT).addSkillName(_effects_skills_id[i], 1));
  8035.                     needsUpdate = true;
  8036.                 }
  8037.                 else if(_curHpPercent <= _effects_hp[i] && _newHpPercent > _effects_hp[i])
  8038.                 {
  8039.                     sendPacket(new SystemMessage(SystemMessage.SINCE_HP_HAS_INCREASED_THE_EFFECT_OF_S1_WILL_DISAPPEAR).addSkillName(_effects_skills_id[i], 1));
  8040.                     needsUpdate = true;
  8041.                 }
  8042.  
  8043.         if(needsUpdate)
  8044.             sendChanges();
  8045.     }
  8046.  
  8047.     /**
  8048.      * СиÑ�темные Ñ�ообщениÑ� длÑ� темных Ñ�льфов о вкл/выкл ShadowSence (skill id = 294)
  8049.      */
  8050.     public void checkDayNightMessages()
  8051.     {
  8052.         int level = getSkillLevel(294);
  8053.         if(level > 0)
  8054.             if(GameTimeController.getInstance().isNowNight())
  8055.                 sendPacket(new SystemMessage(SystemMessage.IT_IS_NOW_MIDNIGHT_AND_THE_EFFECT_OF_S1_CAN_BE_FELT).addSkillName(294, level));
  8056.             else
  8057.                 sendPacket(new SystemMessage(SystemMessage.IT_IS_DAWN_AND_THE_EFFECT_OF_S1_WILL_NOW_DISAPPEAR).addSkillName(294, level));
  8058.         sendChanges();
  8059.     }
  8060.  
  8061.     public int getZoneMask()
  8062.     {
  8063.         return _zoneMask;
  8064.     }
  8065.  
  8066.     //TODO [G1ta0] переработать в лиÑ�енер?
  8067.     @Override
  8068.     protected void onUpdateZones(List<Zone> leaving, List<Zone> entering)
  8069.     {
  8070.         super.onUpdateZones(leaving, entering);
  8071.  
  8072.         if((leaving == null || leaving.isEmpty()) && (entering == null || entering.isEmpty()))
  8073.             return;
  8074.  
  8075.         boolean lastInCombatZone = (_zoneMask & ZONE_PVP_FLAG) == ZONE_PVP_FLAG;
  8076.         boolean lastInDangerArea = (_zoneMask & ZONE_ALTERED_FLAG) == ZONE_ALTERED_FLAG;
  8077.         boolean lastOnSiegeField = (_zoneMask & ZONE_SIEGE_FLAG) == ZONE_SIEGE_FLAG;
  8078.         boolean lastInPeaceZone = (_zoneMask & ZONE_PEACE_FLAG) == ZONE_PEACE_FLAG;
  8079.         //FIXME G1ta0 boolean lastInSSQZone = (_zoneMask & ZONE_SSQ_FLAG) == ZONE_SSQ_FLAG;
  8080.  
  8081.         boolean isInCombatZone = isInZoneBattle();
  8082.         boolean isInDangerArea = isInDangerArea() || isInZone(ZoneType.CHANGED_ZONE);
  8083.         boolean isOnSiegeField = isInSiegeZone();
  8084.         boolean isInPeaceZone = isInPeaceZone();
  8085.         boolean isInSSQZone = isInSSQZone();
  8086.  
  8087.         // обновлÑ�ем компаÑ�, только еÑ�ли перÑ�онаж в мире
  8088.         int lastZoneMask = _zoneMask;
  8089.         _zoneMask = 0;
  8090.  
  8091.         if(isInCombatZone)
  8092.             _zoneMask |= ZONE_PVP_FLAG;
  8093.         if(isInDangerArea)
  8094.             _zoneMask |= ZONE_ALTERED_FLAG;
  8095.         if(isOnSiegeField)
  8096.             _zoneMask |= ZONE_SIEGE_FLAG;
  8097.         if(isInPeaceZone)
  8098.             _zoneMask |= ZONE_PEACE_FLAG;
  8099.         if(isInSSQZone)
  8100.             _zoneMask |= ZONE_SSQ_FLAG;
  8101.  
  8102.         if(lastZoneMask != _zoneMask)
  8103.             sendPacket(new ExSetCompassZoneCode(this));
  8104.         boolean broadcastRelation = false;
  8105.         if(lastInCombatZone != isInCombatZone)
  8106.             broadcastRelation = true;
  8107.  
  8108.         if(lastInDangerArea != isInDangerArea)
  8109.             sendPacket(new EtcStatusUpdatePacket(this));
  8110.  
  8111.         if(lastOnSiegeField != isOnSiegeField)
  8112.         {
  8113.             broadcastRelation = true;
  8114.             if(isOnSiegeField)
  8115.                 sendPacket(SystemMsg.YOU_HAVE_ENTERED_A_COMBAT_ZONE);
  8116.             else
  8117.             {
  8118.                 //ЕÑ�ли игрок выходит за территорию оÑ�ады и у него еÑ�Ñ‚ÑŒ флаг, то отбираем его и Ñ�павним в дефолтное меÑ�то.
  8119.                 //TODO: [Bonux] Проверить как на оффе.
  8120.                 FlagItemAttachment attachment = getActiveWeaponFlagAttachment();
  8121.                 if(attachment != null)
  8122.                     attachment.onLeaveSiegeZone(this);
  8123.  
  8124.                 sendPacket(SystemMsg.YOU_HAVE_LEFT_A_COMBAT_ZONE);
  8125.                 if(!isTeleporting() && getPvpFlag() == 0)
  8126.                     startPvPFlag(null);
  8127.             }
  8128.         }
  8129.  
  8130.         if(broadcastRelation)
  8131.             broadcastRelation();
  8132.  
  8133.         if(isInWater())
  8134.             startWaterTask();
  8135.         else
  8136.             stopWaterTask();
  8137.     }
  8138.  
  8139.     public void startAutoSaveTask()
  8140.     {
  8141.         if(!Config.AUTOSAVE)
  8142.             return;
  8143.         if(_autoSaveTask == null)
  8144.             _autoSaveTask = AutoSaveManager.getInstance().addAutoSaveTask(this);
  8145.     }
  8146.  
  8147.     public void stopAutoSaveTask()
  8148.     {
  8149.         if(_autoSaveTask != null)
  8150.             _autoSaveTask.cancel(false);
  8151.         _autoSaveTask = null;
  8152.     }
  8153.  
  8154.     public void startPcBangPointsTask()
  8155.     {
  8156.         if(!Config.ALT_PCBANG_POINTS_ENABLED || Config.ALT_PCBANG_POINTS_DELAY <= 0)
  8157.             return;
  8158.         if(_pcCafePointsTask == null)
  8159.             _pcCafePointsTask = LazyPrecisionTaskManager.getInstance().addPCCafePointsTask(this);
  8160.     }
  8161.  
  8162.     public void stopPcBangPointsTask()
  8163.     {
  8164.         if(_pcCafePointsTask != null)
  8165.             _pcCafePointsTask.cancel(false);
  8166.         _pcCafePointsTask = null;
  8167.     }
  8168.  
  8169.     public void startUnjailTask(Player player, int time)
  8170.     {
  8171.         if(_unjailTask != null)
  8172.             _unjailTask.cancel(false);
  8173.         _unjailTask = ThreadPoolManager.getInstance().schedule(new UnJailTask(player), time * 60000);
  8174.     }
  8175.  
  8176.     public void stopUnjailTask()
  8177.     {
  8178.         if(_unjailTask != null)
  8179.             _unjailTask.cancel(false);
  8180.         _unjailTask = null;
  8181.     }
  8182.  
  8183.     public void startTrainingCampTask(long timeRemaining)
  8184.     {
  8185.         if(_trainingCampTask == null && isInTrainingCamp())
  8186.             _trainingCampTask = ThreadPoolManager.getInstance().schedule(() -> TrainingCampManager.getInstance().onExitTrainingCamp(this), timeRemaining);
  8187.     }
  8188.  
  8189.     public void stopTrainingCampTask()
  8190.     {
  8191.         if(_trainingCampTask != null)
  8192.         {
  8193.             _trainingCampTask.cancel(false);
  8194.             _trainingCampTask = null;
  8195.         }
  8196.     }
  8197.  
  8198.     public boolean isInTrainingCamp()
  8199.     {
  8200.         TrainingCamp trainingCamp = TrainingCampManager.getInstance().getTrainingCamp(this);
  8201.         return trainingCamp != null && trainingCamp.isTraining() && trainingCamp.isValid(this);
  8202.     }
  8203.  
  8204.     @Override
  8205.     public void sendMessage(String message)
  8206.     {
  8207.         sendPacket(new SystemMessage(message));
  8208.     }
  8209.  
  8210.     private Location _lastClientPosition;
  8211.     private Location _lastServerPosition;
  8212.  
  8213.     public void setLastClientPosition(Location position)
  8214.     {
  8215.         _lastClientPosition = position;
  8216.     }
  8217.  
  8218.     public Location getLastClientPosition()
  8219.     {
  8220.         return _lastClientPosition;
  8221.     }
  8222.  
  8223.     public void setLastServerPosition(Location position)
  8224.     {
  8225.         _lastServerPosition = position;
  8226.     }
  8227.  
  8228.     public Location getLastServerPosition()
  8229.     {
  8230.         return _lastServerPosition;
  8231.     }
  8232.  
  8233.     private int _useSeed = 0;
  8234.  
  8235.     public void setUseSeed(int id)
  8236.     {
  8237.         _useSeed = id;
  8238.     }
  8239.  
  8240.     public int getUseSeed()
  8241.     {
  8242.         return _useSeed;
  8243.     }
  8244.  
  8245.     @Override
  8246.     public int getRelation(Player target)
  8247.     {
  8248.         int result = 0;
  8249.  
  8250.         if(getClan() != null)
  8251.         {
  8252.             result |= RelationChangedPacket.RELATION_CLAN_MEMBER;
  8253.             if(getClan() == target.getClan())
  8254.                 result |= RelationChangedPacket.RELATION_CLAN_MATE;
  8255.             if(getClan().getAllyId() != 0)
  8256.                 result |= RelationChangedPacket.RELATION_ALLY_MEMBER;
  8257.         }
  8258.  
  8259.         if(isClanLeader())
  8260.             result |= RelationChangedPacket.RELATION_LEADER;
  8261.  
  8262.         Party party = getParty();
  8263.         if(party != null && party == target.getParty())
  8264.         {
  8265.             result |= RelationChangedPacket.RELATION_HAS_PARTY;
  8266.  
  8267.             switch(party.getPartyMembers().indexOf(this))
  8268.             {
  8269.                 case 0:
  8270.                     result |= RelationChangedPacket.RELATION_PARTYLEADER; // 0x10
  8271.                     break;
  8272.                 case 1:
  8273.                     result |= RelationChangedPacket.RELATION_PARTY4; // 0x8
  8274.                     break;
  8275.                 case 2:
  8276.                     result |= RelationChangedPacket.RELATION_PARTY3 + RelationChangedPacket.RELATION_PARTY2 + RelationChangedPacket.RELATION_PARTY1; // 0x7
  8277.                     break;
  8278.                 case 3:
  8279.                     result |= RelationChangedPacket.RELATION_PARTY3 + RelationChangedPacket.RELATION_PARTY2; // 0x6
  8280.                     break;
  8281.                 case 4:
  8282.                     result |= RelationChangedPacket.RELATION_PARTY3 + RelationChangedPacket.RELATION_PARTY1; // 0x5
  8283.                     break;
  8284.                 case 5:
  8285.                     result |= RelationChangedPacket.RELATION_PARTY3; // 0x4
  8286.                     break;
  8287.                 case 6:
  8288.                     result |= RelationChangedPacket.RELATION_PARTY2 + RelationChangedPacket.RELATION_PARTY1; // 0x3
  8289.                     break;
  8290.                 case 7:
  8291.                     result |= RelationChangedPacket.RELATION_PARTY2; // 0x2
  8292.                     break;
  8293.                 case 8:
  8294.                     result |= RelationChangedPacket.RELATION_PARTY1; // 0x1
  8295.                     break;
  8296.             }
  8297.         }
  8298.  
  8299.         Clan clan1 = getClan();
  8300.         Clan clan2 = target.getClan();
  8301.         if(clan1 != null && clan2 != null)
  8302.         {
  8303.             if((target.getPledgeType() != Clan.SUBUNIT_ACADEMY || target.getLevel() >= 70) && (getPledgeType() != Clan.SUBUNIT_ACADEMY || getLevel() >= 70))
  8304.                 if(clan2.isAtWarWith(clan1.getClanId()))
  8305.                 {
  8306.                     result |= RelationChangedPacket.RELATION_1SIDED_WAR;
  8307.                     if(clan1.isAtWarWith(clan2.getClanId()))
  8308.                         result |= RelationChangedPacket.RELATION_MUTUAL_WAR;
  8309.                 }
  8310.         }
  8311.  
  8312.         for(Event e : getEvents())
  8313.             result = e.getRelation(this, target, result);
  8314.  
  8315.         return result;
  8316.     }
  8317.  
  8318.     /**
  8319.      * 0=White, 1=Purple, 2=PurpleBlink
  8320.      */
  8321.     protected int _pvpFlag;
  8322.  
  8323.     private Future<?> _PvPRegTask;
  8324.     private long _lastPvPAttack;
  8325.  
  8326.     public long getLastPvPAttack()
  8327.     {
  8328.         return isVioletBoy() ? System.currentTimeMillis() : _lastPvPAttack;
  8329.     }
  8330.  
  8331.     public void setLastPvPAttack(long time)
  8332.     {
  8333.         _lastPvPAttack = time;
  8334.     }
  8335.  
  8336.     @Override
  8337.     public void startPvPFlag(Creature target)
  8338.     {
  8339.         if(isPK() || isVioletBoy())
  8340.             return;
  8341.  
  8342.         long startTime = System.currentTimeMillis();
  8343.         if(target != null && target.getPvpFlag() != 0)
  8344.             startTime -= Config.PVP_TIME / 2;
  8345.         if(getPvpFlag() != 0 && getLastPvPAttack() >= startTime)
  8346.             return;
  8347.  
  8348.         _lastPvPAttack = startTime;
  8349.  
  8350.         updatePvPFlag(1);
  8351.  
  8352.         if(_PvPRegTask == null)
  8353.             _PvPRegTask = ThreadPoolManager.getInstance().scheduleAtFixedRate(new PvPFlagTask(this), 1000, 1000);
  8354.     }
  8355.  
  8356.     public void stopPvPFlag()
  8357.     {
  8358.         if(_PvPRegTask != null)
  8359.         {
  8360.             _PvPRegTask.cancel(false);
  8361.             _PvPRegTask = null;
  8362.         }
  8363.         updatePvPFlag(0);
  8364.     }
  8365.  
  8366.     public void updatePvPFlag(int value)
  8367.     {
  8368.         if(getPvpFlag() == value)
  8369.             return;
  8370.  
  8371.         setPvpFlag(value);
  8372.  
  8373.         sendStatusUpdate(true, true, StatusUpdatePacket.PVP_FLAG);
  8374.  
  8375.         broadcastRelation();
  8376.     }
  8377.  
  8378.     public void setPvpFlag(int pvpFlag)
  8379.     {
  8380.         _pvpFlag = pvpFlag;
  8381.     }
  8382.  
  8383.     @Override
  8384.     public int getPvpFlag()
  8385.     {
  8386.         return isVioletBoy() ? 1 : _pvpFlag;
  8387.     }
  8388.  
  8389.     public boolean isInDuel()
  8390.     {
  8391.         return getEvent(DuelEvent.class) != null;
  8392.     }
  8393.  
  8394.     private long _lastAttackPacket = 0;
  8395.  
  8396.     public long getLastAttackPacket()
  8397.     {
  8398.         return _lastAttackPacket;
  8399.     }
  8400.  
  8401.     public void setLastAttackPacket()
  8402.     {
  8403.         _lastAttackPacket = System.currentTimeMillis();
  8404.     }
  8405.  
  8406.     private long _lastMovePacket = 0;
  8407.  
  8408.     public long getLastMovePacket()
  8409.     {
  8410.         return _lastMovePacket;
  8411.     }
  8412.  
  8413.     public void setLastMovePacket()
  8414.     {
  8415.         _lastMovePacket = System.currentTimeMillis();
  8416.     }
  8417.  
  8418.     public byte[] getKeyBindings()
  8419.     {
  8420.         return _keyBindings;
  8421.     }
  8422.  
  8423.     public void setKeyBindings(byte[] keyBindings)
  8424.     {
  8425.         if(keyBindings == null)
  8426.             keyBindings = ArrayUtils.EMPTY_BYTE_ARRAY;
  8427.         _keyBindings = keyBindings;
  8428.     }
  8429.  
  8430.     /**
  8431.      * Возвращает коллекцию Ñ�киллов, Ñ� учетом текущей транÑ�формации
  8432.      */
  8433.     @Override
  8434.     public final Collection<SkillEntry> getAllSkills()
  8435.     {
  8436.         // ТранÑ�формациÑ� неактивна
  8437.         if(!isTransformed())
  8438.             return super.getAllSkills();
  8439.  
  8440.         // ТранÑ�формациÑ� активна
  8441.         IntObjectMap<SkillEntry> temp = new HashIntObjectMap<SkillEntry>();
  8442.         for(SkillEntry skillEntry : super.getAllSkills())
  8443.         {
  8444.             Skill skill = skillEntry.getTemplate();
  8445.             if(!skill.isActive() && !skill.isToggle())
  8446.                 temp.put(skillEntry.getId(), skillEntry);
  8447.         }
  8448.  
  8449.         temp.putAll(_transformSkills); // ДобавлÑ�ем к паÑ�Ñ�ивкам Ñ�килы текущей транÑ�формации
  8450.         return temp.values();
  8451.     }
  8452.  
  8453.     public final void addTransformSkill(SkillEntry skillEntry)
  8454.     {
  8455.         _transformSkills.put(skillEntry.getId(), skillEntry);
  8456.     }
  8457.  
  8458.     public final void removeTransformSkill(SkillEntry skillEntry)
  8459.     {
  8460.         _transformSkills.remove(skillEntry.getId());
  8461.     }
  8462.  
  8463.     public void setAgathion(int id)
  8464.     {
  8465.         if(_agathionId == id)
  8466.             return;
  8467.  
  8468.         _agathionId = id;
  8469.  
  8470.         sendPacket(new ExUserInfoCubic(this));
  8471.         broadcastCharInfo();
  8472.     }
  8473.  
  8474.     public int getAgathionId()
  8475.     {
  8476.         return _agathionId;
  8477.     }
  8478.  
  8479.     /**
  8480.      * Возвращает количеÑ�тво PcBangPoint'ов даного игрока
  8481.      *
  8482.      * @return количеÑ�тво PcCafe Bang Points
  8483.      */
  8484.     public int getPcBangPoints()
  8485.     {
  8486.         return _pcBangPoints;
  8487.     }
  8488.  
  8489.     /**
  8490.      * УÑ�танавливает количеÑ�тво Pc Cafe Bang Points длÑ� даного игрока
  8491.      *
  8492.      * @param val новое количеÑ�тво PcCafeBangPoints
  8493.      */
  8494.     public void setPcBangPoints(int val)
  8495.     {
  8496.         _pcBangPoints = val;
  8497.     }
  8498.  
  8499.     public void addPcBangPoints(int count, boolean doublePoints, boolean notify)
  8500.     {
  8501.         if(doublePoints)
  8502.             count *= 2;
  8503.  
  8504.         _pcBangPoints += count;
  8505.  
  8506.         if(count > 0 && notify)
  8507.             sendPacket(new SystemMessage(doublePoints ? SystemMessage.DOUBLE_POINTS_YOU_AQUIRED_S1_PC_BANG_POINT : SystemMessage.YOU_ACQUIRED_S1_PC_BANG_POINT).addNumber(count));
  8508.         sendPacket(new ExPCCafePointInfoPacket(this, count, 1, 2, 12));
  8509.     }
  8510.  
  8511.     public boolean reducePcBangPoints(int count)
  8512.     {
  8513.         if(_pcBangPoints < count)
  8514.             return false;
  8515.  
  8516.         _pcBangPoints -= count;
  8517.         sendPacket(new SystemMessage(SystemMessage.YOU_ARE_USING_S1_POINT).addNumber(count));
  8518.         sendPacket(new ExPCCafePointInfoPacket(this, 0, 1, 2, 12));
  8519.         return true;
  8520.     }
  8521.  
  8522.     private Location _groundSkillLoc;
  8523.  
  8524.     public void setGroundSkillLoc(Location location)
  8525.     {
  8526.         _groundSkillLoc = location;
  8527.     }
  8528.  
  8529.     public Location getGroundSkillLoc()
  8530.     {
  8531.         return _groundSkillLoc;
  8532.     }
  8533.  
  8534.     /**
  8535.      * ПерÑ�онаж в процеÑ�Ñ�е выхода из игры
  8536.      *
  8537.      * @return возвращает true еÑ�ли процеÑ�Ñ� выхода уже началÑ�Ñ�
  8538.      */
  8539.     public boolean isLogoutStarted()
  8540.     {
  8541.         if(_isLogout == null)
  8542.             return false;
  8543.  
  8544.         return _isLogout.get();
  8545.     }
  8546.  
  8547.     public void setOfflineMode(boolean val)
  8548.     {
  8549.         if(!val)
  8550.             unsetVar("offline");
  8551.         _offline = val;
  8552.     }
  8553.  
  8554.     public boolean isInOfflineMode()
  8555.     {
  8556.         return _offline;
  8557.     }
  8558.  
  8559.     public void storePrivateStore()
  8560.     {
  8561.         int storeType = getPrivateStoreType();
  8562.         if(storeType == 0)
  8563.             unsetVar("storemode");
  8564.         else if(Config.ALT_SAVE_PRIVATE_STORE || isInOfflineMode())
  8565.             setVar("storemode", storeType);
  8566.  
  8567.         if(_sellList != null && !_sellList.isEmpty() && (Config.ALT_SAVE_PRIVATE_STORE || (isInOfflineMode() && storeType == STORE_PRIVATE_SELL)))
  8568.         {
  8569.             StringBuilder items = new StringBuilder();
  8570.  
  8571.             for(TradeItem i : _sellList)
  8572.             {
  8573.                 items.append(i.getObjectId());
  8574.                 items.append(";");
  8575.                 items.append(i.getCount());
  8576.                 items.append(";");
  8577.                 items.append(i.getOwnersPrice());
  8578.                 items.append(":");
  8579.             }
  8580.             setVar("selllist", items.toString(), -1);
  8581.             String title = getSellStoreName();
  8582.             if(title != null && !title.isEmpty())
  8583.                 setVar("sellstorename", title, -1);
  8584.             else
  8585.                 unsetVar("sellstorename");
  8586.         }
  8587.         else
  8588.         {
  8589.             unsetVar("selllist");
  8590.             unsetVar("sellstorename");
  8591.         }
  8592.  
  8593.         if(_packageSellList != null && !_packageSellList.isEmpty() && (Config.ALT_SAVE_PRIVATE_STORE || (isInOfflineMode() && storeType == STORE_PRIVATE_SELL_PACKAGE)))
  8594.         {
  8595.             StringBuilder items = new StringBuilder();
  8596.             for(TradeItem i : _packageSellList)
  8597.             {
  8598.                 items.append(i.getObjectId());
  8599.                 items.append(";");
  8600.                 items.append(i.getCount());
  8601.                 items.append(";");
  8602.                 items.append(i.getOwnersPrice());
  8603.                 items.append(":");
  8604.             }
  8605.             setVar("packageselllist", items.toString(), -1);
  8606.             String title = getPackageSellStoreName();
  8607.             if(title != null && !title.isEmpty())
  8608.                 setVar("packagesellstorename", title, -1);
  8609.             else
  8610.                 unsetVar("packagesellstorename");
  8611.         }
  8612.         else
  8613.         {
  8614.             unsetVar("packageselllist");
  8615.             unsetVar("packagesellstorename");
  8616.         }
  8617.  
  8618.         if(_buyList != null && !_buyList.isEmpty() && (Config.ALT_SAVE_PRIVATE_STORE || (isInOfflineMode() && storeType == STORE_PRIVATE_BUY)))
  8619.         {
  8620.             StringBuilder items = new StringBuilder();
  8621.             for(TradeItem i : _buyList)
  8622.             {
  8623.                 items.append(i.getItemId());
  8624.                 items.append(";");
  8625.                 items.append(i.getCount());
  8626.                 items.append(";");
  8627.                 items.append(i.getOwnersPrice());
  8628.                 items.append(";");
  8629.                 items.append(i.getEnchantLevel());
  8630.                 items.append(":");
  8631.             }
  8632.             setVar("buylist", items.toString(), -1);
  8633.             String title = getBuyStoreName();
  8634.             if(title != null && !title.isEmpty())
  8635.                 setVar("buystorename", title, -1);
  8636.             else
  8637.                 unsetVar("buystorename");
  8638.         }
  8639.         else
  8640.         {
  8641.             unsetVar("buylist");
  8642.             unsetVar("buystorename");
  8643.         }
  8644.  
  8645.         if(_createList != null && !_createList.isEmpty() && (Config.ALT_SAVE_PRIVATE_STORE || (isInOfflineMode() && storeType == STORE_PRIVATE_MANUFACTURE)))
  8646.         {
  8647.             StringBuilder items = new StringBuilder();
  8648.             for(ManufactureItem i : _createList)
  8649.             {
  8650.                 items.append(i.getRecipeId());
  8651.                 items.append(";");
  8652.                 items.append(i.getCost());
  8653.                 items.append(":");
  8654.             }
  8655.             setVar("createlist", items.toString(), -1);
  8656.             String title = getManufactureName();
  8657.             if(title != null && !title.isEmpty())
  8658.                 setVar("manufacturename", title, -1);
  8659.             else
  8660.                 unsetVar("manufacturename");
  8661.         }
  8662.         else
  8663.         {
  8664.             unsetVar("createlist");
  8665.             unsetVar("manufacturename");
  8666.         }
  8667.     }
  8668.  
  8669.     public void restorePrivateStore()
  8670.     {
  8671.         String var;
  8672.         var = getVar("selllist");
  8673.         if(var != null)
  8674.         {
  8675.             _sellList = new CopyOnWriteArrayList<TradeItem>();
  8676.             String[] items = var.split(":");
  8677.             for(String item : items)
  8678.             {
  8679.                 if(item.equals(""))
  8680.                     continue;
  8681.                 String[] values = item.split(";");
  8682.                 if(values.length < 3)
  8683.                     continue;
  8684.  
  8685.                 int oId = Integer.parseInt(values[0]);
  8686.                 long count = Long.parseLong(values[1]);
  8687.                 long price = Long.parseLong(values[2]);
  8688.  
  8689.                 ItemInstance itemToSell = getInventory().getItemByObjectId(oId);
  8690.  
  8691.                 if(count < 1 || itemToSell == null)
  8692.                     continue;
  8693.  
  8694.                 if(count > itemToSell.getCount())
  8695.                     count = itemToSell.getCount();
  8696.  
  8697.                 TradeItem i = new TradeItem(itemToSell);
  8698.                 i.setCount(count);
  8699.                 i.setOwnersPrice(price);
  8700.  
  8701.                 _sellList.add(i);
  8702.             }
  8703.             var = getVar("sellstorename");
  8704.             if(var != null)
  8705.                 setSellStoreName(var);
  8706.         }
  8707.         var = getVar("packageselllist");
  8708.         if(var != null)
  8709.         {
  8710.             _packageSellList = new CopyOnWriteArrayList<TradeItem>();
  8711.             String[] items = var.split(":");
  8712.             for(String item : items)
  8713.             {
  8714.                 if(item.equals(""))
  8715.                     continue;
  8716.                 String[] values = item.split(";");
  8717.                 if(values.length < 3)
  8718.                     continue;
  8719.  
  8720.                 int oId = Integer.parseInt(values[0]);
  8721.                 long count = Long.parseLong(values[1]);
  8722.                 long price = Long.parseLong(values[2]);
  8723.  
  8724.                 ItemInstance itemToSell = getInventory().getItemByObjectId(oId);
  8725.  
  8726.                 if(count < 1 || itemToSell == null)
  8727.                     continue;
  8728.  
  8729.                 if(count > itemToSell.getCount())
  8730.                     count = itemToSell.getCount();
  8731.  
  8732.                 TradeItem i = new TradeItem(itemToSell);
  8733.                 i.setCount(count);
  8734.                 i.setOwnersPrice(price);
  8735.  
  8736.                 _packageSellList.add(i);
  8737.             }
  8738.             var = getVar("packagesellstorename");
  8739.             if(var != null)
  8740.                 setPackageSellStoreName(var);
  8741.         }
  8742.         var = getVar("buylist");
  8743.         if(var != null)
  8744.         {
  8745.             _buyList = new CopyOnWriteArrayList<TradeItem>();
  8746.             String[] items = var.split(":");
  8747.             for(String item : items)
  8748.             {
  8749.                 if(item.equals(""))
  8750.                     continue;
  8751.                 String[] values = item.split(";");
  8752.                 if(values.length < 3)
  8753.                     continue;
  8754.                 TradeItem i = new TradeItem();
  8755.                 i.setItemId(Integer.parseInt(values[0]));
  8756.                 i.setCount(Long.parseLong(values[1]));
  8757.                 i.setOwnersPrice(Long.parseLong(values[2]));
  8758.                 if(values.length > 3)
  8759.                     i.setEnchantLevel(Integer.parseInt(values[3]));
  8760.  
  8761.                 _buyList.add(i);
  8762.             }
  8763.             var = getVar("buystorename");
  8764.             if(var != null)
  8765.                 setBuyStoreName(var);
  8766.         }
  8767.         var = getVar("createlist");
  8768.         if(var != null)
  8769.         {
  8770.             _createList = new CopyOnWriteArrayList<ManufactureItem>();
  8771.             String[] items = var.split(":");
  8772.             for(String item : items)
  8773.             {
  8774.                 if(item.equals(""))
  8775.                     continue;
  8776.                 String[] values = item.split(";");
  8777.                 if(values.length < 2)
  8778.                     continue;
  8779.                 int recId = Integer.parseInt(values[0]);
  8780.                 long price = Long.parseLong(values[1]);
  8781.                 if(findRecipe(recId))
  8782.                     _createList.add(new ManufactureItem(recId, price));
  8783.             }
  8784.             var = getVar("manufacturename");
  8785.             if(var != null)
  8786.                 setManufactureName(var);
  8787.         }
  8788.  
  8789.         int storeType = getVarInt("storemode", 0);
  8790.         if(storeType != 0)
  8791.         {
  8792.             setPrivateStoreType(storeType);
  8793.             setSitting(true);
  8794.         }
  8795.     }
  8796.  
  8797.     public void restoreRecipeBook()
  8798.     {
  8799.         Connection con = null;
  8800.         PreparedStatement statement = null;
  8801.         ResultSet rset = null;
  8802.         try
  8803.         {
  8804.             con = DatabaseFactory.getInstance().getConnection();
  8805.             statement = con.prepareStatement("SELECT id FROM character_recipebook WHERE char_id=?");
  8806.             statement.setInt(1, getObjectId());
  8807.             rset = statement.executeQuery();
  8808.  
  8809.             while(rset.next())
  8810.             {
  8811.                 int id = rset.getInt("id");
  8812.                 RecipeTemplate recipe = RecipeHolder.getInstance().getRecipeByRecipeId(id);
  8813.                 registerRecipe(recipe, false);
  8814.             }
  8815.         }
  8816.         catch(Exception e)
  8817.         {
  8818.             _log.warn("count not recipe skills:" + e);
  8819.             _log.error("", e);
  8820.         }
  8821.         finally
  8822.         {
  8823.             DbUtils.closeQuietly(con, statement, rset);
  8824.         }
  8825.     }
  8826.  
  8827.     public List<DecoyInstance> getDecoys()
  8828.     {
  8829.         return _decoys;
  8830.     }
  8831.  
  8832.     public void addDecoy(DecoyInstance decoy)
  8833.     {
  8834.         _decoys.add(decoy);
  8835.     }
  8836.  
  8837.     public void removeDecoy(DecoyInstance decoy)
  8838.     {
  8839.         _decoys.remove(decoy);
  8840.     }
  8841.  
  8842.     public MountType getMountType()
  8843.     {
  8844.         return _mount == null ? MountType.NONE : _mount.getType();
  8845.     }
  8846.  
  8847.     @Override
  8848.     public boolean setReflection(Reflection reflection)
  8849.     {
  8850.         if(getReflection() == reflection)
  8851.             return true;
  8852.  
  8853.         if(!super.setReflection(reflection))
  8854.             return false;
  8855.  
  8856.         for(Servitor servitor : getServitors())
  8857.         {
  8858.             if(!servitor.isDead())
  8859.                 servitor.setReflection(reflection);
  8860.         }
  8861.  
  8862.         if(!reflection.isMain())
  8863.         {
  8864.             String var = getVar("reflection");
  8865.             if(var == null || !var.equals(String.valueOf(reflection.getId())))
  8866.                 setVar("reflection", String.valueOf(reflection.getId()), -1);
  8867.         }
  8868.         else
  8869.             unsetVar("reflection");
  8870.  
  8871.         return true;
  8872.     }
  8873.  
  8874.     private int _buyListId;
  8875.  
  8876.     public void setBuyListId(int listId)
  8877.     {
  8878.         _buyListId = listId;
  8879.     }
  8880.  
  8881.     public int getBuyListId()
  8882.     {
  8883.         return _buyListId;
  8884.     }
  8885.  
  8886.     public int getFame()
  8887.     {
  8888.         return _fame;
  8889.     }
  8890.  
  8891.     public void setFame(int fame, String log, boolean notify)
  8892.     {
  8893.         fame = Math.min(Config.LIM_FAME, fame);
  8894.         if(log != null && !log.isEmpty())
  8895.             Log.add(_name + "|" + (fame - _fame) + "|" + fame + "|" + log, "fame");
  8896.         if(fame > _fame && notify)
  8897.             sendPacket(new SystemMessage(SystemMessage.YOU_HAVE_ACQUIRED_S1_REPUTATION_SCORE).addNumber(fame - _fame));
  8898.         _fame = fame;
  8899.         sendChanges();
  8900.     }
  8901.  
  8902.     private final int _incorrectValidateCount = 0;
  8903.  
  8904.     public int getIncorrectValidateCount()
  8905.     {
  8906.         return _incorrectValidateCount;
  8907.     }
  8908.  
  8909.     public int setIncorrectValidateCount(int count)
  8910.     {
  8911.         return _incorrectValidateCount;
  8912.     }
  8913.  
  8914.     public int getExpandInventory()
  8915.     {
  8916.         return _expandInventory;
  8917.     }
  8918.  
  8919.     public void setExpandInventory(int inventory)
  8920.     {
  8921.         _expandInventory = inventory;
  8922.     }
  8923.  
  8924.     public int getExpandWarehouse()
  8925.     {
  8926.         return _expandWarehouse;
  8927.     }
  8928.  
  8929.     public void setExpandWarehouse(int warehouse)
  8930.     {
  8931.         _expandWarehouse = warehouse;
  8932.     }
  8933.  
  8934.     public boolean isNotShowBuffAnim()
  8935.     {
  8936.         return _notShowBuffAnim;
  8937.     }
  8938.  
  8939.     public void setNotShowBuffAnim(boolean value)
  8940.     {
  8941.         _notShowBuffAnim = value;
  8942.     }
  8943.  
  8944.     public boolean canSeeAllShouts()
  8945.     {
  8946.         return _canSeeAllShouts;
  8947.     }
  8948.  
  8949.     public void setCanSeeAllShouts(boolean b)
  8950.     {
  8951.         _canSeeAllShouts = b;
  8952.     }
  8953.  
  8954.     public void enterMovieMode()
  8955.     {
  8956.         if(isInMovie()) //already in movie
  8957.             return;
  8958.  
  8959.         setTarget(null);
  8960.         stopMove();
  8961.         setMovieId(-1);
  8962.         sendPacket(new CameraModePacket(1));
  8963.     }
  8964.  
  8965.     public void leaveMovieMode()
  8966.     {
  8967.         setMovieId(0);
  8968.         sendPacket(new CameraModePacket(0));
  8969.         broadcastCharInfo();
  8970.     }
  8971.  
  8972.     public void specialCamera(GameObject target, int dist, int yaw, int pitch, int time, int duration)
  8973.     {
  8974.         sendPacket(new SpecialCameraPacket(target.getObjectId(), dist, yaw, pitch, time, duration));
  8975.     }
  8976.  
  8977.     public void specialCamera(GameObject target, int dist, int yaw, int pitch, int time, int duration, int turn, int rise, int widescreen, int unk)
  8978.     {
  8979.         sendPacket(new SpecialCameraPacket(target.getObjectId(), dist, yaw, pitch, time, duration, turn, rise, widescreen, unk));
  8980.     }
  8981.  
  8982.     private int _movieId = 0;
  8983.  
  8984.     public void setMovieId(int id)
  8985.     {
  8986.         _movieId = id;
  8987.     }
  8988.  
  8989.     public int getMovieId()
  8990.     {
  8991.         return _movieId;
  8992.     }
  8993.  
  8994.     public boolean isInMovie()
  8995.     {
  8996.         return _movieId != 0 && !isFakePlayer();
  8997.     }
  8998.  
  8999.     public void startScenePlayer(SceneMovie movie)
  9000.     {
  9001.         if(isInMovie()) //already in movie
  9002.             return;
  9003.  
  9004.         sendActionFailed();
  9005.         setTarget(null);
  9006.         stopMove();
  9007.         setMovieId(movie.getId());
  9008.         sendPacket(movie.packet(this));
  9009.     }
  9010.  
  9011.     public void startScenePlayer(int movieId)
  9012.     {
  9013.         if(isInMovie()) //already in movie
  9014.             return;
  9015.  
  9016.         sendActionFailed();
  9017.         setTarget(null);
  9018.         stopMove();
  9019.         setMovieId(movieId);
  9020.         sendPacket(new ExStartScenePlayer(movieId));
  9021.     }
  9022.  
  9023.     public void endScenePlayer()
  9024.     {
  9025.         if(!isInMovie())
  9026.             return;
  9027.  
  9028.         setMovieId(0);
  9029.         decayMe();
  9030.         spawnMe();
  9031.     }
  9032.  
  9033.     public void setAutoLoot(boolean enable)
  9034.     {
  9035.         if(Config.AUTO_LOOT_INDIVIDUAL)
  9036.         {
  9037.             _autoLoot = enable;
  9038.             setVar("AutoLoot", String.valueOf(enable), -1);
  9039.         }
  9040.     }
  9041.  
  9042.     public void setAutoLootOnlyAdena(boolean enable)
  9043.     {
  9044.         if(Config.AUTO_LOOT_INDIVIDUAL && Config.AUTO_LOOT_ONLY_ADENA)
  9045.         {
  9046.             _autoLootOnlyAdena = enable;
  9047.             setVar("AutoLootOnlyAdena", String.valueOf(enable), -1);
  9048.         }
  9049.     }
  9050.  
  9051.     public void setAutoLootHerbs(boolean enable)
  9052.     {
  9053.         if(Config.AUTO_LOOT_INDIVIDUAL)
  9054.         {
  9055.             AutoLootHerbs = enable;
  9056.             setVar("AutoLootHerbs", String.valueOf(enable), -1);
  9057.         }
  9058.     }
  9059.  
  9060.     public boolean isAutoLootEnabled()
  9061.     {
  9062.         return _autoLoot;
  9063.     }
  9064.  
  9065.     public boolean isAutoLootOnlyAdenaEnabled()
  9066.     {
  9067.         return _autoLootOnlyAdena;
  9068.     }
  9069.  
  9070.     public boolean isAutoLootHerbsEnabled()
  9071.     {
  9072.         return AutoLootHerbs;
  9073.     }
  9074.  
  9075.     public final void reName(String name, boolean saveToDB)
  9076.     {
  9077.         setName(name);
  9078.         if(saveToDB)
  9079.         {
  9080.             saveNameToDB();
  9081.             OlympiadParticipiantData participant = Olympiad.getParticipantInfo(getObjectId());
  9082.             if(participant != null)
  9083.                 participant.setName(name);
  9084.         }
  9085.         broadcastUserInfo(true);
  9086.     }
  9087.  
  9088.     public final void reName(String name)
  9089.     {
  9090.         reName(name, false);
  9091.     }
  9092.  
  9093.     public final void saveNameToDB()
  9094.     {
  9095.         Connection con = null;
  9096.         PreparedStatement st = null;
  9097.         try
  9098.         {
  9099.             con = DatabaseFactory.getInstance().getConnection();
  9100.             st = con.prepareStatement("UPDATE characters SET char_name = ? WHERE obj_Id = ?");
  9101.             st.setString(1, getName());
  9102.             st.setInt(2, getObjectId());
  9103.             st.executeUpdate();
  9104.         }
  9105.         catch(Exception e)
  9106.         {
  9107.             _log.error("", e);
  9108.         }
  9109.         finally
  9110.         {
  9111.             DbUtils.closeQuietly(con, st);
  9112.         }
  9113.     }
  9114.  
  9115.     @Override
  9116.     public Player getPlayer()
  9117.     {
  9118.         return this;
  9119.     }
  9120.  
  9121.     public BypassStorage getBypassStorage()
  9122.     {
  9123.         return _bypassStorage;
  9124.     }
  9125.  
  9126.     public int getTalismanCount()
  9127.     {
  9128.         return (int) calcStat(Stats.TALISMANS_LIMIT, 0, null, null);
  9129.     }
  9130.  
  9131.     public int getJewelsLimit()
  9132.     {
  9133.         return (int) calcStat(Stats.JEWELS_LIMIT, 0, null, null);
  9134.     }
  9135.  
  9136.     public final void disableDrop(int time)
  9137.     {
  9138.         _dropDisabled = System.currentTimeMillis() + time;
  9139.     }
  9140.  
  9141.     public final boolean isDropDisabled()
  9142.     {
  9143.         return _dropDisabled > System.currentTimeMillis();
  9144.     }
  9145.  
  9146.     private ItemInstance _petControlItem = null;
  9147.  
  9148.     public void setPetControlItem(int itemObjId)
  9149.     {
  9150.         setPetControlItem(getInventory().getItemByObjectId(itemObjId));
  9151.     }
  9152.  
  9153.     public void setPetControlItem(ItemInstance item)
  9154.     {
  9155.         _petControlItem = item;
  9156.     }
  9157.  
  9158.     public ItemInstance getPetControlItem()
  9159.     {
  9160.         return _petControlItem;
  9161.     }
  9162.  
  9163.     private AtomicBoolean isActive = new AtomicBoolean();
  9164.  
  9165.     public boolean isActive()
  9166.     {
  9167.         return isActive.get();
  9168.     }
  9169.  
  9170.     public void setActive()
  9171.     {
  9172.         setNonAggroTime(0);
  9173.         setNonPvpTime(0);
  9174.  
  9175.         if(isActive.getAndSet(true))
  9176.             return;
  9177.  
  9178.         onActive();
  9179.     }
  9180.  
  9181.     private void onActive()
  9182.     {
  9183.         sendPacket(SystemMsg.YOU_ARE_NO_LONGER_PROTECTED_FROM_AGGRESSIVE_MONSTERS);
  9184.  
  9185.         if(getPetControlItem() != null || _restoredSummons != null && !_restoredSummons.isEmpty())
  9186.         {
  9187.             ThreadPoolManager.getInstance().execute(() ->
  9188.             {
  9189.                 if(getPetControlItem() != null)
  9190.                     summonPet();
  9191.  
  9192.                 if(_restoredSummons != null && !_restoredSummons.isEmpty())
  9193.                     spawnRestoredSummons();
  9194.             });
  9195.         }
  9196.     }
  9197.  
  9198.     public void summonPet()
  9199.     {
  9200.         if(getPet() != null)
  9201.             return;
  9202.  
  9203.         ItemInstance controlItem = getInventory().getItemByObjectId(getPetControlItem().getObjectId());
  9204.         if(controlItem == null)
  9205.         {
  9206.             setPetControlItem(null);
  9207.             return;
  9208.         }
  9209.  
  9210.         PetData petTemplate = PetDataHolder.getInstance().getTemplateByItemId(controlItem.getItemId());
  9211.         if(petTemplate == null)
  9212.         {
  9213.             setPetControlItem(null);
  9214.             return;
  9215.         }
  9216.  
  9217.         NpcTemplate npcTemplate = NpcHolder.getInstance().getTemplate(petTemplate.getNpcId());
  9218.         if(npcTemplate == null)
  9219.         {
  9220.             setPetControlItem(null);
  9221.             return;
  9222.         }
  9223.  
  9224.         PetInstance pet = PetInstance.restore(controlItem, npcTemplate, this);
  9225.         if(pet == null)
  9226.         {
  9227.             setPetControlItem(null);
  9228.             return;
  9229.         }
  9230.  
  9231.         setPet(pet);
  9232.         pet.setTitle(Servitor.TITLE_BY_OWNER_NAME);
  9233.  
  9234.         if(!pet.isRespawned())
  9235.         {
  9236.             pet.setCurrentHp(pet.getMaxHp(), false);
  9237.             pet.setCurrentMp(pet.getMaxMp());
  9238.             pet.setCurrentFed(pet.getMaxFed(), false);
  9239.             pet.updateControlItem();
  9240.             pet.store();
  9241.         }
  9242.  
  9243.         pet.getInventory().restore();
  9244.  
  9245.         pet.setNonAggroTime(System.currentTimeMillis() + Config.NONAGGRO_TIME_ONTELEPORT);
  9246.         pet.setNonPvpTime(System.currentTimeMillis() + Config.NONPVP_TIME_ONTELEPORT);
  9247.         pet.setReflection(getReflection());
  9248.         pet.spawnMe(Location.findPointToStay(this, 50, 70));
  9249.         pet.setRunning();
  9250.         pet.setFollowMode(true);
  9251.         pet.getInventory().validateItems();
  9252.  
  9253.         if(pet instanceof PetBabyInstance)
  9254.             ((PetBabyInstance) pet).startBuffTask();
  9255.  
  9256.         getListeners().onSummonServitor(pet);
  9257.     }
  9258.  
  9259.     public void restoreSummons()
  9260.     {
  9261.         _restoredSummons = SummonsDAO.getInstance().restore(this);
  9262.     }
  9263.  
  9264.     private void spawnRestoredSummons()
  9265.     {
  9266.         if(_restoredSummons == null || _restoredSummons.isEmpty())
  9267.             return;
  9268.  
  9269.         for(RestoredSummon summon : _restoredSummons)
  9270.         {
  9271.             Skill skill = SkillHolder.getInstance().getSkill(summon.skillId, summon.skillLvl);
  9272.             if(skill == null)
  9273.                 continue;
  9274.  
  9275.             if(skill instanceof Summon)
  9276.                 ((Summon) skill).summon(this, null, summon);
  9277.         }
  9278.         _restoredSummons.clear();
  9279.         _restoredSummons = null;
  9280.     }
  9281.  
  9282.     public List<TrapInstance> getTraps()
  9283.     {
  9284.         return _traps;
  9285.     }
  9286.  
  9287.     public void addTrap(TrapInstance trap)
  9288.     {
  9289.         if(_traps == Collections.<TrapInstance>emptyList())
  9290.             _traps = new CopyOnWriteArrayList<TrapInstance>();
  9291.         _traps.add(trap);
  9292.     }
  9293.  
  9294.     public void removeTrap(TrapInstance trap)
  9295.     {
  9296.         _traps.remove(trap);
  9297.     }
  9298.    
  9299.     public void destroyAllTraps()
  9300.     {
  9301.         for(TrapInstance t : _traps)
  9302.             t.deleteMe();
  9303.     }
  9304.  
  9305.     @Override
  9306.     public PlayerListenerList getListeners()
  9307.     {
  9308.         if(listeners == null)
  9309.             synchronized (this)
  9310.             {
  9311.                 if(listeners == null)
  9312.                     listeners = new PlayerListenerList(this);
  9313.             }
  9314.         return (PlayerListenerList) listeners;
  9315.     }
  9316.  
  9317.     @Override
  9318.     public PlayerStatsChangeRecorder getStatsRecorder()
  9319.     {
  9320.         if(_statsRecorder == null)
  9321.             synchronized (this)
  9322.             {
  9323.                 if(_statsRecorder == null)
  9324.                     _statsRecorder = new PlayerStatsChangeRecorder(this);
  9325.             }
  9326.         return (PlayerStatsChangeRecorder) _statsRecorder;
  9327.     }
  9328.  
  9329.     private Future<?> _hourlyTask;
  9330.     private int _hoursInGame = 0;
  9331.  
  9332.     public int getHoursInGame()
  9333.     {
  9334.         _hoursInGame++;
  9335.         return _hoursInGame;
  9336.     }
  9337.  
  9338.     public void startHourlyTask()
  9339.     {
  9340.         _hourlyTask = ThreadPoolManager.getInstance().scheduleAtFixedRate(new HourlyTask(this), 3600000L, 3600000L);
  9341.     }
  9342.  
  9343.     public void stopHourlyTask()
  9344.     {
  9345.         if(_hourlyTask != null)
  9346.         {
  9347.             _hourlyTask.cancel(false);
  9348.             _hourlyTask = null;
  9349.         }
  9350.     }
  9351.  
  9352.     public long getPremiumPoints()
  9353.     {
  9354.         if(Config.IM_PAYMENT_ITEM_ID > 0)
  9355.             return ItemFunctions.getItemCount(this, Config.IM_PAYMENT_ITEM_ID);
  9356.  
  9357.         if(getNetConnection() != null)
  9358.             return getNetConnection().getPoints();
  9359.  
  9360.         return 0;
  9361.     }
  9362.  
  9363.     public boolean reducePremiumPoints(final int val)
  9364.     {
  9365.         if(Config.IM_PAYMENT_ITEM_ID > 0)
  9366.         {
  9367.             if(ItemFunctions.deleteItem(this, Config.IM_PAYMENT_ITEM_ID, val, true))
  9368.                 return true;
  9369.             return false;
  9370.         }
  9371.  
  9372.         if(getNetConnection() != null)
  9373.         {
  9374.             getNetConnection().setPoints((int) (getPremiumPoints() - val));
  9375.             AuthServerCommunication.getInstance().sendPacket(new ReduceAccountPoints(getAccountName(), val));
  9376.             return true;
  9377.         }
  9378.         return false;
  9379.     }
  9380.  
  9381.     private boolean _agathionResAvailable = false;
  9382.  
  9383.     public boolean isAgathionResAvailable()
  9384.     {
  9385.         return _agathionResAvailable;
  9386.     }
  9387.  
  9388.     public void setAgathionRes(boolean val)
  9389.     {
  9390.         _agathionResAvailable = val;
  9391.     }
  9392.  
  9393.     /**
  9394.      * _userSession - иÑ�польюзуетÑ�Ñ� длÑ� хранениÑ� временных переменных.
  9395.      */
  9396.     private Map<String, String> _userSession;
  9397.  
  9398.     public String getSessionVar(String key)
  9399.     {
  9400.         if(_userSession == null)
  9401.             return null;
  9402.         return _userSession.get(key);
  9403.     }
  9404.  
  9405.     public void setSessionVar(String key, String val)
  9406.     {
  9407.         if(_userSession == null)
  9408.             _userSession = new ConcurrentHashMap<String, String>();
  9409.  
  9410.         if(val == null || val.isEmpty())
  9411.             _userSession.remove(key);
  9412.         else
  9413.             _userSession.put(key, val);
  9414.     }
  9415.  
  9416.     public BlockList getBlockList()
  9417.     {
  9418.         return _blockList;
  9419.     }
  9420.  
  9421.     public FriendList getFriendList()
  9422.     {
  9423.         return _friendList;
  9424.     }
  9425.  
  9426.     public PremiumItemList getPremiumItemList()
  9427.     {
  9428.         return _premiumItemList;
  9429.     }
  9430.  
  9431.     public ProductHistoryList getProductHistoryList()
  9432.     {
  9433.         return _productHistoryList;
  9434.     }
  9435.  
  9436.     public HennaList getHennaList()
  9437.     {
  9438.         return _hennaList;
  9439.     }
  9440.  
  9441.     public AttendanceRewards getAttendanceRewards()
  9442.     {
  9443.         return _attendanceRewards;
  9444.     }
  9445.  
  9446.     public DailyMissionList getDailyMissionList()
  9447.     {
  9448.         return _dailiyMissionList;
  9449.     }
  9450.  
  9451.     public boolean isNotShowTraders()
  9452.     {
  9453.         return _notShowTraders;
  9454.     }
  9455.  
  9456.     public void setNotShowTraders(boolean notShowTraders)
  9457.     {
  9458.         _notShowTraders = notShowTraders;
  9459.     }
  9460.  
  9461.     public boolean isDebug()
  9462.     {
  9463.         return _debug;
  9464.     }
  9465.  
  9466.     public void setDebug(boolean b)
  9467.     {
  9468.         _debug = b;
  9469.     }
  9470.  
  9471.     public void sendItemList(boolean show)
  9472.     {
  9473.         final ItemInstance[] items = getInventory().getItems();
  9474.         final LockType lockType = getInventory().getLockType();
  9475.         final int[] lockItems = getInventory().getLockItems();
  9476.  
  9477.         int allSize = items.length;
  9478.         int questItemsSize = 0;
  9479.         int agathionItemsSize = 0;
  9480.         for(ItemInstance item : items)
  9481.         {
  9482.             if(item.getTemplate().isQuest())
  9483.                 questItemsSize++;
  9484.         }
  9485.  
  9486.         sendPacket(new ItemListPacket(this, allSize - questItemsSize, items, show, lockType, lockItems));
  9487.         sendPacket(new ExQuestItemListPacket(questItemsSize, items, lockType, lockItems));
  9488.     }
  9489.  
  9490.     public int getBeltInventoryIncrease()
  9491.     {
  9492.         ItemInstance item = getInventory().getPaperdollItem(Inventory.PAPERDOLL_BELT);
  9493.         if(item != null && item.getTemplate().getAttachedSkills() != null)
  9494.         {
  9495.             for(SkillEntry skillEntry : item.getTemplate().getAttachedSkills())
  9496.             {
  9497.                 for(FuncTemplate func : skillEntry.getTemplate().getAttachedFuncs())
  9498.                 {
  9499.                     if(func._stat == Stats.INVENTORY_LIMIT)
  9500.                         return (int) func._value;
  9501.                 }
  9502.             }
  9503.         }
  9504.         return 0;
  9505.     }
  9506.  
  9507.     @Override
  9508.     public boolean isPlayer()
  9509.     {
  9510.         return true;
  9511.     }
  9512.  
  9513.     public boolean checkCoupleAction(Player target)
  9514.     {
  9515.         if(target.getPrivateStoreType() != Player.STORE_PRIVATE_NONE)
  9516.         {
  9517.             sendPacket(new SystemMessage(SystemMessage.COUPLE_ACTION_CANNOT_C1_TARGET_IN_PRIVATE_STORE).addName(target));
  9518.             return false;
  9519.         }
  9520.         if(target.isFishing())
  9521.         {
  9522.             sendPacket(new SystemMessage(SystemMessage.COUPLE_ACTION_CANNOT_C1_TARGET_IS_FISHING).addName(target));
  9523.             return false;
  9524.         }
  9525.         if(target.isInTrainingCamp())
  9526.         {
  9527.             sendPacket(SystemMsg.YOU_CANNOT_REQUEST_TO_A_CHARACTER_WHO_IS_ENTERING_THE_TRAINING_CAMP);
  9528.             return false;
  9529.         }
  9530.         if(target.isTransformed())
  9531.         {
  9532.             sendPacket(new SystemMessage(SystemMessage.COUPLE_ACTION_CANNOT_C1_TARGET_IS_IN_TRANSFORM).addName(target));
  9533.             return false;
  9534.         }
  9535.         if(target.isInCombat() || target.isVisualTransformed())
  9536.         {
  9537.             sendPacket(new SystemMessage(SystemMessage.COUPLE_ACTION_CANNOT_C1_TARGET_IS_IN_COMBAT).addName(target));
  9538.             return false;
  9539.         }
  9540.         if(target.isInOlympiadMode())
  9541.         {
  9542.             sendPacket(new SystemMessage(SystemMessage.COUPLE_ACTION_CANNOT_C1_TARGET_IS_IN_OLYMPIAD).addName(target));
  9543.             return false;
  9544.         }
  9545.         if(target.isInSiegeZone())
  9546.         {
  9547.             sendPacket(new SystemMessage(SystemMessage.COUPLE_ACTION_CANNOT_C1_TARGET_IS_IN_SIEGE).addName(target));
  9548.             return false;
  9549.         }
  9550.         if(target.isInBoat() || target.getMountNpcId() != 0)
  9551.         {
  9552.             sendPacket(new SystemMessage(SystemMessage.COUPLE_ACTION_CANNOT_C1_TARGET_IS_IN_VEHICLE_MOUNT_OTHER).addName(target));
  9553.             return false;
  9554.         }
  9555.         if(target.isTeleporting())
  9556.         {
  9557.             sendPacket(new SystemMessage(SystemMessage.COUPLE_ACTION_CANNOT_C1_TARGET_IS_TELEPORTING).addName(target));
  9558.             return false;
  9559.         }
  9560.         if(target.isDead())
  9561.         {
  9562.             sendPacket(new SystemMessage(SystemMessage.COUPLE_ACTION_CANNOT_C1_TARGET_IS_DEAD).addName(target));
  9563.             return false;
  9564.         }
  9565.         return true;
  9566.     }
  9567.  
  9568.     @Override
  9569.     public void startAttackStanceTask()
  9570.     {
  9571.         startAttackStanceTask0();
  9572.         for(Servitor servitor : getServitors())
  9573.             servitor.startAttackStanceTask0();
  9574.     }
  9575.  
  9576.     @Override
  9577.     public void displayGiveDamageMessage(Creature target, Skill skill, int damage, Servitor servitorTransferedDamage, int transferedDamage, boolean crit, boolean miss, boolean shld, boolean blocked)
  9578.     {
  9579.         super.displayGiveDamageMessage(target, skill, damage, servitorTransferedDamage, transferedDamage, crit, miss, shld, blocked);
  9580.  
  9581.         if(miss)
  9582.         {
  9583.             if(skill == null)
  9584.                 sendPacket(new SystemMessage(SystemMessage.C1S_ATTACK_WENT_ASTRAY).addName(this));
  9585.             else
  9586.                 sendPacket(new ExMagicAttackInfo(getObjectId(), target.getObjectId(), ExMagicAttackInfo.EVADED));
  9587.             return;
  9588.         }
  9589.  
  9590.         if(crit)
  9591.             if(skill != null)
  9592.             {
  9593.                 if(skill.isMagic())
  9594.                     sendPacket(SystemMsg.MAGIC_CRITICAL_HIT);
  9595.  
  9596.                 sendPacket(new ExMagicAttackInfo(getObjectId(), target.getObjectId(), ExMagicAttackInfo.CRITICAL));
  9597.             }
  9598.             else
  9599.                 sendPacket(new SystemMessage(SystemMessage.C1_HAD_A_CRITICAL_HIT).addName(this));
  9600.  
  9601.         if(blocked)
  9602.         {
  9603.             sendPacket(SystemMsg.THE_ATTACK_HAS_BEEN_BLOCKED);
  9604.             sendPacket(new ExMagicAttackInfo(getObjectId(), target.getObjectId(), target.isInvulnerable() ? ExMagicAttackInfo.IMMUNE : ExMagicAttackInfo.BLOCKED));
  9605.         }
  9606.         else if(target.isDoor() || (target instanceof SiegeToggleNpcInstance))
  9607.             sendPacket(new SystemMessagePacket(SystemMsg.YOU_HIT_FOR_S1_DAMAGE).addInteger(damage));
  9608.         else
  9609.         {
  9610.             if(servitorTransferedDamage != null && transferedDamage > 0)
  9611.             {
  9612.                 SystemMessagePacket sm = new SystemMessagePacket(SystemMsg.C1_INFLICTED_S3_DAMAGE_ON_C2_AND_S4_DAMAGE_ON_THE_DAMAGE_TRANSFER_TARGET);
  9613.                 sm.addName(this);
  9614.                 sm.addInteger(damage);
  9615.                 sm.addName(target);
  9616.                 sm.addInteger(transferedDamage);
  9617.                 sm.addHpChange(target.getObjectId(), getObjectId(), -damage);
  9618.                 sm.addHpChange(servitorTransferedDamage.getObjectId(), getObjectId(), -transferedDamage);
  9619.                 sendPacket(sm);
  9620.             }
  9621.             else
  9622.                 sendPacket(new SystemMessagePacket(SystemMsg.C1_HAS_DONE_S3_POINTS_OF_DAMAGE_TO_C2).addName(this).addName(target).addInteger(damage).addHpChange(target.getObjectId(), getObjectId(), -damage));
  9623.  
  9624.             if(shld)
  9625.             {
  9626.                 if(damage == Config.EXCELLENT_SHIELD_BLOCK_RECEIVED_DAMAGE)
  9627.                 {
  9628.                     if(skill != null && skill.isMagic())
  9629.                     {
  9630.                         sendPacket(new SystemMessagePacket(SystemMsg.C1_RESISTED_C2S_MAGIC).addName(target).addName(this));
  9631.                         sendPacket(new ExMagicAttackInfo(getObjectId(), target.getObjectId(), ExMagicAttackInfo.RESISTED));
  9632.                     }
  9633.                 }
  9634.                 else if(damage > 0 && skill != null && skill.isMagic())
  9635.                     sendPacket(new SystemMessagePacket(SystemMsg.YOUR_OPPONENT_HAS_RESISTANCE_TO_MAGIC_THE_DAMAGE_WAS_DECREASED));
  9636.             }
  9637.         }
  9638.     }
  9639.  
  9640.     @Override
  9641.     public void displayReceiveDamageMessage(Creature attacker, int damage)
  9642.     {
  9643.         if(attacker != this)
  9644.             sendPacket(new SystemMessagePacket(SystemMsg.C1_HAS_RECEIVED_S3_DAMAGE_FROM_C2).addName(this).addName(attacker).addInteger(damage).addHpChange(getObjectId(), attacker.getObjectId(), -damage));
  9645.     }
  9646.  
  9647.     public IntObjectMap<String> getPostFriends()
  9648.     {
  9649.         return _postFriends;
  9650.     }
  9651.  
  9652.     public void setPostFriends(IntObjectMap<String> val)
  9653.     {
  9654.         _postFriends = val;
  9655.     }
  9656.  
  9657.     public void sendReuseMessage(ItemInstance item)
  9658.     {
  9659.         TimeStamp sts = getSharedGroupReuse(item.getTemplate().getReuseGroup());
  9660.         if(sts == null || !sts.hasNotPassed())
  9661.             return;
  9662.  
  9663.         long timeleft = sts.getReuseCurrent();
  9664.         long hours = timeleft / 3600000;
  9665.         long minutes = (timeleft - hours * 3600000) / 60000;
  9666.         long seconds = (long) Math.ceil((timeleft - hours * 3600000 - minutes * 60000) / 1000.);
  9667.  
  9668.         if(hours > 0)
  9669.             sendPacket(new SystemMessagePacket(item.getTemplate().getReuseType().getMessages()[2]).addItemName(item.getTemplate().getItemId()).addInteger(hours).addInteger(minutes).addInteger(seconds));
  9670.         else if(minutes > 0)
  9671.             sendPacket(new SystemMessagePacket(item.getTemplate().getReuseType().getMessages()[1]).addItemName(item.getTemplate().getItemId()).addInteger(minutes).addInteger(seconds));
  9672.         else
  9673.             sendPacket(new SystemMessagePacket(item.getTemplate().getReuseType().getMessages()[0]).addItemName(item.getTemplate().getItemId()).addInteger(seconds));
  9674.     }
  9675.  
  9676.     public void ask(ConfirmDlgPacket dlg, OnAnswerListener listener)
  9677.     {
  9678.         if(_askDialog != null)
  9679.             return;
  9680.         int rnd = Rnd.nextInt();
  9681.         _askDialog = new IntObjectPairImpl<OnAnswerListener>(rnd, listener);
  9682.         dlg.setRequestId(rnd);
  9683.         sendPacket(dlg);
  9684.     }
  9685.  
  9686.     public IntObjectPair<OnAnswerListener> getAskListener(boolean clear)
  9687.     {
  9688.         if(!clear)
  9689.             return _askDialog;
  9690.         else
  9691.         {
  9692.             IntObjectPair<OnAnswerListener> ask = _askDialog;
  9693.             _askDialog = null;
  9694.             return ask;
  9695.         }
  9696.     }
  9697.  
  9698.     @Override
  9699.     public boolean isDead()
  9700.     {
  9701.         return (isInOlympiadMode() || isInDuel()) ? getCurrentHp() <= 1. : super.isDead();
  9702.     }
  9703.  
  9704.     public boolean hasPrivilege(Privilege privilege)
  9705.     {
  9706.         return _clan != null && (getClanPrivileges() & privilege.mask()) == privilege.mask();
  9707.     }
  9708.  
  9709.     public MatchingRoom getMatchingRoom()
  9710.     {
  9711.         return _matchingRoom;
  9712.     }
  9713.  
  9714.     public void setMatchingRoom(MatchingRoom matchingRoom)
  9715.     {
  9716.         _matchingRoom = matchingRoom;
  9717.         if(matchingRoom == null)
  9718.             _matchingRoomWindowOpened = false;
  9719.     }
  9720.  
  9721.     public boolean isMatchingRoomWindowOpened()
  9722.     {
  9723.         return _matchingRoomWindowOpened;
  9724.     }
  9725.  
  9726.     public void setMatchingRoomWindowOpened(boolean b)
  9727.     {
  9728.         _matchingRoomWindowOpened = b;
  9729.     }
  9730.  
  9731.     public void dispelBuffs()
  9732.     {
  9733.         for(Abnormal e : getAbnormalList())
  9734.             if(e.isOffensive() && !e.getSkill().isNewbie() && e.isCancelable() && !e.getSkill().isPreservedOnDeath() && !isSpecialAbnormal(e.getSkill()))
  9735.             {
  9736.                 sendPacket(new SystemMessagePacket(SystemMsg.THE_EFFECT_OF_S1_HAS_BEEN_REMOVED).addSkillName(e.getSkill().getId(), e.getSkill().getLevel()));
  9737.                 e.exit();
  9738.             }
  9739.  
  9740.  
  9741.         for(Servitor servitor : getServitors())
  9742.         {
  9743.             for(Abnormal e : servitor.getAbnormalList())
  9744.             {
  9745.                 if(!e.isOffensive() && !e.getSkill().isNewbie() && e.isCancelable() && !e.getSkill().isPreservedOnDeath() && !servitor.isSpecialAbnormal(e.getSkill()))
  9746.                     e.exit();
  9747.             }
  9748.         }
  9749.     }
  9750.  
  9751.     public void setInstanceReuse(int id, long time)
  9752.     {
  9753.         final SystemMessage msg = new SystemMessage(SystemMessage.INSTANT_ZONE_FROM_HERE__S1_S_ENTRY_HAS_BEEN_RESTRICTED_YOU_CAN_CHECK_THE_NEXT_ENTRY_POSSIBLE).addString(getName());
  9754.         sendPacket(msg);
  9755.         _instancesReuses.put(id, time);
  9756.         mysql.set("REPLACE INTO character_instances (obj_id, id, reuse) VALUES (?,?,?)", getObjectId(), id, time);
  9757.     }
  9758.  
  9759.     public void removeInstanceReuse(int id)
  9760.     {
  9761.         if(_instancesReuses.remove(id) != null)
  9762.             mysql.set("DELETE FROM `character_instances` WHERE `obj_id`=? AND `id`=? LIMIT 1", getObjectId(), id);
  9763.     }
  9764.  
  9765.     public void removeAllInstanceReuses()
  9766.     {
  9767.         _instancesReuses.clear();
  9768.         mysql.set("DELETE FROM `character_instances` WHERE `obj_id`=?", getObjectId());
  9769.     }
  9770.  
  9771.     public void removeInstanceReusesByGroupId(int groupId)
  9772.     {
  9773.         for(int i : InstantZoneHolder.getInstance().getSharedReuseInstanceIdsByGroup(groupId))
  9774.             if(getInstanceReuse(i) != null)
  9775.                 removeInstanceReuse(i);
  9776.     }
  9777.  
  9778.     public Long getInstanceReuse(int id)
  9779.     {
  9780.         return _instancesReuses.get(id);
  9781.     }
  9782.  
  9783.     public Map<Integer, Long> getInstanceReuses()
  9784.     {
  9785.         return _instancesReuses;
  9786.     }
  9787.  
  9788.     private void loadInstanceReuses()
  9789.     {
  9790.         Connection con = null;
  9791.         PreparedStatement offline = null;
  9792.         ResultSet rs = null;
  9793.         try
  9794.         {
  9795.             con = DatabaseFactory.getInstance().getConnection();
  9796.             offline = con.prepareStatement("SELECT * FROM character_instances WHERE obj_id = ?");
  9797.             offline.setInt(1, getObjectId());
  9798.             rs = offline.executeQuery();
  9799.             while(rs.next())
  9800.             {
  9801.                 int id = rs.getInt("id");
  9802.                 long reuse = rs.getLong("reuse");
  9803.                 _instancesReuses.put(id, reuse);
  9804.             }
  9805.         }
  9806.         catch(Exception e)
  9807.         {
  9808.             _log.error("", e);
  9809.         }
  9810.         finally
  9811.         {
  9812.             DbUtils.closeQuietly(con, offline, rs);
  9813.         }
  9814.     }
  9815.  
  9816.     public void setActiveReflection(Reflection reflection)
  9817.     {
  9818.         _activeReflection = reflection;
  9819.     }
  9820.  
  9821.     public Reflection getActiveReflection()
  9822.     {
  9823.         return _activeReflection;
  9824.     }
  9825.  
  9826.     public boolean canEnterInstance(int instancedZoneId)
  9827.     {
  9828.         InstantZone iz = InstantZoneHolder.getInstance().getInstantZone(instancedZoneId);
  9829.  
  9830.         if(isDead())
  9831.             return false;
  9832.  
  9833.         if(ReflectionManager.getInstance().size() > Config.MAX_REFLECTIONS_COUNT)
  9834.         {
  9835.             sendPacket(SystemMsg.THE_MAXIMUM_NUMBER_OF_INSTANCE_ZONES_HAS_BEEN_EXCEEDED);
  9836.             return false;
  9837.         }
  9838.  
  9839.         if(iz == null)
  9840.         {
  9841.             sendPacket(SystemMsg.SYSTEM_ERROR);
  9842.             return false;
  9843.         }
  9844.  
  9845.         if(ReflectionManager.getInstance().getCountByIzId(instancedZoneId) >= iz.getMaxChannels())
  9846.         {
  9847.             sendPacket(SystemMsg.THE_MAXIMUM_NUMBER_OF_INSTANCE_ZONES_HAS_BEEN_EXCEEDED);
  9848.             return false;
  9849.         }
  9850.  
  9851.         return iz.getEntryType(this).canEnter(this, iz);
  9852.     }
  9853.  
  9854.     public boolean canReenterInstance(int instancedZoneId)
  9855.     {
  9856.         if((getActiveReflection() != null && getActiveReflection().getInstancedZoneId() != instancedZoneId) || !getReflection().isMain())
  9857.         {
  9858.             sendPacket(SystemMsg.YOU_HAVE_ENTERED_ANOTHER_INSTANCE_ZONE_THEREFORE_YOU_CANNOT_ENTER_CORRESPONDING_DUNGEON);
  9859.             return false;
  9860.         }
  9861.         InstantZone iz = InstantZoneHolder.getInstance().getInstantZone(instancedZoneId);
  9862.         if(iz.isDispelBuffs())
  9863.             dispelBuffs();
  9864.         return iz.getEntryType(this).canReEnter(this, iz);
  9865.     }
  9866.  
  9867.     public int getBattlefieldChatId()
  9868.     {
  9869.         return _battlefieldChatId;
  9870.     }
  9871.  
  9872.     public void setBattlefieldChatId(int battlefieldChatId)
  9873.     {
  9874.         _battlefieldChatId = battlefieldChatId;
  9875.     }
  9876.  
  9877.     @Override
  9878.     public void broadCast(IBroadcastPacket... packet)
  9879.     {
  9880.         sendPacket(packet);
  9881.     }
  9882.  
  9883.     @Override
  9884.     public int getMemberCount()
  9885.     {
  9886.         return 1;
  9887.     }
  9888.  
  9889.     @Override
  9890.     public Player getGroupLeader()
  9891.     {
  9892.         return this;
  9893.     }
  9894.  
  9895.     @Override
  9896.     public Iterator<Player> iterator()
  9897.     {
  9898.         return Collections.singleton(this).iterator();
  9899.     }
  9900.  
  9901.     public PlayerGroup getPlayerGroup()
  9902.     {
  9903.         if(getParty() != null)
  9904.         {
  9905.             if(getParty().getCommandChannel() != null)
  9906.                 return getParty().getCommandChannel();
  9907.             else
  9908.                 return getParty();
  9909.         }
  9910.         else
  9911.             return this;
  9912.     }
  9913.  
  9914.     public boolean isActionBlocked(String action)
  9915.     {
  9916.         return _blockedActions.contains(action);
  9917.     }
  9918.  
  9919.     public void blockActions(String... actions)
  9920.     {
  9921.         Collections.addAll(_blockedActions, actions);
  9922.     }
  9923.  
  9924.     public void unblockActions(String... actions)
  9925.     {
  9926.         for(String action : actions)
  9927.             _blockedActions.remove(action);
  9928.     }
  9929.  
  9930.     public OlympiadGame getOlympiadGame()
  9931.     {
  9932.         return _olympiadGame;
  9933.     }
  9934.  
  9935.     public void setOlympiadGame(OlympiadGame olympiadGame)
  9936.     {
  9937.         _olympiadGame = olympiadGame;
  9938.     }
  9939.  
  9940.     public void addRadar(int x, int y, int z)
  9941.     {
  9942.         sendPacket(new RadarControlPacket(0, 1, x, y, z));
  9943.     }
  9944.  
  9945.     public void addRadarWithMap(int x, int y, int z)
  9946.     {
  9947.         sendPacket(new RadarControlPacket(0, 2, x, y, z));
  9948.     }
  9949.  
  9950.     public PetitionMainGroup getPetitionGroup()
  9951.     {
  9952.         return _petitionGroup;
  9953.     }
  9954.  
  9955.     public void setPetitionGroup(PetitionMainGroup petitionGroup)
  9956.     {
  9957.         _petitionGroup = petitionGroup;
  9958.     }
  9959.  
  9960.     public int getLectureMark()
  9961.     {
  9962.         return _lectureMark;
  9963.     }
  9964.  
  9965.     public void setLectureMark(int lectureMark)
  9966.     {
  9967.         _lectureMark = lectureMark;
  9968.     }
  9969.  
  9970.     public boolean isUserRelationActive()
  9971.     {
  9972.         return _enableRelationTask == null;
  9973.     }
  9974.  
  9975.     public void startEnableUserRelationTask(long time, SiegeEvent<?, ?> siegeEvent)
  9976.     {
  9977.         if(_enableRelationTask != null)
  9978.             return;
  9979.  
  9980.         _enableRelationTask = ThreadPoolManager.getInstance().schedule(new EnableUserRelationTask(this, siegeEvent), time);
  9981.     }
  9982.  
  9983.     public void stopEnableUserRelationTask()
  9984.     {
  9985.         if(_enableRelationTask != null)
  9986.         {
  9987.             _enableRelationTask.cancel(false);
  9988.             _enableRelationTask = null;
  9989.         }
  9990.     }
  9991.  
  9992.     public void broadcastRelation()
  9993.     {
  9994.         if(!isVisible())
  9995.             return;
  9996.  
  9997.         for(Player target : World.getAroundObservers(this))
  9998.         {
  9999.             if(isInvisible(target))
  10000.                 continue;
  10001.  
  10002.             RelationChangedPacket relationChanged = new RelationChangedPacket(this, target);
  10003.             for(Servitor servitor : getServitors())
  10004.                 relationChanged.add(servitor, target);
  10005.  
  10006.             target.sendPacket(relationChanged);
  10007.         }
  10008.     }
  10009.  
  10010.     private int[] _recentProductList = null;
  10011.  
  10012.     public int[] getRecentProductList()
  10013.     {
  10014.         if(_recentProductList == null)
  10015.         {
  10016.             String value = getVar(RECENT_PRODUCT_LIST_VAR);
  10017.             if(value == null)
  10018.                 return null;
  10019.  
  10020.             String[] products_str = value.split(";");
  10021.             int[] result = new int[0];
  10022.             for(int i = 0; i < products_str.length; i++)
  10023.             {
  10024.                 int productId = Integer.parseInt(products_str[i]);
  10025.                 if(ProductDataHolder.getInstance().getProduct(productId) == null)
  10026.                     continue;
  10027.  
  10028.                 result = ArrayUtils.add(result, productId);
  10029.             }
  10030.             _recentProductList = result;
  10031.         }
  10032.         return _recentProductList;
  10033.     }
  10034.  
  10035.     public void updateRecentProductList(final int productId)
  10036.     {
  10037.         if(_recentProductList == null)
  10038.         {
  10039.             _recentProductList = new int[1];
  10040.             _recentProductList[0] = productId;
  10041.         }
  10042.         else
  10043.         {
  10044.             int[] newProductList = new int[1];
  10045.             newProductList[0] = productId;
  10046.             for(int i = 0; i < _recentProductList.length; i++)
  10047.             {
  10048.                 if(newProductList.length >= Config.IM_MAX_ITEMS_IN_RECENT_LIST)
  10049.                     break;
  10050.  
  10051.                 int itemId = _recentProductList[i];
  10052.                 if(ArrayUtils.contains(newProductList, itemId))
  10053.                     continue;
  10054.  
  10055.                 newProductList = ArrayUtils.add(newProductList, itemId);
  10056.             }
  10057.  
  10058.             _recentProductList = newProductList;
  10059.         }
  10060.  
  10061.         String valueToUpdate = "";
  10062.         for(int itemId : _recentProductList)
  10063.         {
  10064.             valueToUpdate += itemId + ";";
  10065.         }
  10066.         setVar(RECENT_PRODUCT_LIST_VAR, valueToUpdate, -1);
  10067.     }
  10068.  
  10069.     @Override
  10070.     public int getINT()
  10071.     {
  10072.         return Math.max(getTemplate().getMinINT(), Math.min(getTemplate().getMaxINT(), super.getINT()));
  10073.     }
  10074.  
  10075.     @Override
  10076.     public int getSTR()
  10077.     {
  10078.         return Math.max(getTemplate().getMinSTR(), Math.min(getTemplate().getMaxSTR(), super.getSTR()));
  10079.     }
  10080.  
  10081.     @Override
  10082.     public int getCON()
  10083.     {
  10084.         return Math.max(getTemplate().getMinCON(), Math.min(getTemplate().getMaxCON(), super.getCON()));
  10085.     }
  10086.  
  10087.     @Override
  10088.     public int getMEN()
  10089.     {
  10090.         return Math.max(getTemplate().getMinMEN(), Math.min(getTemplate().getMaxMEN(), super.getMEN()));
  10091.     }
  10092.  
  10093.     @Override
  10094.     public int getDEX()
  10095.     {
  10096.         return Math.max(getTemplate().getMinDEX(), Math.min(getTemplate().getMaxDEX(), super.getDEX()));
  10097.     }
  10098.  
  10099.     @Override
  10100.     public int getWIT()
  10101.     {
  10102.         return Math.max(getTemplate().getMinWIT(), Math.min(getTemplate().getMaxWIT(), super.getWIT()));
  10103.     }
  10104.  
  10105.     public BookMarkList getBookMarkList()
  10106.     {
  10107.         return _bookmarks;
  10108.     }
  10109.  
  10110.     public AntiFlood getAntiFlood()
  10111.     {
  10112.         return _antiFlood;
  10113.     }
  10114.  
  10115.     public int getNpcDialogEndTime()
  10116.     {
  10117.         return _npcDialogEndTime;
  10118.     }
  10119.  
  10120.     public void setNpcDialogEndTime(int val)
  10121.     {
  10122.         _npcDialogEndTime = val;
  10123.     }
  10124.  
  10125.     @Override
  10126.     public boolean useItem(ItemInstance item, boolean ctrlPressed, boolean force)
  10127.     {
  10128.         if(item == null)
  10129.             return false;
  10130.  
  10131.         ItemTemplate template = item.getTemplate();
  10132.         IItemHandler handler = template.getHandler();
  10133.         if(handler == null)
  10134.         {
  10135.             //_log.warn("Fail while use item. Not found handler for item ID[" + item.getItemId() + "]!");
  10136.             return false;
  10137.         }
  10138.  
  10139.         boolean success = force ? handler.forceUseItem(this, item, ctrlPressed) : handler.useItem(this, item, ctrlPressed);
  10140.         if(success)
  10141.         {
  10142.             long nextTimeUse = template.getReuseType().next(item);
  10143.             if(nextTimeUse > System.currentTimeMillis())
  10144.             {
  10145.                 TimeStamp timeStamp = new TimeStamp(item.getItemId(), nextTimeUse, template.getReuseDelay());
  10146.                 addSharedGroupReuse(template.getReuseGroup(), timeStamp);
  10147.  
  10148.                 if(template.getReuseDelay() > 0)
  10149.                     sendPacket(new ExUseSharedGroupItem(template.getDisplayReuseGroup(), timeStamp));
  10150.             }
  10151.         }
  10152.         return success;
  10153.     }
  10154.  
  10155.     public int getSkillsElementID()
  10156.     {
  10157.         return (int) calcStat(Stats.SKILLS_ELEMENT_ID, -1, null, null);
  10158.     }
  10159.  
  10160.     public Location getStablePoint()
  10161.     {
  10162.         return _stablePoint;
  10163.     }
  10164.  
  10165.     public void setStablePoint(Location point)
  10166.     {
  10167.         _stablePoint = point;
  10168.     }
  10169.  
  10170.     public boolean isInSameParty(Player target)
  10171.     {
  10172.         return getParty() != null && target.getParty() != null && getParty() == target.getParty();
  10173.     }
  10174.  
  10175.     public boolean isInSameChannel(Player target)
  10176.     {
  10177.         Party activeCharP = getParty();
  10178.         Party targetP = target.getParty();
  10179.         if(activeCharP != null && targetP != null)
  10180.         {
  10181.             CommandChannel chan = activeCharP.getCommandChannel();
  10182.             if(chan != null && chan == targetP.getCommandChannel())
  10183.                 return true;
  10184.         }
  10185.         return false;
  10186.     }
  10187.  
  10188.     public boolean isInSameClan(Player target)
  10189.     {
  10190.         return getClanId() != 0 && getClanId() == target.getClanId();
  10191.     }
  10192.  
  10193.     public final boolean isInSameAlly(Player target)
  10194.     {
  10195.         return getAllyId() != 0 && getAllyId() == target.getAllyId();
  10196.     }
  10197.  
  10198.     public boolean isInPvPEvent()
  10199.     {
  10200.         PvPEvent event = getEvent(PvPEvent.class);
  10201.         if(event != null && event.isBattleActive())
  10202.             return true;
  10203.  
  10204.         return false;
  10205.     }
  10206.  
  10207.     public boolean isRelatedTo(Creature character)
  10208.     {
  10209.         if(character == this)
  10210.             return true;
  10211.  
  10212.         if(character.isServitor())
  10213.         {
  10214.             if(isMyServitor(character.getObjectId()))
  10215.                 return true;
  10216.             else if(character.getPlayer() != null)
  10217.             {
  10218.                 Player Spc = character.getPlayer();
  10219.                 if(isInSameParty(Spc) || isInSameChannel(Spc) || isInSameClan(Spc) || isInSameAlly(Spc))
  10220.                     return true;
  10221.             }
  10222.         }
  10223.         else if(character.isPlayer())
  10224.         {
  10225.             Player pc = character.getPlayer();
  10226.             if(isInSameParty(pc) || isInSameChannel(pc) || isInSameClan(pc) || isInSameAlly(pc))
  10227.                 return true;
  10228.         }
  10229.         return false;
  10230.     }
  10231.  
  10232.     public boolean isAutoSearchParty()
  10233.     {
  10234.         return _autoSearchParty;
  10235.     }
  10236.  
  10237.     public void enableAutoSearchParty()
  10238.     {
  10239.         _autoSearchParty = true;
  10240.         PartySubstituteManager.getInstance().addWaitingPlayer(this);
  10241.         sendPacket(ExWaitWaitingSubStituteInfo.OPEN);
  10242.     }
  10243.  
  10244.     public void disablePartySearch(boolean disableFlag)
  10245.     {
  10246.         if(_autoSearchParty)
  10247.         {
  10248.             PartySubstituteManager.getInstance().removeWaitingPlayer(this);
  10249.             sendPacket(ExWaitWaitingSubStituteInfo.CLOSE);
  10250.             _autoSearchParty = !disableFlag;
  10251.         }
  10252.     }
  10253.  
  10254.     public boolean refreshPartySearchStatus(boolean sendMsg)
  10255.     {
  10256.         if(!mayPartySearch(false,sendMsg))
  10257.         {
  10258.             disablePartySearch(false);
  10259.             return false;
  10260.         }
  10261.  
  10262.         if(isAutoSearchParty())
  10263.         {
  10264.             enableAutoSearchParty();
  10265.             return true;
  10266.         }
  10267.         return false;
  10268.     }
  10269.  
  10270.     public boolean mayPartySearch(boolean first, boolean msg)
  10271.     {
  10272.         if(getParty() != null)
  10273.             return false;
  10274.  
  10275.         if(isPK())
  10276.         {
  10277.             if(msg)
  10278.             {
  10279.                 if(first)
  10280.                     sendPacket(SystemMsg.WAITING_LIST_REGISTRATION_IS_NOT_ALLOWED_WHILE_THE_CURSED_SWORD_IS_BEING_USED_OR_THE_STATUS_IS_IN_A_CHAOTIC_STATE);
  10281.                 else
  10282.                     sendPacket(SystemMsg.WAITING_LIST_REGISTRATION_IS_CANCELLED_BECAUSE_THE_CURSED_SWORD_IS_BEING_USED_OR_THE_STATUS_IS_IN_A_CHAOTIC_STATE);
  10283.             }
  10284.             return false;
  10285.         }
  10286.  
  10287.         if(isInDuel() && getTeam() != TeamType.NONE)
  10288.         {
  10289.             if(msg)
  10290.             {
  10291.                 if(first)
  10292.                     sendPacket(SystemMsg.YOU_CANNOT_REGISTER_IN_THE_WAITING_LIST_DURING_A_DUEL);
  10293.                 else
  10294.                     sendPacket(SystemMsg.WAITING_LIST_REGISTRATION_IS_CANCELLED_BECAUSE_YOU_ARE_IN_A_DUEL);
  10295.             }
  10296.             return false;
  10297.         }
  10298.  
  10299.         if(isInOlympiadMode())
  10300.         {
  10301.             if(msg)
  10302.             {
  10303.                 if(first)
  10304.                     sendPacket(SystemMsg.YOU_CANNOT_REGISTER_IN_THE_WAITING_LIST_WHILE_PARTICIPATING_IN_OLYMPIAD);
  10305.                 else
  10306.                     sendPacket(SystemMsg.WAITING_LIST_REGISTRATION_IS_CANCELLED_BECAUSE_YOU_ARE_CURRENTLY_PARTICIPATING_IN_OLYMPIAD);
  10307.             }
  10308.             return false;
  10309.         }
  10310.  
  10311.         if(isInSiegeZone())
  10312.         {
  10313.             if(msg && first)
  10314.                 sendPacket(SystemMsg.YOU_CANNOT_REGISTER_IN_THE_WAITING_LIST_WHILE_BEING_INSIDE_OF_A_BATTLEGROUND_CASTLE_SIEGEFORTRESS_SIEGETERRITORY_WAR);
  10315.  
  10316.             return false;
  10317.         }
  10318.  
  10319.         if(isInZoneBattle() || getReflectionId() != 0)
  10320.         {
  10321.             if(msg && first)
  10322.                 sendPacket(SystemMsg.YOU_CANNOT_REGISTER_IN_THE_WAITING_LIST_WHILE_PARTICIPATING_IN_BLOCK_CHECKERCOLISEUMKRATEIS_CUBE);
  10323.  
  10324.             return false;
  10325.         }
  10326.  
  10327.         if(isInZone(ZoneType.no_escape) || isInZone(ZoneType.epic))
  10328.             return false;
  10329.            
  10330.         if(!Config.ENABLE_PARTY_SEARCH)
  10331.             return false;
  10332.         return true;
  10333.     }
  10334.  
  10335.     public void startSubstituteTask()
  10336.     {
  10337.         if(!isPartySubstituteStarted())
  10338.         {
  10339.             _substituteTask = PartySubstituteManager.getInstance().SubstituteSearchTask(this);
  10340.             sendUserInfo();
  10341.             if(isInParty())
  10342.                 getParty().getPartyLeader().sendPacket(new PartySmallWindowUpdatePacket(this));
  10343.         }
  10344.     }
  10345.  
  10346.     public void stopSubstituteTask()
  10347.     {
  10348.         if(isPartySubstituteStarted())
  10349.         {
  10350.             PartySubstituteManager.getInstance().removePartyMember(this);
  10351.             _substituteTask.cancel(true);
  10352.             sendUserInfo();
  10353.             if(isInParty())
  10354.                 getParty().getPartyLeader().sendPacket(new PartySmallWindowUpdatePacket(this));
  10355.         }
  10356.     }
  10357.  
  10358.     public boolean isPartySubstituteStarted()
  10359.     {
  10360.         return getParty() != null && _substituteTask != null && !_substituteTask.isDone() && !_substituteTask.isCancelled();
  10361.     }
  10362.  
  10363.     @Override
  10364.     public int getSkillLevel(int skillId)
  10365.     {
  10366.         switch(skillId)
  10367.         {
  10368.             case 1566:  // Смена КлаÑ�Ñ�а
  10369.             case 1567:  // Смена КлаÑ�Ñ�а
  10370.             case 1568:  // Смена КлаÑ�Ñ�а
  10371.             case 1569:  // Смена КлаÑ�Ñ�а
  10372.             case 17192: // Отображение Головного Убора
  10373.                 return 1;
  10374.  
  10375.         }
  10376.         return super.getSkillLevel(skillId);
  10377.     }
  10378.  
  10379.     public SymbolInstance getSymbol()
  10380.     {
  10381.         return _symbol;
  10382.     }
  10383.  
  10384.     public void setSymbol(SymbolInstance symbol)
  10385.     {
  10386.         _symbol = symbol;
  10387.     }
  10388.  
  10389.     public void setRegisteredInEvent(boolean inEvent)
  10390.     {
  10391.         _registeredInEvent = inEvent;
  10392.     }
  10393.  
  10394.     public boolean isRegisteredInEvent()
  10395.     {
  10396.         return _registeredInEvent;
  10397.     }
  10398.  
  10399.     private boolean checkActiveToggleEffects()
  10400.     {
  10401.         boolean dispelled = false;
  10402.         for(Abnormal effect : getAbnormalList())
  10403.         {
  10404.             Skill skill = effect.getSkill();
  10405.             if(skill == null)
  10406.                 continue;
  10407.  
  10408.             if(!skill.isToggle())
  10409.                 continue;
  10410.  
  10411.             if(getAllSkills().contains(skill))
  10412.                 continue;
  10413.  
  10414.             effect.exit();
  10415.         }
  10416.         return dispelled;
  10417.     }
  10418.  
  10419.     @Override
  10420.     public Servitor getServitorForTransfereDamage(double transferDamage)
  10421.     {
  10422.         SummonInstance summon = getSummon();
  10423.         if(summon == null || summon.isDead() || summon.getCurrentHp() < transferDamage)
  10424.             return null;
  10425.  
  10426.         if(summon.isInRangeZ(this, 1200))
  10427.             return summon;
  10428.  
  10429.         return null;
  10430.     }
  10431.  
  10432.     @Override
  10433.     public double getDamageForTransferToServitor(double damage)
  10434.     {
  10435.         final double transferToSummonDam = calcStat(Stats.TRANSFER_TO_SUMMON_DAMAGE_PERCENT, 0.);
  10436.         if(transferToSummonDam > 0)
  10437.             return (damage * transferToSummonDam) * .01;
  10438.         return 0.;
  10439.     }
  10440.  
  10441.     public boolean canFixedRessurect()
  10442.     {
  10443.         if(getPlayerAccess().ResurectFixed)
  10444.             return true;
  10445.  
  10446.         if(!isInSiegeZone())
  10447.         {
  10448.             if(getInventory().getCountOf(10649) > 0)
  10449.                 return true;
  10450.             if(getInventory().getCountOf(13300) > 0)
  10451.                 return true;
  10452.         }
  10453.         else
  10454.         {
  10455.             int level = getLevel();
  10456.             if(level <= 19 && getInventory().getCountOf(8515) > 0)
  10457.                 return true;
  10458.  
  10459.             if(level <= 39 && getInventory().getCountOf(8516) > 0)
  10460.                 return true;
  10461.  
  10462.             if(level <= 51 && getInventory().getCountOf(8517) > 0)
  10463.                 return true;
  10464.  
  10465.             if(level <= 60 && getInventory().getCountOf(8518) > 0)
  10466.                 return true;
  10467.  
  10468.             if(level <= 75 && getInventory().getCountOf(8519) > 0)
  10469.                 return true;
  10470.  
  10471.             if(level <= 84 && getInventory().getCountOf(8520) > 0)
  10472.                 return true;
  10473.         }
  10474.  
  10475.         return false;
  10476.     }
  10477.  
  10478.     @Override
  10479.     public double getLevelBonus()
  10480.     {
  10481.         if(getTransform() != null && getTransform().getLevelBonus(getLevel()) > 0)
  10482.             return getTransform().getLevelBonus(getLevel());
  10483.  
  10484.         return super.getLevelBonus();
  10485.     }
  10486.  
  10487.     @Override
  10488.     public PlayerBaseStats getBaseStats()
  10489.     {
  10490.         if(_baseStats == null)
  10491.             _baseStats = new PlayerBaseStats(this);
  10492.         return (PlayerBaseStats) _baseStats;
  10493.     }
  10494.  
  10495.     @Override
  10496.     public PlayerFlags getFlags()
  10497.     {
  10498.         if(_statuses == null)
  10499.             _statuses = new PlayerFlags(this);
  10500.  
  10501.         return (PlayerFlags) _statuses;
  10502.     }
  10503.  
  10504.     public final String getVisibleName(Player receiver)
  10505.     {
  10506.         String name;
  10507.         for(Event event : getEvents())
  10508.         {
  10509.             name = event.getVisibleName(this, receiver);
  10510.             if(name != null)
  10511.                 return name;
  10512.         }
  10513.  
  10514.         return getName();
  10515.     }
  10516.  
  10517.     public final String getVisibleTitle(Player receiver)
  10518.     {
  10519.         if(isInBuffStore())
  10520.         {
  10521.             BufferData bufferData = OfflineBufferManager.getInstance().getBuffStore(getObjectId());
  10522.             if(bufferData != null)
  10523.                 return bufferData.getSaleTitle();
  10524.         }
  10525.  
  10526.         if(getPrivateStoreType() != Player.STORE_PRIVATE_NONE)
  10527.         {
  10528.             if(getReflection() == ReflectionManager.GIRAN_HARBOR)
  10529.                 return "";
  10530.  
  10531.             if(getReflection() == ReflectionManager.PARNASSUS)
  10532.                 return "";
  10533.         }
  10534.  
  10535.         if(isInAwayingMode())
  10536.         {
  10537.             String awayText = AwayManager.getInstance().getAwayText(this);
  10538.             // TODO: ВынеÑ�ти в ДП Ñ�ообщение.
  10539.             if(awayText == null || awayText.length() <= 1)
  10540.                 return isLangRus() ? "<Отошел>" : "<Away>";
  10541.             else
  10542.                 return (isLangRus() ? "<Отошел>" : "<Away>") + " - " + awayText + "*";
  10543.         }
  10544.  
  10545.         String title;
  10546.         for(Event event : getEvents())
  10547.         {
  10548.             title = event.getVisibleTitle(this, receiver);
  10549.             if(title != null)
  10550.                 return title;
  10551.         }
  10552.  
  10553.         return getTitle();
  10554.     }
  10555.  
  10556.     public final int getVisibleNameColor(Player receiver)
  10557.     {
  10558.         if(isInBuffStore())
  10559.         {
  10560.             OfflineBufferManager.BufferData bufferData = OfflineBufferManager.getInstance().getBuffStore(getObjectId());
  10561.             if(bufferData != null)
  10562.             {
  10563.                 if(isInOfflineMode())
  10564.                     return Config.BUFF_STORE_OFFLINE_NAME_COLOR;
  10565.                 else
  10566.                     return Config.BUFF_STORE_NAME_COLOR;
  10567.             }
  10568.         }
  10569.  
  10570.         if(isInStoreMode() && isInOfflineMode())
  10571.         {
  10572.             return Config.SERVICES_OFFLINE_TRADE_NAME_COLOR;
  10573.         }
  10574.  
  10575.         Integer color;
  10576.         for(Event event : getEvents())
  10577.         {
  10578.             color = event.getVisibleNameColor(this, receiver);
  10579.             if(color != null)
  10580.                 return color.intValue();
  10581.         }
  10582.  
  10583.         int premiumNameColor = getPremiumAccount().getProperties().getNameColor();
  10584.         if(premiumNameColor != -1)
  10585.             return premiumNameColor;
  10586.  
  10587.         return getNameColor();
  10588.     }
  10589.  
  10590.     public final int getVisibleTitleColor(Player receiver)
  10591.     {
  10592.         if(isInBuffStore())
  10593.         {
  10594.             OfflineBufferManager.BufferData bufferData = OfflineBufferManager.getInstance().getBuffStore(getObjectId());
  10595.             if(bufferData != null && !isInOfflineMode())
  10596.                 return Config.BUFF_STORE_TITLE_COLOR;
  10597.         }
  10598.  
  10599.         if(isInAwayingMode())
  10600.             return Config.AWAY_TITLE_COLOR;
  10601.  
  10602.         Integer color;
  10603.         for(Event event : getEvents())
  10604.         {
  10605.             color = event.getVisibleTitleColor(this, receiver);
  10606.             if(color != null)
  10607.                 return color.intValue();
  10608.         }
  10609.  
  10610.         int premiumTitleColor = getPremiumAccount().getProperties().getTitleColor();
  10611.         if(premiumTitleColor != -1)
  10612.             return premiumTitleColor;
  10613.  
  10614.         return getTitleColor();
  10615.     }
  10616.  
  10617.     public final boolean isPledgeVisible(Player receiver)
  10618.     {
  10619.         if(getPrivateStoreType() != Player.STORE_PRIVATE_NONE)
  10620.         {
  10621.             if(getReflection() == ReflectionManager.GIRAN_HARBOR)
  10622.                 return false;
  10623.  
  10624.             if(getReflection() == ReflectionManager.PARNASSUS)
  10625.                 return false;
  10626.         }
  10627.  
  10628.         for(Event event : getEvents())
  10629.         {
  10630.             if(!event.isPledgeVisible(this, receiver))
  10631.                 return false;
  10632.         }
  10633.  
  10634.         return true;
  10635.     }
  10636.  
  10637.     public void checkAndDeleteOlympiadItems()
  10638.     {
  10639.         int rank = Olympiad.getRank(this);
  10640.         if(rank != 2 && rank != 3)
  10641.             ItemFunctions.deleteItemsEverywhere(this, ItemTemplate.ITEM_ID_FAME_CLOAK);
  10642.  
  10643.         if(!isHero())
  10644.         {
  10645.             ItemFunctions.deleteItemsEverywhere(this, ItemTemplate.ITEM_ID_HERO_WING);
  10646.             ItemFunctions.deleteItemsEverywhere(this, ItemTemplate.ITEM_ID_HERO_CLOAK);
  10647.             for(int itemId : ItemTemplate.HERO_WEAPON_IDS)
  10648.                 ItemFunctions.deleteItemsEverywhere(this, itemId);
  10649.         }
  10650.     }
  10651.  
  10652.     public double getEnchantChanceModifier()
  10653.     {
  10654.         return calcStat(Stats.ENCHANT_CHANCE_MODIFIER);
  10655.     }
  10656.  
  10657.     @Override
  10658.     public boolean isSpecialAbnormal(Skill skill)
  10659.     {
  10660.         if(getClan() != null && getClan().isSpecialAbnormal(skill))
  10661.             return true;
  10662.  
  10663.         if(skill.isNecessaryToggle())
  10664.             return true;
  10665.  
  10666.         int skillId = skill.getId();
  10667.  
  10668.         if(skillId == 7008 || skillId == 6038 || skillId == 6039 || skillId == 6040 || skillId == 6055 || skillId == 6056 || skillId == 6057 || skillId == 6058)
  10669.             return true;
  10670.  
  10671.         return false;
  10672.     }
  10673.  
  10674.     @Override
  10675.     public void removeAllSkills()
  10676.     {
  10677.         _dontRewardSkills = true;
  10678.  
  10679.         super.removeAllSkills();
  10680.  
  10681.         _dontRewardSkills = false;
  10682.     }
  10683.  
  10684.     public void setLastMultisellBuyTime(long val)
  10685.     {
  10686.         _lastMultisellBuyTime = val;
  10687.     }
  10688.  
  10689.     public long getLastMultisellBuyTime()
  10690.     {
  10691.         return _lastMultisellBuyTime;
  10692.     }
  10693.  
  10694.     public void setLastEnchantItemTime(long val)
  10695.     {
  10696.         _lastEnchantItemTime = val;
  10697.     }
  10698.  
  10699.     public long getLastEnchantItemTime()
  10700.     {
  10701.         return _lastEnchantItemTime;
  10702.     }
  10703.  
  10704.     public void setLastAttributeItemTime(long val)
  10705.     {
  10706.         _lastAttributeItemTime = val;
  10707.     }
  10708.  
  10709.     public long getLastAttributeItemTime()
  10710.     {
  10711.         return _lastAttributeItemTime;
  10712.     }
  10713.  
  10714.     public void checkLevelUpReward(boolean onRestore)
  10715.     {
  10716.         int lastRewarded = getVarInt(LVL_UP_REWARD_VAR);
  10717.         int lastRewardedByClass = getVarInt(LVL_UP_REWARD_VAR + "_" + getActiveSubClass().getIndex());
  10718.         int playerLvl = getLevel();
  10719.         boolean rewarded = false;
  10720.         int clanPoints = 0;
  10721.         if(playerLvl > lastRewarded)
  10722.         {
  10723.             for(int i = playerLvl; i > lastRewarded; i--)
  10724.             {
  10725.                 TIntLongMap items = LevelUpRewardHolder.getInstance().getRewardData(i);
  10726.                 if(items != null)
  10727.                 {
  10728.                     for(TIntLongIterator iterator = items.iterator(); iterator.hasNext();)
  10729.                     {
  10730.                         iterator.advance();
  10731.                         getPremiumItemList().add(new PremiumItem(iterator.key(), iterator.value(), ""));
  10732.                         rewarded = true;
  10733.                     }
  10734.                 }
  10735.             }
  10736.             setVar(LVL_UP_REWARD_VAR, playerLvl);
  10737.         }
  10738.  
  10739.         if(playerLvl > lastRewardedByClass)
  10740.         {
  10741.             for(int i = playerLvl; i > lastRewardedByClass; i--)
  10742.             {
  10743.                 if(getClan() != null && getClan().getLevel() >= 3)
  10744.                 {
  10745.                     int earnedPoints = 0;
  10746.                     switch(i)
  10747.                     {
  10748.                         case 20:
  10749.                             earnedPoints = 2;
  10750.                             break;
  10751.                         case 21:
  10752.                             earnedPoints = 2;
  10753.                             break;
  10754.                         case 22:
  10755.                             earnedPoints = 2;
  10756.                             break;
  10757.                         case 23:
  10758.                             earnedPoints = 2;
  10759.                             break;
  10760.                         case 24:
  10761.                             earnedPoints = 2;
  10762.                             break;
  10763.                         case 25:
  10764.                             earnedPoints = 2;
  10765.                             break;
  10766.                         case 26:
  10767.                             earnedPoints = 4;
  10768.                             break;
  10769.                         case 27:
  10770.                             earnedPoints = 4;
  10771.                             break;
  10772.                         case 28:
  10773.                             earnedPoints = 4;
  10774.                             break;
  10775.                         case 29:
  10776.                             earnedPoints = 4;
  10777.                             break;
  10778.                         case 30:
  10779.                             earnedPoints = 4;
  10780.                             break;
  10781.                         case 31:
  10782.                             earnedPoints = 6;
  10783.                             break;
  10784.                         case 32:
  10785.                             earnedPoints = 6;
  10786.                             break;
  10787.                         case 33:
  10788.                             earnedPoints = 6;
  10789.                             break;
  10790.                         case 34:
  10791.                             earnedPoints = 6;
  10792.                             break;
  10793.                         case 35:
  10794.                             earnedPoints = 6;
  10795.                             break;
  10796.                         case 36:
  10797.                             earnedPoints = 8;
  10798.                             break;
  10799.                         case 37:
  10800.                             earnedPoints = 8;
  10801.                             break;
  10802.                         case 38:
  10803.                             earnedPoints = 8;
  10804.                             break;
  10805.                         case 39:
  10806.                             earnedPoints = 8;
  10807.                             break;
  10808.                         case 40:
  10809.                             earnedPoints = 8;
  10810.                             break;
  10811.                         case 41:
  10812.                             earnedPoints = 10;
  10813.                             break;
  10814.                         case 42:
  10815.                             earnedPoints = 10;
  10816.                             break;
  10817.                         case 43:
  10818.                             earnedPoints = 10;
  10819.                             break;
  10820.                         case 44:
  10821.                             earnedPoints = 10;
  10822.                             break;
  10823.                         case 45:
  10824.                             earnedPoints = 10;
  10825.                             break;
  10826.                         case 46:
  10827.                             earnedPoints = 12;
  10828.                             break;
  10829.                         case 47:
  10830.                             earnedPoints = 12;
  10831.                             break;
  10832.                         case 48:
  10833.                             earnedPoints = 12;
  10834.                             break;
  10835.                         case 49:
  10836.                             earnedPoints = 12;
  10837.                             break;
  10838.                         case 50:
  10839.                             earnedPoints = 12;
  10840.                             break;
  10841.                         case 51:
  10842.                             earnedPoints = 14;
  10843.                             break;
  10844.                         case 52:
  10845.                             earnedPoints = 14;
  10846.                             break;
  10847.                         case 53:
  10848.                             earnedPoints = 14;
  10849.                             break;
  10850.                         case 54:
  10851.                             earnedPoints = 14;
  10852.                             break;
  10853.                         case 55:
  10854.                             earnedPoints = 14;
  10855.                             break;
  10856.                         case 56:
  10857.                             earnedPoints = 16;
  10858.                             break;
  10859.                         case 57:
  10860.                             earnedPoints = 16;
  10861.                             break;
  10862.                         case 58:
  10863.                             earnedPoints = 16;
  10864.                             break;
  10865.                         case 59:
  10866.                             earnedPoints = 16;
  10867.                             break;
  10868.                         case 60:
  10869.                             earnedPoints = 16;
  10870.                             break;
  10871.                         case 61:
  10872.                             earnedPoints = 18;
  10873.                             break;
  10874.                         case 62:
  10875.                             earnedPoints = 18;
  10876.                             break;
  10877.                         case 63:
  10878.                             earnedPoints = 18;
  10879.                             break;
  10880.                         case 64:
  10881.                             earnedPoints = 18;
  10882.                             break;
  10883.                         case 65:
  10884.                             earnedPoints = 18;
  10885.                             break;
  10886.                         case 66:
  10887.                             earnedPoints = 21;
  10888.                             break;
  10889.                         case 67:
  10890.                             earnedPoints = 21;
  10891.                             break;
  10892.                         case 68:
  10893.                             earnedPoints = 21;
  10894.                             break;
  10895.                         case 69:
  10896.                             earnedPoints = 21;
  10897.                             break;
  10898.                         case 70:
  10899.                             earnedPoints = 21;
  10900.                             break;
  10901.                         case 71:
  10902.                             earnedPoints = 25;
  10903.                             break;
  10904.                         case 72:
  10905.                             earnedPoints = 25;
  10906.                             break;
  10907.                         case 73:
  10908.                             earnedPoints = 25;
  10909.                             break;
  10910.                         case 74:
  10911.                             earnedPoints = 25;
  10912.                             break;
  10913.                         case 75:
  10914.                             earnedPoints = 25;
  10915.                             break;
  10916.                     }
  10917.  
  10918.                     if(earnedPoints > 0)
  10919.                         clanPoints += earnedPoints;
  10920.                 }
  10921.             }
  10922.  
  10923.             setVar(LVL_UP_REWARD_VAR + "_" + getActiveSubClass().getIndex(), playerLvl);
  10924.         }
  10925.  
  10926.         if(rewarded)
  10927.             sendPacket(ExNotifyPremiumItem.STATIC);
  10928.  
  10929.         if(clanPoints > 0)
  10930.             getClan().incReputation(clanPoints, true, "ClanMemberLvlUp");
  10931.     }
  10932.  
  10933.     public void checkHeroSkills()
  10934.     {
  10935.         final boolean hero = isHero() && isBaseClassActive();
  10936.         for(SkillLearn sl : SkillAcquireHolder.getInstance().getAvailableMaxLvlSkills(hero ? this : null, AcquireType.HERO))
  10937.         {
  10938.             SkillEntry skillEntry = SkillHolder.getInstance().getSkillEntry(sl.getId(), sl.getLevel());
  10939.             if(skillEntry == null)
  10940.                 continue;
  10941.  
  10942.             if(hero)
  10943.             {
  10944.                 if(getSkillLevel(skillEntry.getId()) < skillEntry.getLevel())
  10945.                     addSkill(skillEntry, true);
  10946.             }
  10947.             else
  10948.                 removeSkill(skillEntry, true);
  10949.         }
  10950.     }
  10951.  
  10952.     public void activateHeroSkills(boolean activate)
  10953.     {
  10954.         for(SkillLearn sl : SkillAcquireHolder.getInstance().getAvailableMaxLvlSkills(null, AcquireType.HERO))
  10955.         {
  10956.             Skill skill = SkillHolder.getInstance().getSkill(sl.getId(), sl.getLevel());
  10957.             if(skill == null)
  10958.                 continue;
  10959.  
  10960.             if(!activate)
  10961.                 addUnActiveSkill(skill);
  10962.             else
  10963.                 removeUnActiveSkill(skill);
  10964.         }
  10965.     }
  10966.  
  10967.     public void giveGMSkills()
  10968.     {
  10969.         if(!isGM())
  10970.             return;
  10971.  
  10972.         for(SkillLearn sl : SkillAcquireHolder.getInstance().getAvailableMaxLvlSkills(this, AcquireType.GM))
  10973.         {
  10974.             SkillEntry skillEntry = SkillHolder.getInstance().getSkillEntry(sl.getId(), sl.getLevel());
  10975.             if(skillEntry == null)
  10976.                 continue;
  10977.  
  10978.             if(getSkillLevel(skillEntry.getId()) < skillEntry.getLevel())
  10979.                 addSkill(skillEntry, true);
  10980.         }
  10981.     }
  10982.    
  10983.     private long _blockUntilTime = 0;
  10984.  
  10985.     public void setblockUntilTime(long time)
  10986.     {
  10987.         _blockUntilTime = time;
  10988.     }
  10989.  
  10990.     public long getblockUntilTime()
  10991.     {
  10992.         return _blockUntilTime;
  10993.     }
  10994.  
  10995.     public int getWorldChatPoints()
  10996.     {
  10997.         if(hasPremiumAccount())
  10998.             return Math.max(0, Config.WORLD_CHAT_POINTS_PER_DAY_PA - _usedWorldChatPoints);
  10999.  
  11000.         return Math.max(0, Config.WORLD_CHAT_POINTS_PER_DAY - _usedWorldChatPoints);
  11001.     }
  11002.  
  11003.     public int getUsedWorldChatPoints()
  11004.     {
  11005.         return _usedWorldChatPoints;
  11006.     }
  11007.  
  11008.     public void setUsedWorldChatPoints(int value)
  11009.     {
  11010.         _usedWorldChatPoints = value;
  11011.     }
  11012.  
  11013.     public int getArmorSetEnchant()
  11014.     {
  11015.         return _armorSetEnchant;
  11016.     }
  11017.  
  11018.     public void setArmorSetEnchant(int value)
  11019.     {
  11020.         _armorSetEnchant = value;
  11021.     }
  11022.  
  11023.     public boolean hideHeadAccessories()
  11024.     {
  11025.         return _hideHeadAccessories;
  11026.     }
  11027.  
  11028.     public void setHideHeadAccessories(boolean value)
  11029.     {
  11030.         _hideHeadAccessories = value;
  11031.     }
  11032.  
  11033.     public ItemInstance getSynthesisItem1()
  11034.     {
  11035.         return _synthesisItem1;
  11036.     }
  11037.  
  11038.     public void setSynthesisItem1(ItemInstance value)
  11039.     {
  11040.         _synthesisItem1 = value;
  11041.     }
  11042.  
  11043.     public ItemInstance getSynthesisItem2()
  11044.     {
  11045.         return _synthesisItem2;
  11046.     }
  11047.  
  11048.     public void setSynthesisItem2(ItemInstance value)
  11049.     {
  11050.         _synthesisItem2 = value;
  11051.     }
  11052.    
  11053.     public String getHWID()
  11054.     {
  11055.         return getNetConnection().getHWID();
  11056.     }
  11057.  
  11058.     public boolean isInAwayingMode()
  11059.     {
  11060.         return _awaying;
  11061.     }
  11062.  
  11063.     public void setAwayingMode(boolean awaying)
  11064.     {
  11065.         _awaying = awaying;
  11066.     }
  11067.  
  11068.     public double getMPCostDiff(Skill.SkillMagicType type)
  11069.     {
  11070.         double value = 0;
  11071.         switch(type)
  11072.         {
  11073.             case PHYSIC:
  11074.             {
  11075.                 value = (calcStat(Stats.MP_PHYSICAL_SKILL_CONSUME, 10000) / 10000 * 100) - 100;
  11076.                 break;
  11077.             }
  11078.             case MAGIC:
  11079.             {
  11080.                 value = (calcStat(Stats.MP_MAGIC_SKILL_CONSUME, 10000) / 10000 * 100) - 100;
  11081.                 break;
  11082.             }
  11083.             case MUSIC:
  11084.             {
  11085.                 value = (calcStat(Stats.MP_DANCE_SKILL_CONSUME, 10000) / 10000 * 100) - 100;
  11086.                 break;
  11087.             }
  11088.         }
  11089.  
  11090.         return value;
  11091.     }
  11092.  
  11093.     public int getExpertiseIndex()
  11094.     {
  11095.         return getSkillLevel(239, 0);
  11096.     }
  11097.  
  11098.     private final ConcurrentHashMap<ListenerHookType, CopyOnWriteArraySet<ListenerHook>> scriptHookTypeList = new ConcurrentHashMap<ListenerHookType, CopyOnWriteArraySet<ListenerHook>>();
  11099.  
  11100.     public void addListenerHook(ListenerHookType type, ListenerHook hook)
  11101.     {
  11102.         if(!scriptHookTypeList.containsKey(type))
  11103.         {
  11104.             CopyOnWriteArraySet<ListenerHook> hooks = new CopyOnWriteArraySet<ListenerHook>();
  11105.             hooks.add(hook);
  11106.             scriptHookTypeList.put(type, hooks);
  11107.         }
  11108.         else
  11109.         {
  11110.             CopyOnWriteArraySet<ListenerHook> hooks = scriptHookTypeList.get(type);
  11111.             hooks.add(hook);
  11112.         }
  11113.     }
  11114.  
  11115.     public void removeListenerHookType(ListenerHookType type, ListenerHook hook)
  11116.     {
  11117.         if(scriptHookTypeList.containsKey(type))
  11118.         {
  11119.             Set<ListenerHook> hooks = scriptHookTypeList.get(type);
  11120.             hooks.remove(hook);
  11121.         }
  11122.     }
  11123.  
  11124.     public Set<ListenerHook> getListenerHooks(ListenerHookType type)
  11125.     {
  11126.         Set<ListenerHook> hooks = scriptHookTypeList.get(type);
  11127.         if(hooks == null)
  11128.             hooks = Collections.emptySet();
  11129.         return hooks;
  11130.     }
  11131.  
  11132.     @Override
  11133.     public boolean isFakePlayer()
  11134.     {
  11135.         return getAI() != null && getAI().isFake();
  11136.     }
  11137.  
  11138.     public OptionDataTemplate addOptionData(OptionDataTemplate optionData)
  11139.     {
  11140.         if(optionData == null)
  11141.             return null;
  11142.  
  11143.         OptionDataTemplate oldOptionData = _options.get(optionData.getId());
  11144.         if(optionData == oldOptionData)
  11145.             return oldOptionData;
  11146.  
  11147.         _options.put(optionData.getId(), optionData);
  11148.         addTriggers(optionData);
  11149.         addStatFuncs(optionData.getStatFuncs(optionData));
  11150.  
  11151.         for(SkillEntry skillEntry : optionData.getSkills())
  11152.             addSkill(skillEntry);
  11153.  
  11154.         return oldOptionData;
  11155.     }
  11156.  
  11157.     public OptionDataTemplate removeOptionData(int id)
  11158.     {
  11159.         OptionDataTemplate oldOptionData = _options.remove(id);
  11160.         if(oldOptionData != null)
  11161.         {
  11162.             removeTriggers(oldOptionData);
  11163.             removeStatsOwner(oldOptionData);
  11164.             for(SkillEntry skillEntry : oldOptionData.getSkills())
  11165.                 removeSkill(skillEntry);
  11166.         }
  11167.         return oldOptionData;
  11168.     }
  11169.  
  11170.     public long getReceivedExp()
  11171.     {
  11172.         return _receivedExp;
  11173.     }
  11174.  
  11175.     @Override
  11176.     protected void onSpawn()
  11177.     {
  11178.         super.onSpawn();
  11179.         getAI().notifyEvent(CtrlEvent.EVT_SPAWN);
  11180.     }
  11181.  
  11182.     @Override
  11183.     protected void onDespawn()
  11184.     {
  11185.         getAI().notifyEvent(CtrlEvent.EVT_DESPAWN);
  11186.         super.onDespawn();
  11187.     }
  11188.  
  11189.     public void setQuestZoneId(int id)
  11190.     {
  11191.         _questZoneId = id;
  11192.     }
  11193.  
  11194.     public int getQuestZoneId()
  11195.     {
  11196.         return _questZoneId;
  11197.     }
  11198.  
  11199.     @Override
  11200.     protected void onAddSkill(SkillEntry skillEntry)
  11201.     {
  11202.         Skill skill = skillEntry.getTemplate();
  11203.         if(skill.isNecessaryToggle())
  11204.         {
  11205.             if(skill.isToggleGrouped() && skill.getToggleGroupId() > 0)
  11206.             {
  11207.                 for(Abnormal abnormal : getAbnormalList())
  11208.                 {
  11209.                     if(abnormal.getSkill().isToggleGrouped() && abnormal.getSkill().getToggleGroupId() == skill.getToggleGroupId())
  11210.                         return;
  11211.                 }
  11212.             }
  11213.             forceUseSkill(skill, this);
  11214.         }
  11215.     }
  11216.  
  11217.     public void setCustomHero(int hours)
  11218.     {
  11219.         setHero(true);
  11220.         updatePledgeRank();
  11221.         broadcastPacket(new SocialActionPacket(getObjectId(), 20016));
  11222.         checkHeroSkills();
  11223.         int time = hours == -1 ? -1 : (int) (System.currentTimeMillis() / 1000) + hours * 60 * 60;
  11224.         CustomHeroDAO.getInstance().addCustomHero(getObjectId(), time);
  11225.     }
  11226.  
  11227.     public void setSelectedMultiClassId(ClassId classId)
  11228.     {
  11229.         _selectedMultiClassId = classId;
  11230.     }
  11231.  
  11232.     public ClassId getSelectedMultiClassId()
  11233.     {
  11234.         return _selectedMultiClassId;
  11235.     }
  11236.  
  11237.     @Override
  11238.     public int getPAtk(Creature target)
  11239.     {
  11240.         return (int) (super.getPAtk(target) * Config.PLAYER_P_ATK_MODIFIER);
  11241.     }
  11242.  
  11243.     @Override
  11244.     public int getMAtk(Creature target, Skill skill)
  11245.     {
  11246.         return (int) (super.getMAtk(target, skill) * Config.PLAYER_M_ATK_MODIFIER);
  11247.     }
  11248.  
  11249.     @Override
  11250.     public void onZoneEnter(Zone zone)
  11251.     {
  11252.         if(zone.getType() == ZoneType.SIEGE)
  11253.         {
  11254.             for(CastleSiegeEvent siegeEvent : zone.getEvents(CastleSiegeEvent.class))
  11255.             {
  11256.                 if(containsEvent(siegeEvent))
  11257.                     siegeEvent.addVisitedParticipant(this);
  11258.             }
  11259.         }
  11260.  
  11261.         if(zone.getType() == ZoneType.buff_store && Config.BUFF_STORE_ALLOWED_CLASS_LIST.contains(getClassId().getId()))
  11262.             sendPacket(new SayPacket2(0, ChatType.BATTLEFIELD, getName(), new CustomMessage("l2s.gameserver.model.Player.EnterOfflineBufferZone").toString(this)));
  11263.  
  11264.         if(zone.getEnteringMessageId() != 0)
  11265.             sendPacket(new SystemMessage(zone.getEnteringMessageId()));
  11266.  
  11267.         if(zone.getTemplate().getBlockedActions() != null)
  11268.             blockActions(zone.getTemplate().getBlockedActions());
  11269.  
  11270.         if(zone.getType() == ZoneType.peace_zone)
  11271.         {
  11272.             DuelEvent duel = getEvent(DuelEvent.class);
  11273.             if(duel != null)
  11274.                 duel.abortDuel(this);
  11275.         }
  11276.     }
  11277.  
  11278.     @Override
  11279.     public void onZoneLeave(Zone zone)
  11280.     {
  11281.         if(zone.getType() == ZoneType.buff_store && Config.BUFF_STORE_ALLOWED_CLASS_LIST.contains(getClassId().getId()))
  11282.             sendPacket(new SayPacket2(0, ChatType.BATTLEFIELD, getName(), new CustomMessage("l2s.gameserver.model.Player.ExitOfflineBufferZone").toString(this)));
  11283.  
  11284.         if(zone.getLeavingMessageId() != 0 && isPlayer())
  11285.             sendPacket(new SystemMessage(zone.getLeavingMessageId()));
  11286.  
  11287.         if(zone.getTemplate().getBlockedActions() != null)
  11288.             unblockActions(zone.getTemplate().getBlockedActions());
  11289.     }
  11290.  
  11291.     @Override
  11292.     public boolean hasBasicPropertyResist()
  11293.     {
  11294.         return false;
  11295.     }
  11296. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement