/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* http://www.gnu.org/copyleft/gpl.html
*/
package com.l2jfrozen.gameserver.model.actor.instance;
import static com.l2jfrozen.gameserver.ai.CtrlIntention.AI_INTENTION_MOVE_TO;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import javolution.text.TextBuilder;
import javolution.util.FastList;
import javolution.util.FastMap;
import org.apache.commons.lang.RandomStringUtils;
import com.l2jfrozen.Config;
import com.l2jfrozen.gameserver.ai.CtrlIntention;
import com.l2jfrozen.gameserver.ai.L2CharacterAI;
import com.l2jfrozen.gameserver.ai.L2PlayerAI;
import com.l2jfrozen.gameserver.cache.HtmCache;
import com.l2jfrozen.gameserver.cache.WarehouseCacheManager;
import com.l2jfrozen.gameserver.communitybbs.BB.Forum;
import com.l2jfrozen.gameserver.communitybbs.Manager.ForumsBBSManager;
import com.l2jfrozen.gameserver.controllers.GameTimeController;
import com.l2jfrozen.gameserver.controllers.RecipeController;
import com.l2jfrozen.gameserver.ai.custom.StatusChecker;
import com.l2jfrozen.gameserver.datatables.AccessLevel;
import com.l2jfrozen.gameserver.datatables.GmListTable;
import com.l2jfrozen.gameserver.datatables.HeroSkillTable;
import com.l2jfrozen.gameserver.datatables.NobleSkillTable;
import com.l2jfrozen.gameserver.datatables.SkillTable;
import com.l2jfrozen.gameserver.datatables.csv.FishTable;
import com.l2jfrozen.gameserver.datatables.csv.HennaTable;
import com.l2jfrozen.gameserver.datatables.csv.MapRegionTable;
import com.l2jfrozen.gameserver.datatables.csv.RecipeTable;
import com.l2jfrozen.gameserver.datatables.sql.AccessLevels;
import com.l2jfrozen.gameserver.datatables.sql.AdminCommandAccessRights;
import com.l2jfrozen.gameserver.datatables.sql.CharTemplateTable;
import com.l2jfrozen.gameserver.datatables.sql.ClanTable;
import com.l2jfrozen.gameserver.datatables.sql.ItemTable;
import com.l2jfrozen.gameserver.datatables.sql.NpcTable;
import com.l2jfrozen.gameserver.datatables.sql.SkillTreeTable;
import com.l2jfrozen.gameserver.datatables.xml.ExperienceData;
import com.l2jfrozen.gameserver.geo.GeoData;
import com.l2jfrozen.gameserver.handler.IItemHandler;
import com.l2jfrozen.gameserver.handler.ItemHandler;
import com.l2jfrozen.gameserver.handler.admincommandhandlers.AdminEditChar;
import com.l2jfrozen.gameserver.handler.skillhandlers.SiegeFlag;
import com.l2jfrozen.gameserver.handler.skillhandlers.StrSiegeAssault;
import com.l2jfrozen.gameserver.handler.skillhandlers.TakeCastle;
import com.l2jfrozen.gameserver.managers.CastleManager;
import com.l2jfrozen.gameserver.managers.CoupleManager;
import com.l2jfrozen.gameserver.managers.CursedWeaponsManager;
import com.l2jfrozen.gameserver.managers.DimensionalRiftManager;
import com.l2jfrozen.gameserver.managers.DuelManager;
import com.l2jfrozen.gameserver.managers.FortSiegeManager;
import com.l2jfrozen.gameserver.managers.ItemsOnGroundManager;
import com.l2jfrozen.gameserver.managers.QuestManager;
import com.l2jfrozen.gameserver.managers.SiegeManager;
import com.l2jfrozen.gameserver.managers.TownManager;
import com.l2jfrozen.gameserver.masteriopack.rankpvpsystem.RankPvpSystemConfig;
import com.l2jfrozen.gameserver.masteriopack.rankpvpsystem.RankPvpSystemPc;
import com.l2jfrozen.gameserver.model.BlockList;
import com.l2jfrozen.gameserver.model.FishData;
import com.l2jfrozen.gameserver.model.Inventory;
import com.l2jfrozen.gameserver.model.ItemContainer;
import com.l2jfrozen.gameserver.model.L2Attackable;
import com.l2jfrozen.gameserver.model.L2Character;
import com.l2jfrozen.gameserver.model.L2Clan;
import com.l2jfrozen.gameserver.model.L2ClanMember;
import com.l2jfrozen.gameserver.model.L2Effect;
import com.l2jfrozen.gameserver.model.L2Fishing;
import com.l2jfrozen.gameserver.model.L2Macro;
import com.l2jfrozen.gameserver.model.L2ManufactureList;
import com.l2jfrozen.gameserver.model.L2Object;
import com.l2jfrozen.gameserver.model.L2Party;
import com.l2jfrozen.gameserver.model.L2Radar;
import com.l2jfrozen.gameserver.model.L2RecipeList;
import com.l2jfrozen.gameserver.model.L2Request;
import com.l2jfrozen.gameserver.model.L2ShortCut;
import com.l2jfrozen.gameserver.model.L2Skill;
import com.l2jfrozen.gameserver.model.L2Skill.SkillTargetType;
import com.l2jfrozen.gameserver.model.L2Skill.SkillType;
import com.l2jfrozen.gameserver.model.L2SkillLearn;
import com.l2jfrozen.gameserver.model.L2Summon;
import com.l2jfrozen.gameserver.model.L2World;
import com.l2jfrozen.gameserver.model.Location;
import com.l2jfrozen.gameserver.model.MacroList;
import com.l2jfrozen.gameserver.model.PartyMatchRoom;
import com.l2jfrozen.gameserver.model.PartyMatchRoomList;
import com.l2jfrozen.gameserver.model.PartyMatchWaitingList;
import com.l2jfrozen.gameserver.model.PcFreight;
import com.l2jfrozen.gameserver.model.PcInventory;
import com.l2jfrozen.gameserver.model.PcWarehouse;
import com.l2jfrozen.gameserver.model.PetInventory;
import com.l2jfrozen.gameserver.model.PlayerStatus;
import com.l2jfrozen.gameserver.model.ShortCuts;
import com.l2jfrozen.gameserver.model.TradeList;
import com.l2jfrozen.gameserver.model.actor.appearance.PcAppearance;
import com.l2jfrozen.gameserver.model.actor.knownlist.PcKnownList;
import com.l2jfrozen.gameserver.model.actor.position.L2CharPosition;
import com.l2jfrozen.gameserver.model.actor.stat.PcStat;
import com.l2jfrozen.gameserver.model.actor.status.PcStatus;
import com.l2jfrozen.gameserver.model.base.ClassId;
import com.l2jfrozen.gameserver.model.base.ClassLevel;
import com.l2jfrozen.gameserver.model.base.PlayerClass;
import com.l2jfrozen.gameserver.model.base.Race;
import com.l2jfrozen.gameserver.model.base.SubClass;
import com.l2jfrozen.gameserver.model.entity.Announcements;
import com.l2jfrozen.gameserver.model.entity.Duel;
import com.l2jfrozen.gameserver.model.entity.L2Rebirth;
import com.l2jfrozen.gameserver.model.entity.event.CTF;
import com.l2jfrozen.gameserver.model.entity.event.DM;
import com.l2jfrozen.gameserver.model.entity.event.L2Event;
import com.l2jfrozen.gameserver.model.entity.event.LastManStanding;
import com.l2jfrozen.gameserver.model.entity.event.Raid;
import com.l2jfrozen.gameserver.model.entity.event.TvT;
import com.l2jfrozen.gameserver.model.entity.event.VIP;
import com.l2jfrozen.gameserver.model.entity.olympiad.Olympiad;
import com.l2jfrozen.gameserver.model.entity.sevensigns.SevenSigns;
import com.l2jfrozen.gameserver.model.entity.sevensigns.SevenSignsFestival;
import com.l2jfrozen.gameserver.model.entity.siege.Castle;
import com.l2jfrozen.gameserver.model.entity.siege.FortSiege;
import com.l2jfrozen.gameserver.model.entity.siege.Siege;
import com.l2jfrozen.gameserver.model.entity.siege.clanhalls.DevastatedCastle;
import com.l2jfrozen.gameserver.model.extender.BaseExtender.EventType;
import com.l2jfrozen.gameserver.model.quest.Quest;
import com.l2jfrozen.gameserver.model.quest.QuestState;
import com.l2jfrozen.gameserver.model.zone.type.L2TownZone;
import com.l2jfrozen.gameserver.network.L2GameClient;
import com.l2jfrozen.gameserver.network.SystemMessageId;
import com.l2jfrozen.gameserver.network.serverpackets.ActionFailed;
import com.l2jfrozen.gameserver.network.serverpackets.ChangeWaitType;
import com.l2jfrozen.gameserver.network.serverpackets.CharInfo;
import com.l2jfrozen.gameserver.network.serverpackets.ConfirmDlg;
import com.l2jfrozen.gameserver.network.serverpackets.CreatureSay;
import com.l2jfrozen.gameserver.network.serverpackets.EtcStatusUpdate;
import com.l2jfrozen.gameserver.network.serverpackets.ExAutoSoulShot;
import com.l2jfrozen.gameserver.network.serverpackets.ExDuelUpdateUserInfo;
import com.l2jfrozen.gameserver.network.serverpackets.ExFishingEnd;
import com.l2jfrozen.gameserver.network.serverpackets.ExFishingStart;
import com.l2jfrozen.gameserver.network.serverpackets.ExOlympiadMode;
import com.l2jfrozen.gameserver.network.serverpackets.ExOlympiadUserInfo;
import com.l2jfrozen.gameserver.network.serverpackets.ExPCCafePointInfo;
import com.l2jfrozen.gameserver.network.serverpackets.ExSetCompassZoneCode;
import com.l2jfrozen.gameserver.network.serverpackets.FriendList;
import com.l2jfrozen.gameserver.network.serverpackets.HennaInfo;
import com.l2jfrozen.gameserver.network.serverpackets.InventoryUpdate;
import com.l2jfrozen.gameserver.network.serverpackets.ItemList;
import com.l2jfrozen.gameserver.network.serverpackets.L2GameServerPacket;
import com.l2jfrozen.gameserver.network.serverpackets.LeaveWorld;
import com.l2jfrozen.gameserver.network.serverpackets.MagicSkillCanceld;
import com.l2jfrozen.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jfrozen.gameserver.network.serverpackets.NpcHtmlMessage;
import com.l2jfrozen.gameserver.network.serverpackets.NpcInfo;
import com.l2jfrozen.gameserver.network.serverpackets.ObservationMode;
import com.l2jfrozen.gameserver.network.serverpackets.ObservationReturn;
import com.l2jfrozen.gameserver.network.serverpackets.PartySmallWindowUpdate;
import com.l2jfrozen.gameserver.network.serverpackets.PetInventoryUpdate;
import com.l2jfrozen.gameserver.network.serverpackets.PlaySound;
import com.l2jfrozen.gameserver.network.serverpackets.PledgeShowInfoUpdate;
import com.l2jfrozen.gameserver.network.serverpackets.PledgeShowMemberListDelete;
import com.l2jfrozen.gameserver.network.serverpackets.PledgeShowMemberListUpdate;
import com.l2jfrozen.gameserver.network.serverpackets.PrivateStoreListBuy;
import com.l2jfrozen.gameserver.network.serverpackets.PrivateStoreListSell;
import com.l2jfrozen.gameserver.network.serverpackets.QuestList;
import com.l2jfrozen.gameserver.network.serverpackets.RecipeShopSellList;
import com.l2jfrozen.gameserver.network.serverpackets.RelationChanged;
import com.l2jfrozen.gameserver.network.serverpackets.Ride;
import com.l2jfrozen.gameserver.network.serverpackets.SendTradeDone;
import com.l2jfrozen.gameserver.network.serverpackets.SetupGauge;
import com.l2jfrozen.gameserver.network.serverpackets.ShortBuffStatusUpdate;
import com.l2jfrozen.gameserver.network.serverpackets.ShortCutInit;
import com.l2jfrozen.gameserver.network.serverpackets.SkillCoolTime;
import com.l2jfrozen.gameserver.network.serverpackets.SkillList;
import com.l2jfrozen.gameserver.network.serverpackets.Snoop;
import com.l2jfrozen.gameserver.network.serverpackets.SocialAction;
import com.l2jfrozen.gameserver.network.serverpackets.StatusUpdate;
import com.l2jfrozen.gameserver.network.serverpackets.StopMove;
import com.l2jfrozen.gameserver.network.serverpackets.SystemMessage;
import com.l2jfrozen.gameserver.network.serverpackets.TargetSelected;
import com.l2jfrozen.gameserver.network.serverpackets.TitleUpdate;
import com.l2jfrozen.gameserver.network.serverpackets.TradePressOtherOk;
import com.l2jfrozen.gameserver.network.serverpackets.TradePressOwnOk;
import com.l2jfrozen.gameserver.network.serverpackets.TradeStart;
import com.l2jfrozen.gameserver.network.serverpackets.TutorialShowHtml;
import com.l2jfrozen.gameserver.network.serverpackets.UserInfo;
import com.l2jfrozen.gameserver.network.serverpackets.ValidateLocation;
import com.l2jfrozen.gameserver.skills.BaseStats;
import com.l2jfrozen.gameserver.skills.Formulas;
import com.l2jfrozen.gameserver.skills.Stats;
import com.l2jfrozen.gameserver.skills.effects.EffectCharge;
import com.l2jfrozen.gameserver.skills.l2skills.L2SkillSummon;
import com.l2jfrozen.gameserver.templates.L2Armor;
import com.l2jfrozen.gameserver.templates.L2ArmorType;
import com.l2jfrozen.gameserver.templates.L2EtcItemType;
import com.l2jfrozen.gameserver.templates.L2Henna;
import com.l2jfrozen.gameserver.templates.L2Item;
import com.l2jfrozen.gameserver.templates.L2PcTemplate;
import com.l2jfrozen.gameserver.templates.L2Weapon;
import com.l2jfrozen.gameserver.templates.L2WeaponType;
import com.l2jfrozen.gameserver.thread.LoginServerThread;
import com.l2jfrozen.gameserver.thread.ThreadPoolManager;
import com.l2jfrozen.gameserver.thread.daemons.ItemsAutoDestroy;
import com.l2jfrozen.gameserver.util.Broadcast;
import com.l2jfrozen.gameserver.util.FloodProtectors;
import com.l2jfrozen.gameserver.util.Util;
import com.l2jfrozen.logs.Log;
import com.l2jfrozen.util.CloseUtil;
import com.l2jfrozen.util.Point3D;
import com.l2jfrozen.util.database.L2DatabaseFactory;
import com.l2jfrozen.util.random.Rnd;
/**
* This class represents all player characters in the world.<br>
* There is always a client-thread connected to this (except if a player-store is activated upon logout).
* @version $Revision: 1.6.4 $ $Date: 2009/05/12 19:46:09 $
* @author l2jfrozen dev
*/
public final class L2PcInstance extends L2PlayableInstance
{
/** The Constant RESTORE_SKILLS_FOR_CHAR. */
private static final String RESTORE_SKILLS_FOR_CHAR = "SELECT skill_id,skill_level FROM character_skills WHERE char_obj_id=? AND class_index=?";
/** The Constant ADD_NEW_SKILL. */
private static final String ADD_NEW_SKILL = "INSERT INTO character_skills (char_obj_id,skill_id,skill_level,skill_name,class_index) VALUES (?,?,?,?,?)";
/** The Constant UPDATE_CHARACTER_SKILL_LEVEL. */
private static final String UPDATE_CHARACTER_SKILL_LEVEL = "UPDATE character_skills SET skill_level=? WHERE skill_id=? AND char_obj_id=? AND class_index=?";
/** The Constant DELETE_SKILL_FROM_CHAR. */
private static final String DELETE_SKILL_FROM_CHAR = "DELETE FROM character_skills WHERE skill_id=? AND char_obj_id=? AND class_index=?";
/** The Constant DELETE_CHAR_SKILLS. */
private static final String DELETE_CHAR_SKILLS = "DELETE FROM character_skills WHERE char_obj_id=? AND class_index=?";
/** The Constant ADD_SKILL_SAVE. */
//private static final String ADD_SKILL_SAVE = "INSERT INTO character_skills_save (char_obj_id,skill_id,skill_level,effect_count,effect_cur_time,reuse_delay,restore_type,class_index,buff_index) VALUES (?,?,?,?,?,?,?,?,?)";
private static final String ADD_SKILL_SAVE = "INSERT INTO character_skills_save (char_obj_id,skill_id,skill_level,effect_count,effect_cur_time,reuse_delay,systime,restore_type,class_index,buff_index) VALUES (?,?,?,?,?,?,?,?,?,?)";
/** The Constant RESTORE_SKILL_SAVE. */
private static final String RESTORE_SKILL_SAVE = "SELECT skill_id,skill_level,effect_count,effect_cur_time, reuse_delay FROM character_skills_save WHERE char_obj_id=? AND class_index=? AND restore_type=? ORDER BY buff_index ASC";
/** The Constant DELETE_SKILL_SAVE. */
private static final String DELETE_SKILL_SAVE = "DELETE FROM character_skills_save WHERE char_obj_id=? AND class_index=?";
/** The _is the vip. */
public boolean _isVIP = false, _inEventVIP = false, _isNotVIP = false, _isTheVIP = false;
/** The _original karma vip. */
public int _originalNameColourVIP, _originalKarmaVIP;
/** The _vote timestamp. */
private long _voteTimestamp = 0;
/** The _posticipate sit. */
private boolean _posticipateSit;
/** The sitting task launched. */
protected boolean sittingTaskLaunched;
/** The saved_status. */
private PlayerStatus saved_status = null;
/** The _instance login time. */
private final long _instanceLoginTime;
/** The _last teleport action. */
private long _lastTeleportAction = 0;
private String _hwid;
/**
* Gets the actual status.
*
* @return the actual status
*/
public PlayerStatus getActualStatus(){
saved_status = new PlayerStatus(this);
return saved_status;
}
/**
* Gets the last saved status.
*
* @return the last saved status
*/
public PlayerStatus getLastSavedStatus(){
return saved_status;
}
/**
* Gets the vote timestamp.
*
* @return the _voteTimestamp
*/
public long getVoteTimestamp()
{
return _voteTimestamp;
}
/**
* Sets the vote timestamp.
*
* @param timestamp the _voteTimestamp to set
*/
public void setVoteTimestamp(long timestamp)
{
_voteTimestamp = timestamp;
}
/**
* Gets the vote points.
*
* @return the vote points
*/
public int getVotePoints()
{
Connection con = null;
int votePoints = 0;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement;
statement = con.prepareStatement("select votePoints from accounts where login=?");
statement.setString(1, _accountName);
ResultSet rset = statement.executeQuery();
while(rset.next())
{
votePoints = rset.getInt("votePoints");
}
rset.close();
rset = null;
statement.close();
statement = null;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
}
finally
{
CloseUtil.close(con);
con = null;
}
return votePoints;
}
/**
* Sets the vote points.
*
* @param points the new vote points
*/
public void setVotePoints(int points)
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement;
statement = con.prepareStatement("update accounts set votePoints="+points+" where login='"+_accountName+"'");
statement.execute();
statement.close();
statement = null;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
}
finally
{
CloseUtil.close(con);
con = null;
}
}
/**
* Gets the vote time.
*
* @return the vote time
*/
public int getVoteTime()
{
Connection con = null;
int lastVote = 0;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement;
statement = con.prepareStatement("select lastVote from accounts where login=?");
statement.setString(1, _accountName);
ResultSet rset = statement.executeQuery();
while(rset.next())
{
lastVote = rset.getInt("lastVote");
}
rset.close();
rset = null;
statement.close();
statement = null;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
}
finally
{
CloseUtil.close(con);
con = null;
}
return lastVote;
}
/** The _active_boxes. */
public int _active_boxes = -1;
/** The active_boxes_characters. */
public List<String> active_boxes_characters = new ArrayList<String>();
/** UPDATE characters SET level=?,maxHp=?,curHp=?,maxCp=?,curCp=?,maxMp=?,curMp=?,str=?,con=?,dex=?,_int=?,men=?,wit=? ,face=?,hairStyle=?,hairColor =?,heading=?,x=?,y=?,z=?,exp=?,expBeforeDeath=?,sp=?,karma=?,pvpkills=?,pkkills=?,rec_have =?,rec_left=?,clanid=?,maxload =?,race=?,classid=?,deletetime=?,title=?,accesslevel=?,online=?,isin7sdungeon=?,clan_privs =?,wantspeace=?,base_class =?,onlinetime=?,in_jail=?,jail_timer=?,newbie=?,nobless=?,power_grade=?,subpledge=?,last_recom_date =?,lvl_joined_academy =?,apprentice=?,sponsor=?,varka_ketra_ally=?,clan_join_expiry_time=?,clan_create_expiry_time=? ,char_name=?,death_penalty_level=?,good=?,evil=?,gve_kills=? WHERE obj_id=?. */
private static final String UPDATE_CHARACTER = "UPDATE characters SET level=?,maxHp=?,curHp=?,maxCp=?,curCp=?,maxMp=?,curMp=?,str=?,con=?,dex=?,_int=?,men=?,wit=?,face=?,hairStyle=?,hairColor=?,heading=?,x=?,y=?,z=?,exp=?,expBeforeDeath=?,sp=?,karma=?,pvpkills=?,pkkills=?,rec_have=?,rec_left=?,clanid=?,maxload=?,race=?,classid=?,deletetime=?,title=?,accesslevel=?,online=?,isin7sdungeon=?,clan_privs=?,wantspeace=?,base_class=?,onlinetime=?,punish_level=?,punish_timer=?,newbie=?,nobless=?,power_grade=?,subpledge=?,last_recom_date=?,lvl_joined_academy=?,apprentice=?,sponsor=?,varka_ketra_ally=?,clan_join_expiry_time=?,clan_create_expiry_time=?,char_name=?,death_penalty_level=?,pc_point=?,aio=?,aio_end=?,arena_wins=?,arena_defeats=? WHERE obj_id=?";
/** SELECT account_name, obj_Id, char_name, level, maxHp, curHp, maxCp, curCp, maxMp, curMp, acc, crit, evasion, mAtk, mDef, mSpd, pAtk, pDef, pSpd, runSpd, walkSpd, str, con, dex, _int, men, wit, face, hairStyle, hairColor, sex, heading, x, y, z, movement_multiplier, attack_speed_multiplier, colRad, colHeight, exp, expBeforeDeath, sp, karma, pvpkills, pkkills, clanid, maxload, race, classid, deletetime, cancraft, title, rec_have, rec_left, accesslevel, online, char_slot, lastAccess, clan_privs, wantspeace, base_class, onlinetime, isin7sdungeon, in_jail, jail_timer, newbie, nobless, power_grade, subpledge, last_recom_date, lvl_joined_academy, apprentice, sponsor, varka_ketra_ally,clan_join_expiry_time,clan_create_expiry_time,death_penalty_level,good,evil,gve_kills FROM characters WHERE obj_id=?. */
//private static final String RESTORE_CHARACTER = "SELECT account_name, obj_Id, char_name, level, maxHp, curHp, maxCp, curCp, maxMp, curMp, acc, crit, evasion, mAtk, mDef, mSpd, pAtk, pDef, pSpd, runSpd, walkSpd, str, con, dex, _int, men, wit, face, hairStyle, hairColor, sex, heading, x, y, z, movement_multiplier, attack_speed_multiplier, colRad, colHeight, exp, expBeforeDeath, sp, karma, pvpkills, pkkills, clanid, maxload, race, classid, deletetime, cancraft, title, rec_have, rec_left, accesslevel, online, char_slot, lastAccess, clan_privs, wantspeace, base_class, onlinetime, isin7sdungeon, in_jail, jail_timer, newbie, nobless, power_grade, subpledge, last_recom_date, lvl_joined_academy, apprentice, sponsor, varka_ketra_ally,clan_join_expiry_time,clan_create_expiry_time,death_penalty_level,pc_point,banchat_time,name_color,title_color,first_log,aio,aio_end FROM characters WHERE obj_id=?";
private static final String RESTORE_CHARACTER = "SELECT account_name, obj_Id, char_name, level, maxHp, curHp, maxCp, curCp, maxMp, curMp, acc, crit, evasion, mAtk, mDef, mSpd, pAtk, pDef, pSpd, runSpd, walkSpd, str, con, dex, _int, men, wit, face, hairStyle, hairColor, sex, heading, x, y, z, movement_multiplier, attack_speed_multiplier, colRad, colHeight, exp, expBeforeDeath, sp, karma, pvpkills, pkkills, clanid, maxload, race, classid, deletetime, cancraft, title, rec_have, rec_left, accesslevel, online, char_slot, lastAccess, clan_privs, wantspeace, base_class, onlinetime, isin7sdungeon,punish_level,punish_timer," +/* in_jail, jail_timer,*/ "newbie, nobless, power_grade, subpledge, last_recom_date, lvl_joined_academy, apprentice, sponsor, varka_ketra_ally,clan_join_expiry_time,clan_create_expiry_time,death_penalty_level,pc_point,first_log,aio,aio_end,arena_wins,arena_defeats FROM characters WHERE obj_id=?";
/** The Constant STATUS_DATA_GET. */
private static final String STATUS_DATA_GET = "SELECT hero, noble, donator, hero_end_date FROM characters_custom_data WHERE obj_Id = ?";
/** The Constant RESTORE_SKILLS_FOR_CHAR_ALT_SUBCLASS. */
private static final String RESTORE_SKILLS_FOR_CHAR_ALT_SUBCLASS = "SELECT skill_id,skill_level FROM character_skills WHERE char_obj_id=? ORDER BY (skill_level+0)";
// ---------------------- L2JFrozen Addons ---------------------------------- //
/** The Constant RESTORE_CHAR_SUBCLASSES. */
private static final String RESTORE_CHAR_SUBCLASSES = "SELECT class_id,exp,sp,level,class_index FROM character_subclasses WHERE char_obj_id=? ORDER BY class_index ASC";
/** The Constant ADD_CHAR_SUBCLASS. */
private static final String ADD_CHAR_SUBCLASS = "INSERT INTO character_subclasses (char_obj_id,class_id,exp,sp,level,class_index) VALUES (?,?,?,?,?,?)";
/** The Constant UPDATE_CHAR_SUBCLASS. */
private static final String UPDATE_CHAR_SUBCLASS = "UPDATE character_subclasses SET exp=?,sp=?,level=?,class_id=? WHERE char_obj_id=? AND class_index =?";
/** The Constant DELETE_CHAR_SUBCLASS. */
private static final String DELETE_CHAR_SUBCLASS = "DELETE FROM character_subclasses WHERE char_obj_id=? AND class_index=?";
/** The Constant RESTORE_CHAR_HENNAS. */
private static final String RESTORE_CHAR_HENNAS = "SELECT slot,symbol_id FROM character_hennas WHERE char_obj_id=? AND class_index=?";
/** The Constant ADD_CHAR_HENNA. */
private static final String ADD_CHAR_HENNA = "INSERT INTO character_hennas (char_obj_id,symbol_id,slot,class_index) VALUES (?,?,?,?)";
/** The Constant DELETE_CHAR_HENNA. */
private static final String DELETE_CHAR_HENNA = "DELETE FROM character_hennas WHERE char_obj_id=? AND slot=? AND class_index=?";
/** The Constant DELETE_CHAR_HENNAS. */
private static final String DELETE_CHAR_HENNAS = "DELETE FROM character_hennas WHERE char_obj_id=? AND class_index=?";
/** The Constant DELETE_CHAR_SHORTCUTS. */
private static final String DELETE_CHAR_SHORTCUTS = "DELETE FROM character_shortcuts WHERE char_obj_id=? AND class_index=?";
/** The Constant RESTORE_CHAR_RECOMS. */
private static final String RESTORE_CHAR_RECOMS = "SELECT char_id,target_id FROM character_recommends WHERE char_id=?";
/** The Constant ADD_CHAR_RECOM. */
private static final String ADD_CHAR_RECOM = "INSERT INTO character_recommends (char_id,target_id) VALUES (?,?)";
/** The Constant DELETE_CHAR_RECOMS. */
private static final String DELETE_CHAR_RECOMS = "DELETE FROM character_recommends WHERE char_id=?";
/** The Constant REQUEST_TIMEOUT. */
public static final int REQUEST_TIMEOUT = 15;
/** The Constant STORE_PRIVATE_NONE. */
public static final int STORE_PRIVATE_NONE = 0;
/** The Constant STORE_PRIVATE_SELL. */
public static final int STORE_PRIVATE_SELL = 1;
/** The Constant STORE_PRIVATE_BUY. */
public static final int STORE_PRIVATE_BUY = 3;
/** The Constant STORE_PRIVATE_MANUFACTURE. */
public static final int STORE_PRIVATE_MANUFACTURE = 5;
/** The Constant STORE_PRIVATE_PACKAGE_SELL. */
public static final int STORE_PRIVATE_PACKAGE_SELL = 8;
/** The fmt. */
private final SimpleDateFormat fmt = new SimpleDateFormat("H:mm.");
/** The table containing all minimum level needed for each Expertise (None, D, C, B, A, S). */
private static final int[] EXPERTISE_LEVELS =
{
SkillTreeTable.getInstance().getExpertiseLevel(0), //NONE
SkillTreeTable.getInstance().getExpertiseLevel(1), //D
SkillTreeTable.getInstance().getExpertiseLevel(2), //C
SkillTreeTable.getInstance().getExpertiseLevel(3), //B
SkillTreeTable.getInstance().getExpertiseLevel(4), //A
SkillTreeTable.getInstance().getExpertiseLevel(5), //S
};
/** The Constant COMMON_CRAFT_LEVELS. */
private static final int[] COMMON_CRAFT_LEVELS =
{
5, 20, 28, 36, 43, 49, 55, 62
};
//private static Logger _log = Logger.getLogger(L2PcInstance.class.getName());
/**
* The Class AIAccessor.
*/
public class AIAccessor extends L2Character.AIAccessor
{
/**
* Instantiates a new aI accessor.
*/
protected AIAccessor()
{}
/**
* Gets the player.
*
* @return the player
*/
public L2PcInstance getPlayer()
{
return L2PcInstance.this;
}
/**
* Do pickup item.
*
* @param object the object
*/
public void doPickupItem(L2Object object)
{
L2PcInstance.this.doPickupItem(object);
}
/**
* Do interact.
*
* @param target the target
*/
public void doInteract(L2Character target)
{
L2PcInstance.this.doInteract(target);
}
/*
* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character.AIAccessor#doAttack(com.l2jfrozen.gameserver.model.L2Character)
*/
@Override
public void doAttack(L2Character target)
{
if (isInsidePeaceZone(L2PcInstance.this, target))
{
// if(target instanceof L2PcInstance){ //the only case where to avoid the attack is if the attacked is L2PcInstance
// //and one of them is not into a fun event, otherwise continue
//
// if (!isInFunEvent() || !((L2PcInstance)target).isInFunEvent()) {
// getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
sendPacket(ActionFailed.STATIC_PACKET);
return;
// }
// }
}
// during teleport phase, players cant do any attack
if ((TvT.is_teleport() && _inEventTvT) || (CTF.is_teleport() && _inEventCTF) || (DM.is_teleport() && _inEventDM))
{
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
super.doAttack(target);
// cancel the recent fake-death protection instantly if the player attacks or casts spells
getPlayer().setRecentFakeDeath(false);
/*
* if(getPlayer().isSilentMoving()) { L2Effect silentMove = getPlayer().getFirstEffect(L2Effect.EffectType.SILENT_MOVE); if(silentMove != null) { silentMove.exit(true); } }
*/
synchronized (_cubics)
{
for (L2CubicInstance cubic : _cubics.values())
if (cubic.getId() != L2CubicInstance.LIFE_CUBIC)
{
cubic.doAction(/* target */);
}
}
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character.AIAccessor#doCast(com.l2jfrozen.gameserver.model.L2Skill)
*/
@Override
public void doCast(L2Skill skill)
{
// cancel the recent fake-death protection instantly if the player attacks or casts spells
getPlayer().setRecentFakeDeath(false);
if(skill == null)
return;
// Like L2OFF you can use cupid bow skills on peace zone
// Like L2OFF players can use TARGET_AURA skills on peace zone, all targets will be ignored.
if (skill.isOffensive() && (isInsidePeaceZone(L2PcInstance.this, getTarget()) && skill.getTargetType() != SkillTargetType.TARGET_AURA) && (skill.getId() != 3261 && skill.getId() != 3260 && skill.getId() != 3262)) //check limited to active target
{
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
//during teleport phase, players cant do any attack
if((TvT.is_teleport() && _inEventTvT)
|| (CTF.is_teleport() && _inEventCTF)
|| (DM.is_teleport() && _inEventDM)){
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
super.doCast(skill);
if(!skill.isOffensive())
return;
/*
if(getPlayer().isSilentMoving() && skill.getSkillType() != SkillType.AGGDAMAGE)
{
L2Effect silentMove = getPlayer().getFirstEffect(L2Effect.EffectType.SILENT_MOVE);
if(silentMove != null)
{
silentMove.exit(true);
}
}
*/
switch(skill.getTargetType())
{
case TARGET_GROUND:
return;
default:
{
L2Object mainTarget = skill.getFirstOfTargetList(L2PcInstance.this);
if(mainTarget == null || !(mainTarget instanceof L2Character))
return;
synchronized(_cubics)
{
for(L2CubicInstance cubic : _cubics.values())
if(cubic!=null && cubic.getId() != L2CubicInstance.LIFE_CUBIC)
{
cubic.doAction(/*(L2Character) mainTarget*/);
}
}
mainTarget = null;
}
break;
}
}
}
/** The _client. */
private L2GameClient _client;
/** The _account name. */
private String _accountName;
/** The _delete timer. */
private long _deleteTimer;
/** The _is online. */
private boolean _isOnline = false;
/** The _online time. */
private long _onlineTime;
/** The _online begin time. */
private long _onlineBeginTime;
/** The _last access. */
private long _lastAccess;
/** The _uptime. */
private long _uptime;
/** The _base class. */
protected int _baseClass;
/** The _active class. */
protected int _activeClass;
/** The _class index. */
protected int _classIndex = 0;
/** Fireworks on first login. */
private boolean _first_log;
/** PC BANG POINT. */
private int pcBangPoint = 0;
/** The list of sub-classes this character has. */
private Map<Integer, SubClass> _subClasses;
/** The _appearance. */
private PcAppearance _appearance;
/** The Identifier of the L2PcInstance. */
private int _charId = 0x00030b7a;
/** The Experience of the L2PcInstance before the last Death Penalty. */
private long _expBeforeDeath;
/** The Karma of the L2PcInstance (if higher than 0, the name of the L2PcInstance appears in red). */
private int _karma;
/** The number of player killed during a PvP (the player killed was PvP Flagged). */
private int _pvpKills;
/** The PK counter of the L2PcInstance (= Number of non PvP Flagged player killed). */
private int _pkKills;
/** The _last kill. */
private int _lastKill = 0;
/** The count. */
private int count = 0;
/** The PvP Flag state of the L2PcInstance (0=White, 1=Purple). */
private byte _pvpFlag;
/** The Siege state of the L2PcInstance. */
private byte _siegeState = 0;
/** The _cur weight penalty. */
private int _curWeightPenalty = 0;
/** The _last compass zone. */
private int _lastCompassZone; // the last compass zone update send to the client
/** The _zone validate counter. */
private byte _zoneValidateCounter = 4;
/** The _is in7s dungeon. */
private boolean _isIn7sDungeon = false;
//private boolean _inJail = false;
//private long _jailTimer = 0;
//private ScheduledFuture<?> _jailTask;
/** Special hero aura values. */
private int heroConsecutiveKillCount = 0;
/** The is pvp hero. */
private boolean isPVPHero = false;
/**Cant gain xp. */
private boolean _cantGainXP;
public void cantGainXP(boolean b)
{
_cantGainXP = b;
}
public boolean cantGainXP()
{
return _cantGainXP;
}
/** character away mode *. */
private boolean _awaying = false;
/** The _is away. */
private boolean _isAway = false;
/** The _original title color away. */
public int _originalTitleColorAway;
/** The _original title away. */
public String _originalTitleAway;
/** The _is aio. */
private boolean _isAio = false;
/** The _aio_end time. */
private long _aio_endTime = 0;
/** Event parameters. */
public int eventX;
/** The event y. */
public int eventY;
/** The event z. */
public int eventZ;
/** The event karma. */
public int eventKarma;
/** The event pvp kills. */
public int eventPvpKills;
/** The event pk kills. */
public int eventPkKills;
/** The event title. */
public String eventTitle;
/** The kills. */
public List<String> kills = new LinkedList<String>();
/** The event sit forced. */
public boolean eventSitForced = false;
/** The at event. */
public boolean atEvent = false;
/** Raid Engine parameters */
public String _originalTitleRaid;
public int _originalNameColorRaid, _originalTitleColorRaid, _originalKarmaRaid;
public boolean _inEventRaid = false;
/** TvT Engine parameters. */
public String _teamNameTvT, _originalTitleTvT;
/** The _original karma tv t. */
public int _originalNameColorTvT = 0, _countTvTkills, _countTvTdies, _originalKarmaTvT;
/** The _in event tv t. */
public boolean _inEventTvT = false;
/** CTF Engine parameters. */
public String _teamNameCTF,
_teamNameHaveFlagCTF,
_originalTitleCTF;
/** The _count ct fflags. */
public int _originalNameColorCTF = 0,
_originalKarmaCTF,
_countCTFflags;
/** The _have flag ctf. */
public boolean _inEventCTF = false,
_haveFlagCTF = false;
/** The _pos checker ctf. */
public Future<?> _posCheckerCTF = null;
/** DM Engine parameters. */
public String _originalTitleDM;
/** The _original karma dm. */
public int _originalNameColorDM = 0,
_countDMkills,
_originalKarmaDM;
/** The _in event dm. */
public boolean _inEventDM = false;
/** The _correct word. */
public int _correctWord = -1;
/** The _stop kick bot task. */
public boolean _stopKickBotTask = false;
/** Event Engine parameters. */
public int _originalNameColor, _countKills, _originalKarma, _eventKills;
/** The _in event. */
public boolean _inEvent = false;
/** Olympiad. */
private boolean _inOlympiadMode = false;
/** The _ olympiad start. */
private boolean _OlympiadStart = false;
/** The _ olympiad position. */
private int[] _OlympiadPosition;
/** The _olympiad game id. */
private int _olympiadGameId = -1;
/** The _olympiad side. */
private int _olympiadSide = -1;
// Rank PvP System by Masterio
public RankPvpSystemPc _rankPvpSystemPc = new RankPvpSystemPc();
/** The dmg dealt. */
//public int dmgDealt = 0;
/** Duel. */
private boolean _isInDuel = false;
/** The _duel state. */
private int _duelState = Duel.DUELSTATE_NODUEL;
/** The _duel id. */
private int _duelId = 0;
/** The _no duel reason. */
private SystemMessageId _noDuelReason = SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL;
/** Boat. */
private boolean _inBoat;
/** The _boat. */
private L2BoatInstance _boat;
/** The _in boat position. */
private Point3D _inBoatPosition;
/** The _mount type. */
private int _mountType;
/** Store object used to summon the strider you are mounting *. */
private int _mountObjectID = 0;
/** The _telemode. */
public int _telemode = 0;
/** The _is silent moving. */
private int _isSilentMoving = 0;
/** The _in crystallize. */
private boolean _inCrystallize;
/** The _in craft mode. */
private boolean _inCraftMode;
/** The table containing all L2RecipeList of the L2PcInstance. */
private Map<Integer, L2RecipeList> _dwarvenRecipeBook = new FastMap<Integer, L2RecipeList>();
/** The _common recipe book. */
private Map<Integer, L2RecipeList> _commonRecipeBook = new FastMap<Integer, L2RecipeList>();
/** True if the L2PcInstance is sitting. */
private boolean _waitTypeSitting;
/** True if the L2PcInstance is using the relax skill. */
private boolean _relax;
/** Location before entering Observer Mode. */
private int _obsX;
/** The _obs y. */
private int _obsY;
/** The _obs z. */
private int _obsZ;
/** The _observer mode. */
private boolean _observerMode = false;
/** Stored from last ValidatePosition *. */
private Location _lastClientPosition = new Location(0, 0, 0);
/** The _last server position. */
private Location _lastServerPosition = new Location(0, 0, 0);
/** The number of recommandation obtained by the L2PcInstance. */
private int _recomHave; // how much I was recommended by others
/** The number of recommandation that the L2PcInstance can give. */
private int _recomLeft; // how many recomendations I can give to others
/** Date when recom points were updated last time. */
private long _lastRecomUpdate;
/** List with the recomendations that I've give. */
private List<Integer> _recomChars = new FastList<Integer>();
/** The random number of the L2PcInstance. */
//private static final Random _rnd = new Random();
private PcInventory _inventory = new PcInventory(this);
/** The _warehouse. */
private PcWarehouse _warehouse;
/** The _freight. */
private PcFreight _freight = new PcFreight(this);
/** The Private Store type of the L2PcInstance (STORE_PRIVATE_NONE=0, STORE_PRIVATE_SELL=1, sellmanage=2, STORE_PRIVATE_BUY=3, buymanage=4, STORE_PRIVATE_MANUFACTURE=5). */
private int _privatestore;
/** The _active trade list. */
private TradeList _activeTradeList;
/** The _active warehouse. */
private ItemContainer _activeWarehouse;
/** The _create list. */
private L2ManufactureList _createList;
/** The _sell list. */
private TradeList _sellList;
/** The _buy list. */
private TradeList _buyList;
/** True if the L2PcInstance is newbie. */
private boolean _newbie;
private boolean _inLMS = false;
private boolean inKamalokaEvent = false;
/** The _noble. */
private boolean _noble = false;
/** The _hero. */
private boolean _hero = false;
// kamaloka event
private boolean _kamaStatus = false;
private long _kamaStatus_endTime = 0;
private boolean _kama2Status = false;
private long _kama2Status_endTime = 0;
private boolean _kama3Status = false;
private long _kama3Status_endTime = 0;
/** The _donator. */
private boolean _donator = false;
/** The L2FolkInstance corresponding to the last Folk wich one the player talked. */
private L2FolkInstance _lastFolkNpc = null;
/** Last NPC Id talked on a quest. */
private int _questNpcObject = 0;
private int _party_find = 0;
//summon friend
/** The _summon request. */
private SummonRequest _summonRequest = new SummonRequest();
/**
* The Class SummonRequest.
*/
protected static class SummonRequest
{
/** The _target. */
private L2PcInstance _target = null;
/** The _skill. */
private L2Skill _skill = null;
/**
* Sets the target.
*
* @param destination the destination
* @param skill the skill
*/
public void setTarget(L2PcInstance destination, L2Skill skill)
{
_target = destination;
_skill = skill;
}
/**
* Gets the target.
*
* @return the target
*/
public L2PcInstance getTarget()
{
return _target;
}
/**
* Gets the skill.
*
* @return the skill
*/
public L2Skill getSkill()
{
return _skill;
}
}
/** The table containing all Quests began by the L2PcInstance. */
private Map<String, QuestState> _quests = new FastMap<String, QuestState>();
/** The list containing all shortCuts of this L2PcInstance. */
private ShortCuts _shortCuts = new ShortCuts(this);
/** The list containing all macroses of this L2PcInstance. */
private MacroList _macroses = new MacroList(this);
/** The _snoop listener. */
private List<L2PcInstance> _snoopListener = new FastList<L2PcInstance>();
/** The _snooped player. */
private List<L2PcInstance> _snoopedPlayer = new FastList<L2PcInstance>();
/** The _skill learning class id. */
private ClassId _skillLearningClassId;
// hennas
/** The _henna. */
private final L2HennaInstance[] _henna = new L2HennaInstance[3];
/** The _henna str. */
private int _hennaSTR;
/** The _henna int. */
private int _hennaINT;
/** The _henna dex. */
private int _hennaDEX;
/** The _henna men. */
private int _hennaMEN;
/** The _henna wit. */
private int _hennaWIT;
/** The _henna con. */
private int _hennaCON;
/** The L2Summon of the L2PcInstance. */
private L2Summon _summon = null;
// apparently, a L2PcInstance CAN have both a summon AND a tamed beast at the same time!!
/** The _tamed beast. */
private L2TamedBeastInstance _tamedBeast = null;
// client radar
/** The _radar. */
private L2Radar _radar;
// Clan related attributes
/** The Clan Identifier of the L2PcInstance. */
private int _clanId = 0;
/** The Clan object of the L2PcInstance. */
private L2Clan _clan;
/** Apprentice and Sponsor IDs. */
private int _apprentice = 0;
/** The _sponsor. */
private int _sponsor = 0;
/** The _clan join expiry time. */
private long _clanJoinExpiryTime;
/** The _clan create expiry time. */
private long _clanCreateExpiryTime;
/** The _power grade. */
private int _powerGrade = 0;
/** The _clan privileges. */
private int _clanPrivileges = 0;
/** L2PcInstance's pledge class (knight, Baron, etc.) */
private int _pledgeClass = 0;
/** The _pledge type. */
private int _pledgeType = 0;
/** Level at which the player joined the clan as an academy member. */
private int _lvlJoinedAcademy = 0;
/** The _wants peace. */
private int _wantsPeace = 0;
//Death Penalty Buff Level
/** The _death penalty buff level. */
private int _deathPenaltyBuffLevel = 0;
// private int _ChatFilterCount = 0;
//GM related variables
// private boolean _isGm;
/** The _access level. */
private AccessLevel _accessLevel;
//private boolean _chatBanned = false; // Chat Banned
//private ScheduledFuture<?> _chatUnbanTask = null;
/** The _message refusal. */
private boolean _messageRefusal = false; // message refusal mode
/** The _diet mode. */
private boolean _dietMode = false; // ignore weight penalty
/** The _exchange refusal. */
private boolean _exchangeRefusal = false; // Exchange refusal
/** The _party. */
private L2Party _party;
private long _lastAttackPacket = 0;
// this is needed to find the inviting player for Party response
// there can only be one active party request at once
/** The _active requester. */
private L2PcInstance _activeRequester;
/** The _request expire time. */
private long _requestExpireTime = 0;
/** The _request. */
private L2Request _request = new L2Request(this);
/** The _arrow item. */
private L2ItemInstance _arrowItem;
// Used for protection after teleport
/** The _protect end time. */
private long _protectEndTime = 0;
public boolean isSpawnProtected() { return _protectEndTime > GameTimeController.getGameTicks(); }
private long _teleportProtectEndTime = 0;
public boolean isTeleportProtected() { return _teleportProtectEndTime > GameTimeController.getGameTicks(); }
// protects a char from agro mobs when getting up from fake death
/** The _recent fake death end time. */
private long _recentFakeDeathEndTime = 0;
/** The fists L2Weapon of the L2PcInstance (used when no weapon is equiped). */
private L2Weapon _fistsWeaponItem;
/** The _chars. */
private final Map<Integer, String> _chars = new FastMap<Integer, String>();
//private byte _updateKnownCounter = 0;
/** The current higher Expertise of the L2PcInstance (None=0, D=1, C=2, B=3, A=4, S=5). */
private int _expertiseIndex; // index in EXPERTISE_LEVELS
/** The _expertise penalty. */
private int _expertisePenalty = 0;
/** The _heavy_mastery. */
private boolean _heavy_mastery = false;
/** The _light_mastery. */
private boolean _light_mastery = false;
/** The _robe_mastery. */
private boolean _robe_mastery = false;
/** The _mastery penalty. */
private int _masteryPenalty = 0;
/** The _active enchant item. */
private L2ItemInstance _activeEnchantItem = null;
/** The _inventory disable. */
protected boolean _inventoryDisable = false;
/** The _cubics. */
protected Map<Integer, L2CubicInstance> _cubics = new FastMap<Integer, L2CubicInstance>();
/** Active shots. A FastSet variable would actually suffice but this was changed to fix threading stability... */
protected Map<Integer, Integer> _activeSoulShots = new FastMap<Integer, Integer>().shared();
/** The soul shot lock. */
public final ReentrantLock soulShotLock = new ReentrantLock();
/** The dialog. */
public Quest dialog = null;
/** new loto ticket *. */
private int _loto[] = new int[5];
//public static int _loto_nums[] = {0,1,2,3,4,5,6,7,8,9,};
/** new race ticket *. */
private int _race[] = new int[2];
/** The _block list. */
private final BlockList _blockList = new BlockList(this);
/** The _team. */
private int _team = 0;
/** lvl of alliance with ketra orcs or varka silenos, used in quests and aggro checks [-5,-1] varka, 0 neutral, [1,5] ketra. */
private int _alliedVarkaKetra = 0;
/** ********************************************************************* Adventurers' coupon (0-no 1-NG 2-D 3-NG & D) 0 = No coupon 1 = coupon for No Grade 2 = coupon for D Grade 3 = coupon for No & D Grade ********************************************************************. */
private int _hasCoupon = 0;
/** The _fish combat. */
private L2Fishing _fishCombat;
/** The _fishing. */
private boolean _fishing = false;
/** The _fishx. */
private int _fishx = 0;
/** The _fishy. */
private int _fishy = 0;
/** The _fishz. */
private int _fishz = 0;
/** The _task rent pet. */
private ScheduledFuture<?> _taskRentPet;
/** The _task water. */
private ScheduledFuture<?> _taskWater;
/** Bypass validations. */
private List<String> _validBypass = new FastList<String>();
/** The _valid bypass2. */
private List<String> _validBypass2 = new FastList<String>();
/** The _valid link. */
private List<String> _validLink = new FastList<String>();
/** The _forum mail. */
private Forum _forumMail;
/** The _forum memo. */
private Forum _forumMemo;
/** Current skill in use. */
private SkillDat _currentSkill;
private SkillDat _currentPetSkill;
/** Skills queued because a skill is already in progress. */
private SkillDat _queuedSkill;
/* Flag to disable equipment/skills while wearing formal wear **/
/** The _ is wearing formal wear. */
private boolean _IsWearingFormalWear = false;
/** The _current skill world position. */
private Point3D _currentSkillWorldPosition;
/** The _cursed weapon equiped id. */
private int _cursedWeaponEquipedId = 0;
// private boolean _combatFlagEquippedId = false;
/** The _revive requested. */
private int _reviveRequested = 0;
/** The _revive power. */
private double _revivePower = 0;
/** The _revive pet. */
private boolean _revivePet = false;
/** The _cp update inc check. */
private double _cpUpdateIncCheck = .0;
/** The _cp update dec check. */
private double _cpUpdateDecCheck = .0;
/** The _cp update interval. */
private double _cpUpdateInterval = .0;
/** The _mp update inc check. */
private double _mpUpdateIncCheck = .0;
/** The _mp update dec check. */
private double _mpUpdateDecCheck = .0;
/** The _mp update interval. */
private double _mpUpdateInterval = .0;
private long timerToAttack;
//private boolean isInDangerArea;
////////////////////////////////////////////////////////////////////
//START CHAT BAN SYSTEM
////////////////////////////////////////////////////////////////////
//private long _chatBanTimer = 0L;
//private ScheduledFuture<?> _chatBanTask = null;
////////////////////////////////////////////////////////////////////
//END CHAT BAN SYSTEM
////////////////////////////////////////////////////////////////////
/** The _is offline. */
private boolean _isOffline = false;
/** The _is trade off. */
private boolean _isTradeOff = false;
/** The _offline shop start. */
private long _offlineShopStart = 0;
/** The _original name color offline. */
public int _originalNameColorOffline = 0xFFFFFF;
/** Herbs Task Time *. */
private int _herbstask = 0;
/** 2vs2 event */
private boolean inArenaEvent = false;
/**
* Task for Herbs.
*/
public class HerbTask implements Runnable
{
/** The _process. */
private String _process;
/** The _item id. */
private int _itemId;
/** The _count. */
private int _count;
/** The _reference. */
private L2Object _reference;
/** The _send message. */
private boolean _sendMessage;
/**
* Instantiates a new herb task.
*
* @param process the process
* @param itemId the item id
* @param count the count
* @param reference the reference
* @param sendMessage the send message
*/
HerbTask(String process, int itemId, int count, L2Object reference, boolean sendMessage)
{
_process = process;
_itemId = itemId;
_count = count;
_reference = reference;
_sendMessage = sendMessage;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
@SuppressWarnings("synthetic-access")
public void run()
{
try
{
addItem(_process, _itemId, _count, _reference, _sendMessage);
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.WARNING, "", t);
}
}
}
// L2JMOD Wedding
/** The _married. */
private boolean _married = false;
/** The _married type. */
private int _marriedType = 0;
/** The _partner id. */
private int _partnerId = 0;
/** The _couple id. */
private int _coupleId = 0;
/** The _engagerequest. */
private boolean _engagerequest = false;
/** The _engageid. */
private int _engageid = 0;
/** The _marryrequest. */
private boolean _marryrequest = false;
/** The _marryaccepted. */
private boolean _marryaccepted = false;
/** Quake System. */
private int quakeSystem = 0;
/** The _is locked. */
private boolean _isLocked = false;
/** The _is stored. */
private boolean _isStored = false;
/**
* Skill casting information (used to queue when several skills are cast in a short time) *.
*/
public class SkillDat
{
/** The _skill. */
private L2Skill _skill;
/** The _ctrl pressed. */
private boolean _ctrlPressed;
/** The _shift pressed. */
private boolean _shiftPressed;
/**
* Instantiates a new skill dat.
*
* @param skill the skill
* @param ctrlPressed the ctrl pressed
* @param shiftPressed the shift pressed
*/
protected SkillDat(L2Skill skill, boolean ctrlPressed, boolean shiftPressed)
{
_skill = skill;
_ctrlPressed = ctrlPressed;
_shiftPressed = shiftPressed;
}
/**
* Checks if is ctrl pressed.
*
* @return true, if is ctrl pressed
*/
public boolean isCtrlPressed()
{
return _ctrlPressed;
}
/**
* Checks if is shift pressed.
*
* @return true, if is shift pressed
*/
public boolean isShiftPressed()
{
return _shiftPressed;
}
/**
* Gets the skill.
*
* @return the skill
*/
public L2Skill getSkill()
{
return _skill;
}
/**
* Gets the skill id.
*
* @return the skill id
*/
public int getSkillId()
{
return getSkill() != null ? getSkill().getId() : -1;
}
}
/**
* Create a new L2PcInstance and add it in the characters table of the database.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Create a new L2PcInstance with an account name</li> <li>Set the name, the Hair Style, the Hair Color and the
* Face type of the L2PcInstance</li> <li>Add the player in the characters table of the database</li><BR>
* <BR>
*
* @param objectId Identifier of the object to initialized
* @param template The L2PcTemplate to apply to the L2PcInstance
* @param accountName The name of the L2PcInstance
* @param name The name of the L2PcInstance
* @param hairStyle The hair style Identifier of the L2PcInstance
* @param hairColor The hair color Identifier of the L2PcInstance
* @param face The face type Identifier of the L2PcInstance
* @param sex the sex
* @return The L2PcInstance added to the database or null
*/
public static L2PcInstance create(int objectId, L2PcTemplate template, String accountName, String name, byte hairStyle, byte hairColor, byte face, boolean sex)
{
// Create a new L2PcInstance with an account name
PcAppearance app = new PcAppearance(face, hairColor, hairStyle, sex);
L2PcInstance player = new L2PcInstance(objectId, template, accountName, app);
app = null;
// Set the name of the L2PcInstance
player.setName(name);
// Set the base class ID to that of the actual class ID.
player.setBaseClass(player.getClassId());
if(Config.ALT_GAME_NEW_CHAR_ALWAYS_IS_NEWBIE)
{
player.setNewbie(true);
}
// Add the player in the characters table of the database
boolean ok = player.createDb();
if(!ok)
return null;
return player;
}
/**
* Creates the dummy player.
*
* @param objectId the object id
* @param name the name
* @return the l2 pc instance
*/
public static L2PcInstance createDummyPlayer(int objectId, String name)
{
// Create a new L2PcInstance with an account name
L2PcInstance player = new L2PcInstance(objectId);
player.setName(name);
return player;
}
/**
* Gets the account name.
*
* @return the account name
*/
public String getAccountName()
{
if(getClient()!=null)
return getClient().getAccountName();
return _accountName;
}
/**
* Gets the account chars.
*
* @return the account chars
*/
public Map<Integer, String> getAccountChars()
{
return _chars;
}
/**
* Gets the relation.
*
* @param target the target
* @return the relation
*/
public int getRelation(L2PcInstance target)
{
int result = 0;
// karma and pvp may not be required
if(getPvpFlag() != 0)
{
result |= RelationChanged.RELATION_PVP_FLAG;
}
if(getKarma() > 0)
{
result |= RelationChanged.RELATION_HAS_KARMA;
}
if(isClanLeader())
{
result |= RelationChanged.RELATION_LEADER;
}
if(getSiegeState() != 0)
{
result |= RelationChanged.RELATION_INSIEGE;
if(getSiegeState() != target.getSiegeState())
{
result |= RelationChanged.RELATION_ENEMY;
}
else
{
result |= RelationChanged.RELATION_ALLY;
}
if(getSiegeState() == 1)
{
result |= RelationChanged.RELATION_ATTACKER;
}
}
if(getClan() != null && target.getClan() != null)
{
if(target.getPledgeType() != L2Clan.SUBUNIT_ACADEMY && getPledgeType() != L2Clan.SUBUNIT_ACADEMY && target.getClan().isAtWarWith(getClan().getClanId()))
{
result |= RelationChanged.RELATION_1SIDED_WAR;
if(getClan().isAtWarWith(target.getClan().getClanId()))
{
result |= RelationChanged.RELATION_MUTUAL_WAR;
}
}
}
return result;
}
/**
* Retrieve a L2PcInstance from the characters table of the database and add it in _allObjects of the L2world (call
* restore method).<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Retrieve the L2PcInstance from the characters table of the database</li> <li>Add the L2PcInstance object in
* _allObjects</li> <li>Set the x,y,z position of the L2PcInstance and make it invisible</li> <li>Update the
* overloaded status of the L2PcInstance</li><BR>
* <BR>
*
* @param objectId Identifier of the object to initialized
* @return The L2PcInstance loaded from the database
*/
public static L2PcInstance load(int objectId)
{
return restore(objectId);
}
/**
* Inits the pc status update values.
*/
private void initPcStatusUpdateValues()
{
_cpUpdateInterval = getMaxCp() / 352.0;
_cpUpdateIncCheck = getMaxCp();
_cpUpdateDecCheck = getMaxCp() - _cpUpdateInterval;
_mpUpdateInterval = getMaxMp() / 352.0;
_mpUpdateIncCheck = getMaxMp();
_mpUpdateDecCheck = getMaxMp() - _mpUpdateInterval;
}
/**
* Constructor of L2PcInstance (use L2Character constructor).<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Call the L2Character constructor to create an empty _skills slot and copy basic Calculator set to this
* L2PcInstance</li> <li>Set the name of the L2PcInstance</li><BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : This method SET the level of the L2PcInstance to 1</B></FONT><BR>
* <BR>
*
* @param objectId Identifier of the object to initialized
* @param template The L2PcTemplate to apply to the L2PcInstance
* @param accountName The name of the account including this L2PcInstance
* @param app the app
*/
private L2PcInstance(int objectId, L2PcTemplate template, String accountName, PcAppearance app)
{
super(objectId, template);
getKnownList(); // init knownlist
getStat(); // init stats
getStatus(); // init status
super.initCharStatusUpdateValues();
initPcStatusUpdateValues();
_accountName = accountName;
_appearance = app;
// Create an AI
_ai = new L2PlayerAI(new L2PcInstance.AIAccessor());
// Create a L2Radar object
_radar = new L2Radar(this);
// Retrieve from the database all skills of this L2PcInstance and add them to _skills
// Retrieve from the database all items of this L2PcInstance and add them to _inventory
getInventory().restore();
if(!Config.WAREHOUSE_CACHE)
{
getWarehouse();
}
getFreight().restore();
_instanceLoginTime = System.currentTimeMillis();
}
/**
* Instantiates a new l2 pc instance.
*
* @param objectId the object id
*/
private L2PcInstance(int objectId)
{
super(objectId, null);
getKnownList(); // init knownlist
getStat(); // init stats
getStatus(); // init status
super.initCharStatusUpdateValues();
initPcStatusUpdateValues();
_instanceLoginTime = System.currentTimeMillis();
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.actor.instance.L2PlayableInstance#getKnownList()
*/
@Override
public final PcKnownList getKnownList()
{
if(super.getKnownList() == null || !(super.getKnownList() instanceof PcKnownList))
{
setKnownList(new PcKnownList(this));
}
return (PcKnownList) super.getKnownList();
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.actor.instance.L2PlayableInstance#getStat()
*/
@Override
public final PcStat getStat()
{
if(super.getStat() == null || !(super.getStat() instanceof PcStat))
{
setStat(new PcStat(this));
}
return (PcStat) super.getStat();
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.actor.instance.L2PlayableInstance#getStatus()
*/
@Override
public final PcStatus getStatus()
{
if(super.getStatus() == null || !(super.getStatus() instanceof PcStatus))
{
setStatus(new PcStatus(this));
}
return (PcStatus) super.getStatus();
}
/**
* Gets the appearance.
*
* @return the appearance
*/
public final PcAppearance getAppearance()
{
return _appearance;
}
/**
* Return the base L2PcTemplate link to the L2PcInstance.<BR>
* <BR>
*
* @return the base template
*/
public final L2PcTemplate getBaseTemplate()
{
return CharTemplateTable.getInstance().getTemplate(_baseClass);
}
/**
* Return the L2PcTemplate link to the L2PcInstance.
*
* @return the template
*/
@Override
public final L2PcTemplate getTemplate()
{
return (L2PcTemplate) super.getTemplate();
}
/**
* Sets the template.
*
* @param newclass the new template
*/
public void setTemplate(ClassId newclass)
{
super.setTemplate(CharTemplateTable.getInstance().getTemplate(newclass));
}
public void setTimerToAttack (long time)
{
timerToAttack = time;
}
public long getTimerToAttack ()
{
return timerToAttack;
}
/**
* Return the AI of the L2PcInstance (create it if necessary).<BR>
* <BR>
*
* @return the aI
*/
@Override
public L2CharacterAI getAI()
{
if(_ai == null)
{
synchronized (this)
{
if(_ai == null)
{
_ai = new L2PlayerAI(new L2PcInstance.AIAccessor());
}
}
}
return _ai;
}
/**
* Calculate a destination to explore the area and set the AI Intension to AI_INTENTION_MOVE_TO.<BR>
* <BR>
*
* @return the level
*//* TODO
public void explore()
{
if(!_exploring)
return;
if(getMountType() == 2)
return;
// Calculate the destination point (random)
int x = getX() + Rnd.nextInt(6000) - 3000;
int y = getY() + Rnd.nextInt(6000) - 3000;
if(x > Universe.MAX_X)
{
x = Universe.MAX_X;
}
if(x < Universe.MIN_X)
{
x = Universe.MIN_X;
}
if(y > Universe.MAX_Y)
{
y = Universe.MAX_Y;
}
if(y < Universe.MIN_Y)
{
y = Universe.MIN_Y;
}
int z = getZ();
L2CharPosition pos = new L2CharPosition(x, y, z, 0);
// Set the AI Intention to AI_INTENTION_MOVE_TO
getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, pos);
pos = null;
}*/
/** Return the Level of the L2PcInstance. */
@Override
public final int getLevel()
{
int level = getStat().getLevel();
if(level == -1){
L2PcInstance local_char = restore(this.getObjectId());
if(local_char!=null)
level = local_char.getLevel();
}
if(level<0)
level = 1;
return level;
}
/**
* Return the _newbie state of the L2PcInstance.<BR>
* <BR>
*
* @return true, if is newbie
*/
public boolean isNewbie()
{
return _newbie;
}
/**
* Set the _newbie state of the L2PcInstance.<BR>
* <BR>
*
* @param isNewbie The Identifier of the _newbie state<BR>
* <BR>
*/
public void setNewbie(boolean isNewbie)
{
_newbie = isNewbie;
}
public void setInLMS(boolean b)
{
_inLMS = b;
}
public boolean isInLMS()
{
return _inLMS;
}
public void setInKamaloka(boolean b)
{
inKamalokaEvent = b;
}
public boolean isInKamaloka()
{
return inKamalokaEvent;
}
/**
* Sets the base class.
*
* @param baseClass the new base class
*/
public void setBaseClass(int baseClass)
{
_baseClass = baseClass;
}
/**
* Sets the base class.
*
* @param classId the new base class
*/
public void setBaseClass(ClassId classId)
{
_baseClass = classId.ordinal();
}
/**
* Checks if is in store mode.
*
* @return true, if is in store mode
*/
public boolean isInStoreMode()
{
return getPrivateStoreType() > 0;
}
@Override
public boolean isInRaidEvent()
{
return ((Raid._started && _inEventRaid) || (Raid._sitForced && _inEventRaid) && !isGM());
}
// public boolean isInCraftMode() { return (getPrivateStoreType() == STORE_PRIVATE_MANUFACTURE); }
/**
* Checks if is in craft mode.
*
* @return true, if is in craft mode
*/
public boolean isInCraftMode()
{
return _inCraftMode;
}
/**
* Checks if is in craft mode.
*
* @param b the b
*/
public void isInCraftMode(boolean b)
{
_inCraftMode = b;
}
/** The _kicked. */
private boolean _kicked = false;
/**
* Manage Logout Task.<BR>
* <BR>
*
* @param kicked the kicked
*/
public void logout(boolean kicked)
{
// prevent from player disconnect when in Event
if(atEvent)
{
sendMessage("A superior power doesn't allow you to leave the event.");
sendPacket(ActionFailed.STATIC_PACKET);
}
if (isInLMS())
{
sendMessage("A superior power doesn't allow you to leave the event.");
sendPacket(ActionFailed.STATIC_PACKET);
}
_kicked = kicked;
closeNetConnection();
}
/**
* Checks if is kicked.
*
* @return true, if is kicked
*/
public boolean isKicked(){
return _kicked;
}
/**
* Sets the kicked.
*
* @param value the new kicked
*/
public void setKicked(boolean value){
_kicked = value;
}
/**
* Manage Logout Task.<BR>
* <BR>
*/
public void logout()
{
logout(false);
/*
if(_active_boxes!=-1){ //normal logout
this.decreaseBoxes();
}
*/
/*
_active_boxes = _active_boxes-1;
if(getClient()!=null && !getClient().getConnection().isClosed()){
String thisip = getClient().getConnection().getSocketChannel().socket().getInetAddress().getHostAddress();
Collection<L2PcInstance> allPlayers = L2World.getInstance().getAllPlayers();
L2PcInstance[] players = allPlayers.toArray(new L2PcInstance[allPlayers.size()]);
for(L2PcInstance player : players)
{
if(player != null)
{
if(player.getClient()!=null && !player.getClient().getConnection().isClosed()){
String ip = player.getClient().getConnection().getSocketChannel().socket().getInetAddress().getHostAddress();
if(thisip.equals(ip) && this != player && player != null)
{
player._active_boxes = _active_boxes;
}
}
}
}
}
*/
}
/**
* Return a table containing all Common L2RecipeList of the L2PcInstance.<BR>
* <BR>
*
* @return the common recipe book
*/
public L2RecipeList[] getCommonRecipeBook()
{
return _commonRecipeBook.values().toArray(new L2RecipeList[_commonRecipeBook.values().size()]);
}
/**
* Return a table containing all Dwarf L2RecipeList of the L2PcInstance.<BR>
* <BR>
*
* @return the dwarven recipe book
*/
public L2RecipeList[] getDwarvenRecipeBook()
{
return _dwarvenRecipeBook.values().toArray(new L2RecipeList[_dwarvenRecipeBook.values().size()]);
}
/**
* Add a new L2RecipList to the table _commonrecipebook containing all L2RecipeList of the L2PcInstance <BR>
* <BR>.
*
* @param recipe The L2RecipeList to add to the _recipebook
*/
public void registerCommonRecipeList(L2RecipeList recipe)
{
_commonRecipeBook.put(recipe.getId(), recipe);
}
/**
* Add a new L2RecipList to the table _recipebook containing all L2RecipeList of the L2PcInstance <BR>
* <BR>.
*
* @param recipe The L2RecipeList to add to the _recipebook
*/
public void registerDwarvenRecipeList(L2RecipeList recipe)
{
_dwarvenRecipeBook.put(recipe.getId(), recipe);
}
/**
* Checks for recipe list.
*
* @param recipeId the recipe id
* @return <b>TRUE</b> if player has the recipe on Common or Dwarven Recipe book else returns <b>FALSE</b>
*/
public boolean hasRecipeList(int recipeId)
{
if(_dwarvenRecipeBook.containsKey(recipeId))
return true;
else if(_commonRecipeBook.containsKey(recipeId))
return true;
else
return false;
}
/**
* Tries to remove a L2RecipList from the table _DwarvenRecipeBook or from table _CommonRecipeBook, those table
* contain all L2RecipeList of the L2PcInstance <BR>
* <BR>.
*
* @param recipeId the recipe id
*/
public void unregisterRecipeList(int recipeId)
{
if(_dwarvenRecipeBook.containsKey(recipeId))
{
_dwarvenRecipeBook.remove(recipeId);
}
else if(_commonRecipeBook.containsKey(recipeId))
{
_commonRecipeBook.remove(recipeId);
}
else
{
_log.warning("Attempted to remove unknown RecipeList: " + recipeId);
}
L2ShortCut[] allShortCuts = getAllShortCuts();
for(L2ShortCut sc : allShortCuts)
{
if(sc != null && sc.getId() == recipeId && sc.getType() == L2ShortCut.TYPE_RECIPE)
{
deleteShortCut(sc.getSlot(), sc.getPage());
}
}
allShortCuts = null;
}
/**
* Returns the Id for the last talked quest NPC.<BR>
* <BR>
*
* @return the last quest npc object
*/
public int getLastQuestNpcObject()
{
return _questNpcObject;
}
/**
* Sets the last quest npc object.
*
* @param npcId the new last quest npc object
*/
public void setLastQuestNpcObject(int npcId)
{
_questNpcObject = npcId;
}
/**
* Return the QuestState object corresponding to the quest name.<BR>
* <BR>
*
* @param quest The name of the quest
* @return the quest state
*/
public QuestState getQuestState(String quest)
{
return _quests.get(quest);
}
/**
* Add a QuestState to the table _quest containing all quests began by the L2PcInstance.<BR>
* <BR>
*
* @param qs The QuestState to add to _quest
*/
public void setQuestState(QuestState qs)
{
_quests.put(qs.getQuestName(), qs);
}
/**
* Remove a QuestState from the table _quest containing all quests began by the L2PcInstance.<BR>
* <BR>
*
* @param quest The name of the quest
*/
public void delQuestState(String quest)
{
_quests.remove(quest);
}
/**
* Adds the to quest state array.
*
* @param questStateArray the quest state array
* @param state the state
* @return the quest state[]
*/
private QuestState[] addToQuestStateArray(QuestState[] questStateArray, QuestState state)
{
int len = questStateArray.length;
QuestState[] tmp = new QuestState[len + 1];
for(int i = 0; i < len; i++)
{
tmp[i] = questStateArray[i];
}
tmp[len] = state;
return tmp;
}
/**
* Return a table containing all Quest in progress from the table _quests.<BR>
* <BR>
*
* @return the all active quests
*/
public Quest[] getAllActiveQuests()
{
FastList<Quest> quests = new FastList<Quest>();
for(QuestState qs : _quests.values())
{
if(qs != null)
{
if(qs.getQuest().getQuestIntId() >= 1999)
{
continue;
}
if(qs.isCompleted() && !Config.DEVELOPER)
{
continue;
}
if(!qs.isStarted() && !Config.DEVELOPER)
{
continue;
}
quests.add(qs.getQuest());
}
}
return quests.toArray(new Quest[quests.size()]);
}
/**
* Return a table containing all QuestState to modify after a L2Attackable killing.<BR>
* <BR>
*
* @param npc the npc
* @return the quests for attacks
*/
public QuestState[] getQuestsForAttacks(L2NpcInstance npc)
{
// Create a QuestState table that will contain all QuestState to modify
QuestState[] states = null;
// Go through the QuestState of the L2PcInstance quests
for(Quest quest : npc.getTemplate().getEventQuests(Quest.QuestEventType.ON_ATTACK))
{
// Check if the Identifier of the L2Attackable attck is needed for the current quest
if(getQuestState(quest.getName()) != null)
{
// Copy the current L2PcInstance QuestState in the QuestState table
if(states == null)
{
states = new QuestState[]
{
getQuestState(quest.getName())
};
}
else
{
states = addToQuestStateArray(states, getQuestState(quest.getName()));
}
}
}
// Return a table containing all QuestState to modify
return states;
}
/**
* Return a table containing all QuestState to modify after a L2Attackable killing.<BR>
* <BR>
*
* @param npc the npc
* @return the quests for kills
*/
public QuestState[] getQuestsForKills(L2NpcInstance npc)
{
// Create a QuestState table that will contain all QuestState to modify
QuestState[] states = null;
// Go through the QuestState of the L2PcInstance quests
for(Quest quest : npc.getTemplate().getEventQuests(Quest.QuestEventType.ON_KILL))
{
// Check if the Identifier of the L2Attackable killed is needed for the current quest
if(getQuestState(quest.getName()) != null)
{
// Copy the current L2PcInstance QuestState in the QuestState table
if(states == null)
{
states = new QuestState[]
{
getQuestState(quest.getName())
};
}
else
{
states = addToQuestStateArray(states, getQuestState(quest.getName()));
}
}
}
// Return a table containing all QuestState to modify
return states;
}
/**
* Return a table containing all QuestState from the table _quests in which the L2PcInstance must talk to the NPC.<BR>
* <BR>
*
* @param npcId The Identifier of the NPC
* @return the quests for talk
*/
public QuestState[] getQuestsForTalk(int npcId)
{
// Create a QuestState table that will contain all QuestState to modify
QuestState[] states = null;
// Go through the QuestState of the L2PcInstance quests
for(Quest quest : NpcTable.getInstance().getTemplate(npcId).getEventQuests(Quest.QuestEventType.QUEST_TALK))
{
if(quest != null)
{
// Copy the current L2PcInstance QuestState in the QuestState table
if(getQuestState(quest.getName()) != null)
{
if(states == null)
{
states = new QuestState[]
{
getQuestState(quest.getName())
};
}
else
{
states = addToQuestStateArray(states, getQuestState(quest.getName()));
}
}
}
}
// Return a table containing all QuestState to modify
return states;
}
/**
* Process quest event.
*
* @param quest the quest
* @param event the event
* @return the quest state
*/
public QuestState processQuestEvent(String quest, String event)
{
QuestState retval = null;
if(event == null)
{
event = "";
}
if(!_quests.containsKey(quest))
return retval;
QuestState qs = getQuestState(quest);
if(qs == null && event.length() == 0)
return retval;
if(qs == null)
{
Quest q = null;
if(!Config.ALT_DEV_NO_QUESTS)
q = QuestManager.getInstance().getQuest(quest);
if(q == null)
return retval;
qs = q.newQuestState(this);
}
if(qs != null)
{
if(getLastQuestNpcObject() > 0)
{
L2Object object = L2World.getInstance().findObject(getLastQuestNpcObject());
if(object instanceof L2NpcInstance && isInsideRadius(object, L2NpcInstance.INTERACTION_DISTANCE, false, false))
{
L2NpcInstance npc = (L2NpcInstance) object;
QuestState[] states = getQuestsForTalk(npc.getNpcId());
if(states != null)
{
for(QuestState state : states)
{
if(state.getQuest().getQuestIntId() == qs.getQuest().getQuestIntId() && !qs.isCompleted())
{
if(qs.getQuest().notifyEvent(event, npc, this))
{
showQuestWindow(quest, qs.getStateId());
}
retval = qs;
}
}
sendPacket(new QuestList());
}
}
}
qs = null;
}
return retval;
}
/**
* Show quest window.
*
* @param questId the quest id
* @param stateId the state id
*/
private void showQuestWindow(String questId, String stateId)
{
String path = "data/scripts/quests/" + questId + "/" + stateId + ".htm";
String content = HtmCache.getInstance().getHtm(path);
if(content != null)
{
if(Config.DEBUG)
{
_log.fine("Showing quest window for quest " + questId + " state " + stateId + " html path: " + path);
}
NpcHtmlMessage npcReply = new NpcHtmlMessage(5);
npcReply.setHtml(content);
sendPacket(npcReply);
content = null;
npcReply = null;
}
sendPacket(ActionFailed.STATIC_PACKET);
path = null;
}
/**
* Return a table containing all L2ShortCut of the L2PcInstance.<BR>
* <BR>
*
* @return the all short cuts
*/
public L2ShortCut[] getAllShortCuts()
{
return _shortCuts.getAllShortCuts();
}
/**
* Return the L2ShortCut of the L2PcInstance corresponding to the position (page-slot).<BR>
* <BR>
*
* @param slot The slot in wich the shortCuts is equiped
* @param page The page of shortCuts containing the slot
* @return the short cut
*/
public L2ShortCut getShortCut(int slot, int page)
{
return _shortCuts.getShortCut(slot, page);
}
/**
* Add a L2shortCut to the L2PcInstance _shortCuts<BR>
* <BR>.
*
* @param shortcut the shortcut
*/
public void registerShortCut(L2ShortCut shortcut)
{
_shortCuts.registerShortCut(shortcut);
}
/**
* Delete the L2ShortCut corresponding to the position (page-slot) from the L2PcInstance _shortCuts.<BR>
* <BR>
*
* @param slot the slot
* @param page the page
*/
public void deleteShortCut(int slot, int page)
{
_shortCuts.deleteShortCut(slot, page);
}
/**
* Add a L2Macro to the L2PcInstance _macroses<BR>
* <BR>.
*
* @param macro the macro
*/
public void registerMacro(L2Macro macro)
{
_macroses.registerMacro(macro);
}
/**
* Delete the L2Macro corresponding to the Identifier from the L2PcInstance _macroses.<BR>
* <BR>
*
* @param id the id
*/
public void deleteMacro(int id)
{
_macroses.deleteMacro(id);
}
/**
* Return all L2Macro of the L2PcInstance.<BR>
* <BR>
*
* @return the macroses
*/
public MacroList getMacroses()
{
return _macroses;
}
/**
* Set the siege state of the L2PcInstance.<BR>
* <BR>
* 1 = attacker, 2 = defender, 0 = not involved
*
* @param siegeState the new siege state
*/
public void setSiegeState(byte siegeState)
{
_siegeState = siegeState;
}
/**
* Get the siege state of the L2PcInstance.<BR>
* <BR>
* 1 = attacker, 2 = defender, 0 = not involved
*
* @return the siege state
*/
public byte getSiegeState()
{
return _siegeState;
}
/**
* Set the PvP Flag of the L2PcInstance.<BR>
* <BR>
*
* @param pvpFlag the new pvp flag
*/
public void setPvpFlag(int pvpFlag)
{
_pvpFlag = (byte) pvpFlag;
}
/**
* Gets the pvp flag.
*
* @return the pvp flag
*/
public byte getPvpFlag()
{
return _pvpFlag;
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character#updatePvPFlag(int)
*/
@Override
public void updatePvPFlag(int value)
{
if(getPvpFlag() == value)
return;
setPvpFlag(value);
sendPacket(new UserInfo(this));
// If this player has a pet update the pets pvp flag as well
if(getPet() != null)
{
sendPacket(new RelationChanged(getPet(), getRelation(this), false));
}
for(L2PcInstance target : getKnownList().getKnownPlayers().values())
{
if(target==null)
continue;
target.sendPacket(new RelationChanged(this, getRelation(this), isAutoAttackable(target)));
if(getPet() != null)
{
target.sendPacket(new RelationChanged(getPet(), getRelation(this), isAutoAttackable(target)));
}
}
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character#revalidateZone(boolean)
*/
@Override
public void revalidateZone(boolean force)
{
// Cannot validate if not in a world region (happens during teleport)
if(getWorldRegion() == null)
return;
if (Config.ALLOW_WATER)
checkWaterState();
// This function is called very often from movement code
if(force)
{
_zoneValidateCounter = 4;
}
else
{
_zoneValidateCounter--;
if(_zoneValidateCounter < 0)
{
_zoneValidateCounter = 4;
}
else
return;
}
getWorldRegion().revalidateZones(this);
if(isInsideZone(ZONE_SIEGE))
{
if(_lastCompassZone == ExSetCompassZoneCode.SIEGEWARZONE2)
return;
_lastCompassZone = ExSetCompassZoneCode.SIEGEWARZONE2;
ExSetCompassZoneCode cz = new ExSetCompassZoneCode(ExSetCompassZoneCode.SIEGEWARZONE2);
sendPacket(cz);
cz = null;
}
else if(isInsideZone(ZONE_PVP))
{
if(_lastCompassZone == ExSetCompassZoneCode.PVPZONE)
return;
_lastCompassZone = ExSetCompassZoneCode.PVPZONE;
ExSetCompassZoneCode cz = new ExSetCompassZoneCode(ExSetCompassZoneCode.PVPZONE);
sendPacket(cz);
cz = null;
}
else if(isInsideZone(ZONE_EVENT))
{
if(_lastCompassZone == ExSetCompassZoneCode.EVENTZONE)
return;
_lastCompassZone = ExSetCompassZoneCode.EVENTZONE;
ExSetCompassZoneCode cz = new ExSetCompassZoneCode(ExSetCompassZoneCode.EVENTZONE);
sendPacket(cz);
cz = null;
}
else if(isIn7sDungeon())
{
if(_lastCompassZone == ExSetCompassZoneCode.SEVENSIGNSZONE)
return;
_lastCompassZone = ExSetCompassZoneCode.SEVENSIGNSZONE;
ExSetCompassZoneCode cz = new ExSetCompassZoneCode(ExSetCompassZoneCode.SEVENSIGNSZONE);
sendPacket(cz);
cz = null;
}
else if(isInsideZone(ZONE_PEACE))
{
if(_lastCompassZone == ExSetCompassZoneCode.PEACEZONE)
return;
_lastCompassZone = ExSetCompassZoneCode.PEACEZONE;
ExSetCompassZoneCode cz = new ExSetCompassZoneCode(ExSetCompassZoneCode.PEACEZONE);
sendPacket(cz);
cz = null;
}
else if(isInsideZone(ZONE_CHAOTIC)){
if(_lastCompassZone == ExSetCompassZoneCode.CHAOTICZONE)
return;
_lastCompassZone = ExSetCompassZoneCode.CHAOTICZONE;
ExSetCompassZoneCode cz = new ExSetCompassZoneCode(ExSetCompassZoneCode.CHAOTICZONE);
sendPacket(cz);
cz = null;
}
else
{
if(_lastCompassZone == ExSetCompassZoneCode.GENERALZONE)
return;
if(_lastCompassZone == ExSetCompassZoneCode.SIEGEWARZONE2)
{
updatePvPStatus();
}
_lastCompassZone = ExSetCompassZoneCode.GENERALZONE;
ExSetCompassZoneCode cz = new ExSetCompassZoneCode(ExSetCompassZoneCode.GENERALZONE);
sendPacket(cz);
cz = null;
}
}
/**
* Return True if the L2PcInstance can Craft Dwarven Recipes.<BR>
* <BR>
*
* @return true, if successful
*/
public boolean hasDwarvenCraft()
{
return getSkillLevel(L2Skill.SKILL_CREATE_DWARVEN) >= 1;
}
/**
* Gets the dwarven craft.
*
* @return the dwarven craft
*/
public int getDwarvenCraft()
{
return getSkillLevel(L2Skill.SKILL_CREATE_DWARVEN);
}
/**
* Return True if the L2PcInstance can Craft Dwarven Recipes.<BR>
* <BR>
*
* @return true, if successful
*/
public boolean hasCommonCraft()
{
return getSkillLevel(L2Skill.SKILL_CREATE_COMMON) >= 1;
}
/**
* Gets the common craft.
*
* @return the common craft
*/
public int getCommonCraft()
{
return getSkillLevel(L2Skill.SKILL_CREATE_COMMON);
}
/**
* Return the PK counter of the L2PcInstance.<BR>
* <BR>
*
* @return the pk kills
*/
public int getPkKills()
{
return _pkKills;
}
/**
* Set the PK counter of the L2PcInstance.<BR>
* <BR>
*
* @param pkKills the new pk kills
*/
public void setPkKills(int pkKills)
{
_pkKills = pkKills;
}
/**
* Return the _deleteTimer of the L2PcInstance.<BR>
* <BR>
*
* @return the delete timer
*/
public long getDeleteTimer()
{
return _deleteTimer;
}
/**
* Set the _deleteTimer of the L2PcInstance.<BR>
* <BR>
*
* @param deleteTimer the new delete timer
*/
public void setDeleteTimer(long deleteTimer)
{
_deleteTimer = deleteTimer;
}
/**
* Return the current weight of the L2PcInstance.<BR>
* <BR>
*
* @return the current load
*/
public int getCurrentLoad()
{
return _inventory.getTotalWeight();
}
/**
* Return date of las update of recomPoints.
*
* @return the last recom update
*/
public long getLastRecomUpdate()
{
return _lastRecomUpdate;
}
/**
* Sets the last recom update.
*
* @param date the new last recom update
*/
public void setLastRecomUpdate(long date)
{
_lastRecomUpdate = date;
}
/**
* Return the number of recommandation obtained by the L2PcInstance.<BR>
* <BR>
*
* @return the recom have
*/
public int getRecomHave()
{
return _recomHave;
}
/**
* Increment the number of recommandation obtained by the L2PcInstance (Max : 255).<BR>
* <BR>
*/
protected void incRecomHave()
{
if(_recomHave < 255)
{
_recomHave++;
}
}
/**
* Set the number of recommandation obtained by the L2PcInstance (Max : 255).<BR>
* <BR>
*
* @param value the new recom have
*/
public void setRecomHave(int value)
{
if(value > 255)
{
_recomHave = 255;
}
else if(value < 0)
{
_recomHave = 0;
}
else
{
_recomHave = value;
}
}
/**
* Return the number of recommandation that the L2PcInstance can give.<BR>
* <BR>
*
* @return the recom left
*/
public int getRecomLeft()
{
return _recomLeft;
}
/**
* Increment the number of recommandation that the L2PcInstance can give.<BR>
* <BR>
*/
protected void decRecomLeft()
{
if(_recomLeft > 0)
{
_recomLeft--;
}
}
/**
* Give recom.
*
* @param target the target
*/
public void giveRecom(L2PcInstance target)
{
if(Config.ALT_RECOMMEND)
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement(ADD_CHAR_RECOM);
statement.setInt(1, getObjectId());
statement.setInt(2, target.getObjectId());
statement.execute();
statement.close();
statement = null;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("could not update char recommendations:" + e);
}
finally
{
CloseUtil.close(con);
con = null;
}
}
target.incRecomHave();
decRecomLeft();
_recomChars.add(target.getObjectId());
}
/**
* Can recom.
*
* @param target the target
* @return true, if successful
*/
public boolean canRecom(L2PcInstance target)
{
return !_recomChars.contains(target.getObjectId());
}
/**
* Set the exp of the L2PcInstance before a death.
*
* @param exp the new exp before death
*/
public void setExpBeforeDeath(long exp)
{
_expBeforeDeath = exp;
}
/**
* Gets the exp before death.
*
* @return the exp before death
*/
public long getExpBeforeDeath()
{
return _expBeforeDeath;
}
/**
* Return the Karma of the L2PcInstance.<BR>
* <BR>
*
* @return the karma
*/
public int getKarma()
{
return _karma;
}
/**
* Set the Karma of the L2PcInstance and send a Server->Client packet StatusUpdate (broadcast).<BR>
* <BR>
*
* @param karma the new karma
*/
public void setKarma(int karma)
{
if(karma < 0)
{
karma = 0;
}
if(_karma == 0 && karma > 0)
{
for(L2Object object : getKnownList().getKnownObjects().values())
{
if(object == null || !(object instanceof L2GuardInstance))
{
continue;
}
if(((L2GuardInstance) object).getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)
{
((L2GuardInstance) object).getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE, null);
}
}
}
else if(_karma > 0 && karma == 0)
{
// Send a Server->Client StatusUpdate packet with Karma and PvP Flag to the L2PcInstance and all L2PcInstance to inform (broadcast)
setKarmaFlag(0);
}
_karma = karma;
broadcastKarma();
}
/**
* Return the max weight that the L2PcInstance can load.<BR>
* <BR>
*
* @return the max load
*/
public int getMaxLoad()
{
int con = getCON();
if (con < 1)
return 31000;
if (con > 59)
return 176000;
double baseLoad = Math.floor(BaseStats.CON.calcBonus(this) * 69000 * Config.ALT_WEIGHT_LIMIT);
return (int) calcStat(Stats.MAX_LOAD, baseLoad, this, null);
}
/**
* Gets the expertise penalty.
*
* @return the expertise penalty
*/
public int getExpertisePenalty()
{
return _expertisePenalty;
}
/**
* Gets the mastery penalty.
*
* @return the mastery penalty
*/
public int getMasteryPenalty()
{
return _masteryPenalty;
}
/**
* Gets the mastery weap penalty.
*
* @return the mastery weap penalty
*/
public int getMasteryWeapPenalty()
{
return _masteryWeapPenalty;
}
/**
* Gets the weight penalty.
*
* @return the weight penalty
*/
public int getWeightPenalty()
{
if(_dietMode)
return 0;
return _curWeightPenalty;
}
/**
* Update the overloaded status of the L2PcInstance.<BR>
* <BR>
*/
public void refreshOverloaded()
{
if(Config.DISABLE_WEIGHT_PENALTY)
{
setIsOverloaded(false);
}
else if(_dietMode)
{
setIsOverloaded(false);
_curWeightPenalty = 0;
super.removeSkill(getKnownSkill(4270));
sendPacket(new EtcStatusUpdate(this));
Broadcast.toKnownPlayers(this, new CharInfo(this));
}
else
{
int maxLoad = getMaxLoad();
if(maxLoad > 0)
{
//setIsOverloaded(getCurrentLoad() > maxLoad);
//int weightproc = getCurrentLoad() * 1000 / maxLoad;
long weightproc = (long) ((getCurrentLoad() - calcStat(Stats.WEIGHT_PENALTY, 1, this, null)) * 1000 / maxLoad);
int newWeightPenalty;
if(weightproc < 500)
{
newWeightPenalty = 0;
}
else if(weightproc < 666)
{
newWeightPenalty = 1;
}
else if(weightproc < 800)
{
newWeightPenalty = 2;
}
else if(weightproc < 1000)
{
newWeightPenalty = 3;
}
else
{
newWeightPenalty = 4;
}
if(_curWeightPenalty != newWeightPenalty)
{
_curWeightPenalty = newWeightPenalty;
if(newWeightPenalty > 0)
{
super.addSkill(SkillTable.getInstance().getInfo(4270, newWeightPenalty));
sendSkillList(); // Fix visual bug
}
else
{
super.removeSkill(getKnownSkill(4270));
sendSkillList(); // Fix visual bug
}
sendPacket(new EtcStatusUpdate(this));
Broadcast.toKnownPlayers(this, new CharInfo(this));
}
}
}
sendPacket(new UserInfo(this));
}
/**
* Refresh mastery penality.
*/
public void refreshMasteryPenality()
{
if (!Config.MASTERY_PENALTY || this.getLevel() <= Config.LEVEL_TO_GET_PENALITY)
return;
_heavy_mastery = false;
_light_mastery = false;
_robe_mastery = false;
L2Skill[] char_skills = this.getAllSkills();
for (L2Skill actual_skill : char_skills)
{
if (actual_skill.getName().contains("Heavy Armor Mastery"))
{
_heavy_mastery = true;
}
if (actual_skill.getName().contains("Light Armor Mastery"))
{
_light_mastery = true;
}
if (actual_skill.getName().contains("Robe Mastery"))
{
_robe_mastery = true;
}
}
int newMasteryPenalty = 0;
if (!_heavy_mastery && !_light_mastery && !_robe_mastery)
{
// not completed 1st class transfer or not acquired yet the mastery skills
newMasteryPenalty = 0;
}
else
{
for (L2ItemInstance item : getInventory().getItems())
{
if (item != null && item.isEquipped() && item.getItem() instanceof L2Armor)
{
// No penality for formal wear
if (item.getItemId() == 6408)
continue;
L2Armor armor_item = (L2Armor) item.getItem();
switch (armor_item.getItemType())
{
case HEAVY:
{
if (!_heavy_mastery)
newMasteryPenalty++;
}
break;
case LIGHT:
{
if (!_light_mastery)
newMasteryPenalty++;
}
break;
case MAGIC:
{
if (!_robe_mastery)
newMasteryPenalty++;
}
break;
}
}
}
}
if (_masteryPenalty != newMasteryPenalty)
{
int penalties = _masteryWeapPenalty + _expertisePenalty + newMasteryPenalty;
if (penalties > 0)
{
super.addSkill(SkillTable.getInstance().getInfo(4267, 1)); // level used to be newPenalty
}
else
{
super.removeSkill(getKnownSkill(4267));
}
sendPacket(new EtcStatusUpdate(this));
_masteryPenalty = newMasteryPenalty;
}
}
/**
* Can interact.
*
* @param player the player
* @return true, if successful
*/
protected boolean canInteract(L2PcInstance player)
{
if(!isInsideRadius(player, 50, false, false))
return false;
return true;
}
/** The _blunt_mastery. */
private boolean _blunt_mastery = false;
/** The _pole_mastery. */
private boolean _pole_mastery = false;
/** The _dagger_mastery. */
private boolean _dagger_mastery = false;
/** The _sword_mastery. */
private boolean _sword_mastery = false;
/** The _bow_mastery. */
private boolean _bow_mastery = false;
/** The _fist_mastery. */
private boolean _fist_mastery = false;
/** The _dual_mastery. */
private boolean _dual_mastery = false;
/** The _2hands_mastery. */
private boolean _2hands_mastery = false;
/** The _mastery weap penalty. */
private int _masteryWeapPenalty = 0;
/**
* Refresh mastery weap penality.
*/
public void refreshMasteryWeapPenality()
{
if (!Config.MASTERY_WEAPON_PENALTY || this.getLevel() <= Config.LEVEL_TO_GET_WEAPON_PENALITY)
return;
_blunt_mastery = false;
_bow_mastery = false;
_dagger_mastery = false;
_fist_mastery = false;
_dual_mastery = false;
_pole_mastery = false;
_sword_mastery = false;
_2hands_mastery = false;
L2Skill[] char_skills = this.getAllSkills();
for (L2Skill actual_skill : char_skills)
{
if (actual_skill.getName().contains("Sword Blunt Mastery"))
{
_sword_mastery = true;
_blunt_mastery = true;
continue;
}
if (actual_skill.getName().contains("Blunt Mastery"))
{
_blunt_mastery = true;
continue;
}
if (actual_skill.getName().contains("Bow Mastery"))
{
_bow_mastery = true;
continue;
}
if (actual_skill.getName().contains("Dagger Mastery"))
{
_dagger_mastery = true;
continue;
}
if (actual_skill.getName().contains("Fist Mastery"))
{
_fist_mastery = true;
continue;
}
if (actual_skill.getName().contains("Dual Weapon Mastery"))
{
_dual_mastery = true;
continue;
}
if (actual_skill.getName().contains("Polearm Mastery"))
{
_pole_mastery = true;
continue;
}
if (actual_skill.getName().contains("Two-handed Weapon Mastery"))
{
_2hands_mastery = true;
continue;
}
}
int newMasteryPenalty = 0;
if (!_bow_mastery && !_blunt_mastery && !_dagger_mastery && !_fist_mastery && !_dual_mastery && !_pole_mastery && !_sword_mastery && !_2hands_mastery)
{ // not completed 1st class transfer or not acquired yet the mastery skills
newMasteryPenalty = 0;
}
else
{
for (L2ItemInstance item : getInventory().getItems())
{
if (item != null && item.isEquipped() && item.getItem() instanceof L2Weapon && !isCursedWeaponEquiped())
{
// No penality for cupid's bow
if (item.isCupidBow())
continue;
L2Weapon weap_item = (L2Weapon) item.getItem();
switch (weap_item.getItemType())
{
case BIGBLUNT:
case BIGSWORD:
{
if (!_2hands_mastery)
newMasteryPenalty++;
}
break;
case BLUNT:
{
if (!_blunt_mastery)
newMasteryPenalty++;
}
break;
case BOW:
{
if (!_bow_mastery)
newMasteryPenalty++;
}
break;
case DAGGER:
{
if (!_dagger_mastery)
newMasteryPenalty++;
}
break;
case DUAL:
{
if (!_dual_mastery)
newMasteryPenalty++;
}
break;
case DUALFIST:
case FIST:
{
if (!_fist_mastery)
newMasteryPenalty++;
}
break;
case POLE:
{
if (!_pole_mastery)
newMasteryPenalty++;
}
break;
case SWORD:
{
if (!_sword_mastery)
newMasteryPenalty++;
}
break;
}
}
}
}
if (_masteryWeapPenalty != newMasteryPenalty)
{
int penalties = _masteryPenalty + _expertisePenalty + newMasteryPenalty;
if (penalties > 0)
{
super.addSkill(SkillTable.getInstance().getInfo(4267, 1)); // level used to be newPenalty
}
else
{
super.removeSkill(getKnownSkill(4267));
}
sendPacket(new EtcStatusUpdate(this));
_masteryWeapPenalty = newMasteryPenalty;
}
}
/**
* Refresh expertise penalty.
*/
public void refreshExpertisePenalty()
{
if (!Config.EXPERTISE_PENALTY)
return;
int newPenalty = 0;
for(L2ItemInstance item : getInventory().getItems())
{
if(item != null && item.isEquipped())
{
int crystaltype = item.getItem().getCrystalType();
if(crystaltype > newPenalty)
{
newPenalty = crystaltype;
}
}
}
newPenalty = newPenalty - getExpertiseIndex();
if(newPenalty <= 0)
{
newPenalty = 0;
}
if(getExpertisePenalty() != newPenalty)
{
int penalties = _masteryPenalty + _masteryWeapPenalty + newPenalty;
_expertisePenalty = newPenalty;
if(penalties > 0)
{
super.addSkill(SkillTable.getInstance().getInfo(4267, 1)); // level used to be newPenalty
sendSkillList(); // Update skill list
}
else
{
super.removeSkill(getKnownSkill(4267));
sendSkillList(); // Update skill list
}
sendPacket(new EtcStatusUpdate(this));
}
}
public void checkIfWeaponIsAllowed()
{
// Override for Gamemasters
if (isGM())
{
return;
}
// Iterate through all effects currently on the character.
for (L2Effect currenteffect : getAllEffects())
{
L2Skill effectSkill = currenteffect.getSkill();
// Ignore all buff skills that are party related (ie. songs, dances) while still remaining weapon dependant on cast though.
if (!effectSkill.isOffensive() && !(effectSkill.getTargetType() == SkillTargetType.TARGET_PARTY && effectSkill.getSkillType() == SkillType.BUFF))
{
// Check to rest to assure current effect meets weapon requirements.
if (!effectSkill.getWeaponDependancy(this))
{
sendMessage(effectSkill.getName() + " cannot be used with this weapon.");
if (Config.DEBUG)
{
_log.info(" | Skill " + effectSkill.getName() + " has been disabled for (" + getName() + "); Reason: Incompatible Weapon Type.");
}
currenteffect.exit();
}
}
continue;
}
}
/**
* Check ss match.
*
* @param equipped the equipped
* @param unequipped the unequipped
*/
public void checkSSMatch(L2ItemInstance equipped, L2ItemInstance unequipped)
{
if(unequipped == null)
return;
if(unequipped.getItem().getType2() == L2Item.TYPE2_WEAPON && (equipped == null ? true : equipped.getItem().getCrystalType() != unequipped.getItem().getCrystalType()))
// && getInventory().getItem() != null - must be fixed.
{
for(L2ItemInstance ss : getInventory().getItems())
{
int _itemId = ss.getItemId();
if((_itemId >= 2509 && _itemId <= 2514 || _itemId >= 3947 && _itemId <= 3952 || _itemId <= 1804 && _itemId >= 1808 || _itemId == 5789 || _itemId == 5790 || _itemId == 1835) && ss.getItem().getCrystalType() == unequipped.getItem().getCrystalType())
{
sendPacket(new ExAutoSoulShot(_itemId, 0));
SystemMessage sm = new SystemMessage(SystemMessageId.AUTO_USE_OF_S1_CANCELLED);
sm.addString(ss.getItemName());
sendPacket(sm);
}
}
}
}
/**
* Return the the PvP Kills of the L2PcInstance (Number of player killed during a PvP).<BR>
* <BR>
*
* @return the pvp kills
*/
public int getPvpKills()
{
return _pvpKills;
}
/**
* Set the the PvP Kills of the L2PcInstance (Number of player killed during a PvP).<BR>
* <BR>
*
* @param pvpKills the new pvp kills
*/
public void setPvpKills(int pvpKills)
{
_pvpKills = pvpKills;
/*// Set hero aura if pvp kills > 100
if (pvpKills > 100)
{
isPermaHero = true;
setHeroAura(true);
}*/
}
/**
* Return the ClassId object of the L2PcInstance contained in L2PcTemplate.<BR>
* <BR>
*
* @return the class id
*/
public ClassId getClassId()
{
return getTemplate().classId;
}
/**
* Set the template of the L2PcInstance.<BR>
* <BR>
*
* @param Id The Identifier of the L2PcTemplate to set to the L2PcInstance
*/
public void setClassId(int Id)
{
if(getLvlJoinedAcademy() != 0 && _clan != null && PlayerClass.values()[Id].getLevel() == ClassLevel.Third)
{
if(getLvlJoinedAcademy() <= 16)
{
_clan.setReputationScore(_clan.getReputationScore() + 400, true);
}
else if(getLvlJoinedAcademy() >= 39)
{
_clan.setReputationScore(_clan.getReputationScore() + 170, true);
}
else
{
_clan.setReputationScore(_clan.getReputationScore() + 400 - (getLvlJoinedAcademy() - 16) * 10, true);
}
_clan.broadcastToOnlineMembers(new PledgeShowInfoUpdate(_clan));
setLvlJoinedAcademy(0);
//oust pledge member from the academy, cuz he has finished his 2nd class transfer
SystemMessage msg = new SystemMessage(SystemMessageId.CLAN_MEMBER_S1_EXPELLED);
msg.addString(getName());
_clan.broadcastToOnlineMembers(msg);
_clan.broadcastToOnlineMembers(new PledgeShowMemberListDelete(getName()));
_clan.removeClanMember(getName(), 0);
sendPacket(new SystemMessage(SystemMessageId.ACADEMY_MEMBERSHIP_TERMINATED));
msg = null;
// receive graduation gift
getInventory().addItem("Gift", 8181, 1, this, null); // give academy circlet
getInventory().updateDatabase(); // update database
}
if(isSubClassActive())
{
getSubClasses().get(_classIndex).setClassId(Id);
}
doCast(SkillTable.getInstance().getInfo(5103, 1));
setClassTemplate(Id);
}
/**
* Return the Experience of the L2PcInstance.
*
* @return the exp
*/
public long getExp()
{
return getStat().getExp();
}
/**
* Sets the active enchant item.
*
* @param scroll the new active enchant item
*/
public void setActiveEnchantItem(L2ItemInstance scroll)
{
_activeEnchantItem = scroll;
}
/**
* Gets the active enchant item.
*
* @return the active enchant item
*/
public L2ItemInstance getActiveEnchantItem()
{
return _activeEnchantItem;
}
/**
* Set the fists weapon of the L2PcInstance (used when no weapon is equiped).<BR>
* <BR>
*
* @param weaponItem The fists L2Weapon to set to the L2PcInstance
*/
public void setFistsWeaponItem(L2Weapon weaponItem)
{
_fistsWeaponItem = weaponItem;
}
/**
* Return the fists weapon of the L2PcInstance (used when no weapon is equiped).<BR>
* <BR>
*
* @return the fists weapon item
*/
public L2Weapon getFistsWeaponItem()
{
return _fistsWeaponItem;
}
/**
* Return the fists weapon of the L2PcInstance Class (used when no weapon is equiped).<BR>
* <BR>
*
* @param classId the class id
* @return the l2 weapon
*/
public L2Weapon findFistsWeaponItem(int classId)
{
L2Weapon weaponItem = null;
if(classId >= 0x00 && classId <= 0x09)
{
//human fighter fists
L2Item temp = ItemTable.getInstance().getTemplate(246);
weaponItem = (L2Weapon) temp;
temp = null;
}
else if(classId >= 0x0a && classId <= 0x11)
{
//human mage fists
L2Item temp = ItemTable.getInstance().getTemplate(251);
weaponItem = (L2Weapon) temp;
temp = null;
}
else if(classId >= 0x12 && classId <= 0x18)
{
//elven fighter fists
L2Item temp = ItemTable.getInstance().getTemplate(244);
weaponItem = (L2Weapon) temp;
temp = null;
}
else if(classId >= 0x19 && classId <= 0x1e)
{
//elven mage fists
L2Item temp = ItemTable.getInstance().getTemplate(249);
weaponItem = (L2Weapon) temp;
temp = null;
}
else if(classId >= 0x1f && classId <= 0x25)
{
//dark elven fighter fists
L2Item temp = ItemTable.getInstance().getTemplate(245);
weaponItem = (L2Weapon) temp;
temp = null;
}
else if(classId >= 0x26 && classId <= 0x2b)
{
//dark elven mage fists
L2Item temp = ItemTable.getInstance().getTemplate(250);
weaponItem = (L2Weapon) temp;
temp = null;
}
else if(classId >= 0x2c && classId <= 0x30)
{
//orc fighter fists
L2Item temp = ItemTable.getInstance().getTemplate(248);
weaponItem = (L2Weapon) temp;
temp = null;
}
else if(classId >= 0x31 && classId <= 0x34)
{
//orc mage fists
L2Item temp = ItemTable.getInstance().getTemplate(252);
weaponItem = (L2Weapon) temp;
temp = null;
}
else if(classId >= 0x35 && classId <= 0x39)
{
//dwarven fists
L2Item temp = ItemTable.getInstance().getTemplate(247);
weaponItem = (L2Weapon) temp;
temp = null;
}
return weaponItem;
}
/**
* Give Expertise skill of this level and remove beginner Lucky skill.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Get the Level of the L2PcInstance</li> <li>If L2PcInstance Level is 5, remove beginner Lucky skill</li> <li>
* Add the Expertise skill corresponding to its Expertise level</li> <li>Update the overloaded status of the
* L2PcInstance</li><BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T give other free skills (SP needed = 0)</B></FONT><BR>
* <BR>
*/
public synchronized void rewardSkills()
{
// Get the Level of the L2PcInstance
int lvl = getLevel();
// Remove beginner Lucky skill
if(lvl == 10)
{
L2Skill skill = SkillTable.getInstance().getInfo(194, 1);
skill = removeSkill(skill);
if(Config.DEBUG && skill != null)
{
_log.fine("removed skill 'Lucky' from " + getName());
}
skill = null;
}
// Calculate the current higher Expertise of the L2PcInstance
for(int i = 0; i < EXPERTISE_LEVELS.length; i++)
{
if(lvl >= EXPERTISE_LEVELS[i])
{
setExpertiseIndex(i);
}
}
// Add the Expertise skill corresponding to its Expertise level
if(getExpertiseIndex() > 0)
{
L2Skill skill = SkillTable.getInstance().getInfo(239, getExpertiseIndex());
addSkill(skill, true);
if(Config.DEBUG)
{
_log.fine("awarded " + getName() + " with new expertise.");
}
skill = null;
}
else
{
if(Config.DEBUG)
{
_log.fine("No skills awarded at lvl: " + lvl);
}
}
//Active skill dwarven craft
if(getSkillLevel(1321) < 1 && getRace() == Race.dwarf)
{
L2Skill skill = SkillTable.getInstance().getInfo(1321, 1);
addSkill(skill, true);
skill = null;
}
//Active skill common craft
if(getSkillLevel(1322) < 1)
{
L2Skill skill = SkillTable.getInstance().getInfo(1322, 1);
addSkill(skill, true);
skill = null;
}
for(int i = 0; i < COMMON_CRAFT_LEVELS.length; i++)
{
if(lvl >= COMMON_CRAFT_LEVELS[i] && getSkillLevel(1320) < i + 1)
{
L2Skill skill = SkillTable.getInstance().getInfo(1320, (i + 1));
addSkill(skill, true);
skill = null;
}
}
// Auto-Learn skills if activated
if(Config.AUTO_LEARN_SKILLS)
{
giveAvailableSkills();
}
sendSkillList();
if (_clan != null)
{
if (_clan.getLevel() > 3 && isClanLeader())
SiegeManager.getInstance().addSiegeSkills(this);
}
// This function gets called on login, so not such a bad place to check weight
refreshOverloaded(); // Update the overloaded status of the L2PcInstance
refreshExpertisePenalty(); // Update the expertise status of the L2PcInstance
refreshMasteryPenality();
refreshMasteryWeapPenality();
}
/**
* Regive all skills which aren't saved to database, like Noble, Hero, Clan Skills<BR>
* <BR>.
*/
private synchronized void regiveTemporarySkills()
{
// Do not call this on enterworld or char load
// Add noble skills if noble
if(isNoble())
{
setNoble(true);
}
// Add Hero skills if hero
if(isHero())
{
setHero(true);
}
/*
// Add clan leader skills if clanleader
if(isClanLeader())
{
setClanLeader(true);
}
*/
// Add clan skills
if(getClan() != null && getClan().getReputationScore() >= 0)
{
L2Skill[] skills = getClan().getAllSkills();
for(L2Skill sk : skills)
{
if(sk.getMinPledgeClass() <= getPledgeClass())
{
addSkill(sk, false);
}
}
skills = null;
}
// Reload passive skills from armors / jewels / weapons
getInventory().reloadEquippedItems();
}
/**
* Give all available skills to the player.<br>
* <br>
*/
public void giveAvailableSkills()
{
// int unLearnable = 0;
int skillCounter = 0;
// Get available skills
// L2SkillLearn[] skills = SkillTreeTable.getInstance().getAvailableSkills(this, getClassId());
// while(skills.length > unLearnable)
// {
// unLearnable = 0;
// for(L2SkillLearn s : skills)
Collection<L2Skill> skills = SkillTreeTable.getInstance().getAllAvailableSkills(this, getClassId());
for (L2Skill sk : skills){
// {
// L2Skill sk = SkillTable.getInstance().getInfo(s.getId(), s.getLevel());
// if(sk == null || (sk.getId() == L2Skill.SKILL_DIVINE_INSPIRATION && !Config.AUTO_LEARN_DIVINE_INSPIRATION))
// {
// unLearnable++;
// continue;
// }
if(getSkillLevel(sk.getId()) == -1)
{
skillCounter++;
}
// Penality skill are not auto learn
if(sk.getId() == 4267 || sk.getId() == 4270)
continue;
// fix when learning toggle skills
if(sk.isToggle())
{
L2Effect toggleEffect = getFirstEffect(sk.getId());
if(toggleEffect != null)
{
// stop old toggle skill effect, and give new toggle skill effect back
toggleEffect.exit(false);
sk.getEffects(this, this,false,false,false);
}
}
addSkill(sk, true);
}
// // Get new available skills
// skills = SkillTreeTable.getInstance().getAvailableSkills(this, getClassId());
// }
sendMessage("You have learned " + skillCounter + " new skills.");
skills = null;
}
/**
* Set the Experience value of the L2PcInstance.
*
* @param exp the new exp
*/
public void setExp(long exp)
{
getStat().setExp(exp);
}
/**
* Return the Race object of the L2PcInstance.<BR>
* <BR>
*
* @return the race
*/
public Race getRace()
{
if(!isSubClassActive())
return getTemplate().race;
L2PcTemplate charTemp = CharTemplateTable.getInstance().getTemplate(_baseClass);
return charTemp.race;
}
/**
* Gets the radar.
*
* @return the radar
*/
public L2Radar getRadar()
{
return _radar;
}
/**
* Return the SP amount of the L2PcInstance.
*
* @return the sp
*/
public int getSp()
{
return getStat().getSp();
}
/**
* Set the SP amount of the L2PcInstance.
*
* @param sp the new sp
*/
public void setSp(int sp)
{
super.getStat().setSp(sp);
}
/**
* Return true if this L2PcInstance is a clan leader in ownership of the passed castle.
*
* @param castleId the castle id
* @return true, if is castle lord
*/
public boolean isCastleLord(int castleId)
{
L2Clan clan = getClan();
// player has clan and is the clan leader, check the castle info
if(clan != null && clan.getLeader().getPlayerInstance() == this)
{
// if the clan has a castle and it is actually the queried castle, return true
Castle castle = CastleManager.getInstance().getCastleByOwner(clan);
if(castle != null && castle == CastleManager.getInstance().getCastleById(castleId))
{
castle = null;
return true;
}
castle = null;
}
clan = null;
return false;
}
/**
* Return the Clan Identifier of the L2PcInstance.<BR>
* <BR>
*
* @return the clan id
*/
public int getClanId()
{
return _clanId;
}
/**
* Return the Clan Crest Identifier of the L2PcInstance or 0.<BR>
* <BR>
*
* @return the clan crest id
*/
public int getClanCrestId()
{
if(_clan != null && _clan.hasCrest())
return _clan.getCrestId();
return 0;
}
/**
* Gets the clan crest large id.
*
* @return The Clan CrestLarge Identifier or 0
*/
public int getClanCrestLargeId()
{
if(_clan != null && _clan.hasCrestLarge())
return _clan.getCrestLargeId();
return 0;
}
/**
* Gets the clan join expiry time.
*
* @return the clan join expiry time
*/
public long getClanJoinExpiryTime()
{
return _clanJoinExpiryTime;
}
/**
* Sets the clan join expiry time.
*
* @param time the new clan join expiry time
*/
public void setClanJoinExpiryTime(long time)
{
_clanJoinExpiryTime = time;
}
/**
* Gets the clan create expiry time.
*
* @return the clan create expiry time
*/
public long getClanCreateExpiryTime()
{
return _clanCreateExpiryTime;
}
/**
* Sets the clan create expiry time.
*
* @param time the new clan create expiry time
*/
public void setClanCreateExpiryTime(long time)
{
_clanCreateExpiryTime = time;
}
/**
* Sets the online time.
*
* @param time the new online time
*/
public void setOnlineTime(long time)
{
_onlineTime = time;
_onlineBeginTime = System.currentTimeMillis();
}
/**
* Return the PcInventory Inventory of the L2PcInstance contained in _inventory.<BR>
* <BR>
*
* @return the inventory
*/
public PcInventory getInventory()
{
return _inventory;
}
/**
* Delete a ShortCut of the L2PcInstance _shortCuts.<BR>
* <BR>
*
* @param objectId the object id
*/
public void removeItemFromShortCut(int objectId)
{
_shortCuts.deleteShortCutByObjectId(objectId);
}
//MOVING on attack TASK, L2OFF FIX
/** The launched moving task. */
protected MoveOnAttack launchedMovingTask = null;
/** The _moving task defined. */
protected Boolean _movingTaskDefined = false;
/**
* MoveOnAttack Task.
*/
public class MoveOnAttack implements Runnable
{
/** The _player. */
final L2PcInstance _player;
/** The _pos. */
L2CharPosition _pos;
/**
* Instantiates a new move on attack.
* @param player the player
* @param pos the pos
*/
public MoveOnAttack(L2PcInstance player, L2CharPosition pos)
{
_player = player;
_pos = pos;
// launchedMovingTask = this;
}
/*
* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
synchronized (_movingTaskDefined)
{
launchedMovingTask = null;
_movingTaskDefined = false;
}
// Set the Intention of this AbstractAI to AI_INTENTION_MOVE_TO
_player.getAI().changeIntention(AI_INTENTION_MOVE_TO, _pos, null);
// Stop the actor auto-attack client side by sending Server->Client packet AutoAttackStop (broadcast)
_player.getAI().clientStopAutoAttack();
// Abort the attack of the L2Character and send Server->Client ActionFailed packet
_player.abortAttack();
// Move the actor to Location (x,y,z) server side AND client side by sending Server->Client packet CharMoveToLocation (broadcast)
_player.getAI().moveTo(_pos.x, _pos.y, _pos.z);
}
/**
* Sets the new position.
* @param pos the new new position
*/
public void setNewPosition(L2CharPosition pos)
{
_pos = pos;
}
}
/**
* Checks if is moving task defined.
*
* @return true, if is moving task defined
*/
public boolean isMovingTaskDefined()
{
return _movingTaskDefined;
//return launchedMovingTask != null;
}
/**
* Define new moving task.
* @param pos the pos
*/
public void defineNewMovingTask(L2CharPosition pos)
{
synchronized (_movingTaskDefined)
{
launchedMovingTask = new MoveOnAttack(this, pos);
_movingTaskDefined = true;
}
}
/**
* Modify moving task.
* @param pos the pos
*/
public void modifyMovingTask(L2CharPosition pos)
{
synchronized (_movingTaskDefined)
{
if (!_movingTaskDefined)
return;
launchedMovingTask.setNewPosition(pos);
}
}
/**
* Start moving task.
*/
public void startMovingTask()
{
synchronized (_movingTaskDefined)
{
if (!_movingTaskDefined)
return;
if((isMoving() && isAttackingNow()))
return;
ThreadPoolManager.getInstance().executeTask(launchedMovingTask);
}
}
/**
* Return True if the L2PcInstance is sitting.<BR>
* <BR>
*
* @return true, if is sitting
*/
public boolean isSitting()
{
return _waitTypeSitting || sittingTaskLaunched;
}
/**
* Return True if the L2PcInstance is sitting task launched.<BR>
* <BR>
*
* @return true, if is sitting task launched
*/
public boolean isSittingTaskLaunched()
{
return sittingTaskLaunched;
}
/**
* Set _waitTypeSitting to given value.
*
* @param state the new checks if is sitting
*/
public void setIsSitting(boolean state)
{
_waitTypeSitting = state;
}
/**
* Sets the posticipate sit.
*
* @param act the new posticipate sit
*/
public void setPosticipateSit(boolean act)
{
_posticipateSit = act;
}
/**
* Gets the posticipate sit.
*
* @return the posticipate sit
*/
public boolean getPosticipateSit()
{
return _posticipateSit;
}
/**
* Sit down the L2PcInstance, set the AI Intention to AI_INTENTION_REST and send a Server->Client ChangeWaitType
* packet (broadcast)<BR>
* <BR>.
*/
public void sitDown()
{
if(isFakeDeath())
{
stopFakeDeath(null);
}
if(isMoving()) //since you are moving and want sit down
//the posticipate sitdown task will be always true
{
setPosticipateSit(true);
return;
}
//we are going to sitdown, so posticipate is false
setPosticipateSit(false);
if(isCastingNow() && !_relax)
return;
if(sittingTaskLaunched) //if already started the task
//just return
return;
if(!_waitTypeSitting && !isAttackingDisabled() && !isOutOfControl() && !isImobilised())
{
breakAttack();
setIsSitting(true);
broadcastPacket(new ChangeWaitType(this, ChangeWaitType.WT_SITTING));
sittingTaskLaunched = true;
// Schedule a sit down task to wait for the animation to finish
ThreadPoolManager.getInstance().scheduleGeneral(new SitDownTask(this), 2500);
setIsParalyzed(true);
}
}
/**
* Sit down Task.
*/
class SitDownTask implements Runnable
{
/** The _player. */
L2PcInstance _player;
/** The this$0. */
final L2PcInstance this$0;
/**
* Instantiates a new sit down task.
*
* @param player the player
*/
SitDownTask(L2PcInstance player)
{
this$0 = L2PcInstance.this;
_player = player;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
setIsSitting(true);
_player.setIsParalyzed(false);
sittingTaskLaunched = false;
_player.getAI().setIntention(CtrlIntention.AI_INTENTION_REST);
}
}
/**
* Stand up Task.
*/
class StandUpTask implements Runnable
{
/** The _player. */
L2PcInstance _player;
/**
* Instantiates a new stand up task.
*
* @param player the player
*/
StandUpTask(L2PcInstance player)
{
_player = player;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
_player.setIsSitting(false);
_player.setIsImobilised(false);
_player.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
}
}
/**
* Stand up the L2PcInstance, set the AI Intention to AI_INTENTION_IDLE and send a Server->Client ChangeWaitType
* packet (broadcast)<BR>
* <BR>.
*/
public void standUp()
{
if(isFakeDeath())
{
broadcastPacket(new ChangeWaitType(this, ChangeWaitType.WT_STANDING));
// Schedule a stand up task to wait for the animation to finish
setIsImobilised(true);
ThreadPoolManager.getInstance().scheduleGeneral(new StandUpTask(this), 2000);
stopFakeDeath(null);
}
if(sittingTaskLaunched){
return;
}
if(L2Event.active && eventSitForced)
{
sendMessage("A dark force beyond your mortal understanding makes your knees to shake when you try to stand up ...");
}
else if((TvT.is_sitForced() && _inEventTvT) || (CTF.is_sitForced() && _inEventCTF) || (DM.is_sitForced() && _inEventDM))
{
sendMessage("The Admin/GM handle if you sit or stand in this match!");
}
else if (Raid._sitForced && _inEventRaid)
{
sendMessage("A dark force beyond your mortal understanding makes your knees shake when you try to stand up ...");
}
else if(VIP._sitForced && _inEventVIP)
{
sendMessage("The Admin/GM handle if you sit or stand in this match!");
}
else if(isAway())
{
sendMessage("You can't stand up if your Status is Away.");
}
else if(_waitTypeSitting && !isInStoreMode() && !isAlikeDead())
{
if(_relax)
{
setRelax(false);
stopEffects(L2Effect.EffectType.RELAXING);
}
broadcastPacket(new ChangeWaitType(this, ChangeWaitType.WT_STANDING));
// Schedule a stand up task to wait for the animation to finish
setIsImobilised(true);
ThreadPoolManager.getInstance().scheduleGeneral(new StandUpTask(this), 2500);
}
}
/**
* Set the value of the _relax value. Must be True if using skill Relax and False if not.
*
* @param val the new relax
*/
public void setRelax(boolean val)
{
_relax = val;
}
/**
* Return the PcWarehouse object of the L2PcInstance.<BR>
* <BR>
*
* @return the warehouse
*/
public PcWarehouse getWarehouse()
{
if(_warehouse == null)
{
_warehouse = new PcWarehouse(this);
_warehouse.restore();
}
if(Config.WAREHOUSE_CACHE)
{
WarehouseCacheManager.getInstance().addCacheTask(this);
}
return _warehouse;
}
/**
* Free memory used by Warehouse.
*/
public void clearWarehouse()
{
if(_warehouse != null)
{
_warehouse.deleteMe();
}
_warehouse = null;
}
/**
* Return the PcFreight object of the L2PcInstance.<BR>
* <BR>
*
* @return the freight
*/
public PcFreight getFreight()
{
return _freight;
}
/**
* Return the Identifier of the L2PcInstance.<BR>
* <BR>
*
* @return the char id
*/
public int getCharId()
{
return _charId;
}
/**
* Set the Identifier of the L2PcInstance.<BR>
* <BR>
*
* @param charId the new char id
*/
public void setCharId(int charId)
{
_charId = charId;
}
/**
* Return the Adena amount of the L2PcInstance.<BR>
* <BR>
*
* @return the adena
*/
public int getAdena()
{
return _inventory.getAdena();
}
/**
* Return the Item amount of the L2PcInstance.<BR>
* <BR>
*
* @param itemId the item id
* @param enchantLevel the enchant level
* @return the item count
*/
public int getItemCount(int itemId, int enchantLevel)
{
return _inventory.getInventoryItemCount(itemId, enchantLevel);
}
/**
* Return the Ancient Adena amount of the L2PcInstance.<BR>
* <BR>
*
* @return the ancient adena
*/
public int getAncientAdena()
{
return _inventory.getAncientAdena();
}
public int getPvptoken()
{
return _inventory.getPvptoken();
}
/**
* Add adena to Inventory of the L2PcInstance and send a Server->Client InventoryUpdate packet to the L2PcInstance.
* @param process : String Identifier of process triggering this action
* @param count : int Quantity of adena to be added
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in transformation
* @param sendMessage : boolean Specifies whether to send message to Client about this action
*/
public void addAdena(String process, int count, L2Object reference, boolean sendMessage)
{
if (count > 0)
{
if (_inventory.getAdena() == Integer.MAX_VALUE)
{
return;
}
else if (_inventory.getAdena() >= Integer.MAX_VALUE - count)
{
count = Integer.MAX_VALUE - _inventory.getAdena();
_inventory.addAdena(process, count, this, reference);
}
else if (_inventory.getAdena() < Integer.MAX_VALUE - count)
{
_inventory.addAdena(process, count, this, reference);
}
if (sendMessage)
{
SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_ADENA);
sm.addNumber(count);
sendPacket(sm);
sm = null;
}
// Send update packet
if (!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
iu.addItem(_inventory.getAdenaInstance());
sendPacket(iu);
iu = null;
}
else
{
sendPacket(new ItemList(this, false));
}
}
}
/**
* Reduce adena in Inventory of the L2PcInstance and send a Server->Client InventoryUpdate packet to the
* L2PcInstance.
*
* @param process : String Identifier of process triggering this action
* @param count : int Quantity of adena to be reduced
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in
* transformation
* @param sendMessage : boolean Specifies whether to send message to Client about this action
* @return boolean informing if the action was successfull
*/
public boolean reduceAdena(String process, int count, L2Object reference, boolean sendMessage)
{
if(count > getAdena())
{
if(sendMessage)
{
sendPacket(new SystemMessage(SystemMessageId.YOU_NOT_ENOUGH_ADENA));
}
return false;
}
if(count > 0)
{
L2ItemInstance adenaItem = _inventory.getAdenaInstance();
_inventory.reduceAdena(process, count, this, reference);
// Send update packet
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
iu.addItem(adenaItem);
sendPacket(iu);
iu = null;
}
else
{
sendPacket(new ItemList(this, false));
}
if(sendMessage)
{
SystemMessage sm = new SystemMessage(SystemMessageId.DISSAPEARED_ADENA);
sm.addNumber(count);
sendPacket(sm);
sm = null;
}
adenaItem = null;
}
return true;
}
/**
* Add ancient adena to Inventory of the L2PcInstance and send a Server->Client InventoryUpdate packet to the
* L2PcInstance.
*
* @param process : String Identifier of process triggering this action
* @param count : int Quantity of ancient adena to be added
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in
* transformation
* @param sendMessage : boolean Specifies whether to send message to Client about this action
*/
public void addAncientAdena(String process, int count, L2Object reference, boolean sendMessage)
{
if(sendMessage)
{
SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S);
sm.addItemName(PcInventory.ANCIENT_ADENA_ID);
sm.addNumber(count);
sendPacket(sm);
sm = null;
}
if(count > 0)
{
_inventory.addAncientAdena(process, count, this, reference);
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
iu.addItem(_inventory.getAncientAdenaInstance());
sendPacket(iu);
iu = null;
}
else
{
sendPacket(new ItemList(this, false));
}
}
}
/**
* Reduce ancient adena in Inventory of the L2PcInstance and send a Server->Client InventoryUpdate packet to the
* L2PcInstance.
*
* @param process : String Identifier of process triggering this action
* @param count : int Quantity of ancient adena to be reduced
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in
* transformation
* @param sendMessage : boolean Specifies whether to send message to Client about this action
* @return boolean informing if the action was successfull
*/
public boolean reduceAncientAdena(String process, int count, L2Object reference, boolean sendMessage)
{
if(count > getAncientAdena())
{
if(sendMessage)
{
sendPacket(new SystemMessage(SystemMessageId.YOU_NOT_ENOUGH_ADENA));
}
return false;
}
if(count > 0)
{
L2ItemInstance ancientAdenaItem = _inventory.getAncientAdenaInstance();
_inventory.reduceAncientAdena(process, count, this, reference);
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
iu.addItem(ancientAdenaItem);
sendPacket(iu);
iu = null;
}
else
{
sendPacket(new ItemList(this, false));
}
if(sendMessage)
{
SystemMessage sm = new SystemMessage(SystemMessageId.DISSAPEARED_ITEM);
sm.addNumber(count);
sm.addItemName(PcInventory.ANCIENT_ADENA_ID);
sendPacket(sm);
sm = null;
}
ancientAdenaItem = null;
}
return true;
}
public void addPvptoken(String process, int count, L2Object reference, boolean sendMessage)
{
if(sendMessage)
{
SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S);
sm.addItemName(PcInventory.PVP_TOKEN);
sm.addNumber(count);
sendPacket(sm);
sm = null;
}
if(count > 0)
{
_inventory.addPvptoken(process, count, this, reference);
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
iu.addItem(_inventory.getPvptokenInstance());
sendPacket(iu);
iu = null;
}
else
{
sendPacket(new ItemList(this, false));
}
}
}
public boolean reducePvptoken(String process, int count, L2Object reference, boolean sendMessage)
{
if(count > getPvptoken())
{
if(sendMessage)
{
sendMessage("You don't have enough pvp points.");
}
return false;
}
if(count > 0)
{
L2ItemInstance PvptokenItem = _inventory.getPvptokenInstance();
_inventory.reducePvptoken(process, count, this, reference);
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
iu.addItem(PvptokenItem);
sendPacket(iu);
iu = null;
}
else
{
sendPacket(new ItemList(this, false));
}
if(sendMessage)
{
SystemMessage sm = new SystemMessage(SystemMessageId.DISSAPEARED_ITEM);
sm.addNumber(count);
sm.addItemName(PcInventory.PVP_TOKEN);
sendPacket(sm);
sm = null;
}
PvptokenItem = null;
}
return true;
}
/**
* Adds item to inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
*
* @param process : String Identifier of process triggering this action
* @param item : L2ItemInstance to be added
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in
* transformation
* @param sendMessage : boolean Specifies whether to send message to Client about this action
*/
public void addItem(String process, L2ItemInstance item, L2Object reference, boolean sendMessage)
{
if(item.getCount() > 0)
{
// Sends message to client if requested
if(sendMessage)
{
if(item.getCount() > 1)
{
if(item.isStackable() && !Config.MULTIPLE_ITEM_DROP){
SystemMessage sm = new SystemMessage(SystemMessageId.YOU_PICKED_UP_S1);
sm.addItemName(item.getItemId());
sendPacket(sm);
sm = null;
}else{
SystemMessage sm = new SystemMessage(SystemMessageId.YOU_PICKED_UP_S1_S2);
sm.addItemName(item.getItemId());
sm.addNumber(item.getCount());
sendPacket(sm);
sm = null;
}
}
else if(item.getEnchantLevel() > 0)
{
SystemMessage sm = new SystemMessage(SystemMessageId.YOU_PICKED_UP_A_S1_S2);
sm.addNumber(item.getEnchantLevel());
sm.addItemName(item.getItemId());
sendPacket(sm);
sm = null;
}
else
{
SystemMessage sm = new SystemMessage(SystemMessageId.YOU_PICKED_UP_S1);
sm.addItemName(item.getItemId());
sendPacket(sm);
sm = null;
}
}
// Add the item to inventory
L2ItemInstance newitem = _inventory.addItem(process, item, this, reference);
// Send inventory update packet
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate playerIU = new InventoryUpdate();
playerIU.addItem(newitem);
sendPacket(playerIU);
playerIU = null;
}
else
{
sendPacket(new ItemList(this, false));
}
// Update current load as well
StatusUpdate su = new StatusUpdate(getObjectId());
su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
sendPacket(su);
su = null;
// If over capacity, Drop the item
if(!isGM() && !_inventory.validateCapacity(0))
{
dropItem("InvDrop", newitem, null, true, true);
}
else if(CursedWeaponsManager.getInstance().isCursed(newitem.getItemId()))
{
CursedWeaponsManager.getInstance().activate(this, newitem);
}
newitem = null;
}
// If you pickup arrows.
if (item.getItem().getItemType() == L2EtcItemType.ARROW)
{
// If a bow is equipped, try to equip them if no arrows is currently equipped.
L2Weapon currentWeapon = getActiveWeaponItem();
if (currentWeapon != null && currentWeapon.getItemType() == L2WeaponType.BOW && getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND) == null)
checkAndEquipArrows();
}
}
/**
* Adds item to Inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
*
* @param process : String Identifier of process triggering this action
* @param itemId : int Item Identifier of the item to be added
* @param count : int Quantity of items to be added
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in
* transformation
* @param sendMessage : boolean Specifies whether to send message to Client about this action
*/
public void addItem(String process, int itemId, int count, L2Object reference, boolean sendMessage)
{
if(count > 0)
{
// Sends message to client if requested
if(sendMessage && (!isCastingNow()
&& ItemTable.getInstance().createDummyItem(itemId).getItemType() == L2EtcItemType.HERB
|| ItemTable.getInstance().createDummyItem(itemId).getItemType() != L2EtcItemType.HERB))
{
if(count > 1)
{
if(process.equalsIgnoreCase("sweep") || process.equalsIgnoreCase("Quest"))
{
SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S);
sm.addItemName(itemId);
sm.addNumber(count);
sendPacket(sm);
sm = null;
}
else
{
SystemMessage sm = new SystemMessage(SystemMessageId.YOU_PICKED_UP_S1_S2);
sm.addItemName(itemId);
sm.addNumber(count);
sendPacket(sm);
sm = null;
}
}
else
{
if(process.equalsIgnoreCase("sweep") || process.equalsIgnoreCase("Quest"))
{
SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_ITEM);
sm.addItemName(itemId);
sendPacket(sm);
sm = null;
}
else
{
SystemMessage sm = new SystemMessage(SystemMessageId.YOU_PICKED_UP_S1);
sm.addItemName(itemId);
sendPacket(sm);
sm = null;
}
}
}
//Auto use herbs - autoloot
if(ItemTable.getInstance().createDummyItem(itemId).getItemType() == L2EtcItemType.HERB) //If item is herb dont add it to iv :]
{
if(!isCastingNow() && !isCastingPotionNow())
{
L2ItemInstance herb = new L2ItemInstance(_charId, itemId);
IItemHandler handler = ItemHandler.getInstance().getItemHandler(herb.getItemId());
if(handler == null)
{
_log.warning("No item handler registered for Herb - item ID " + herb.getItemId() + ".");
}
else
{
handler.useItem(this, herb);
if(_herbstask >= 100)
{
_herbstask -= 100;
}
handler = null;
}
herb = null;
}
else
{
_herbstask += 100;
ThreadPoolManager.getInstance().scheduleAi(new HerbTask(process, itemId, count, reference, sendMessage), _herbstask);
}
}
else
{
// Add the item to inventory
L2ItemInstance item = _inventory.addItem(process, itemId, count, this, reference);
// Send inventory update packet
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate playerIU = new InventoryUpdate();
playerIU.addItem(item);
sendPacket(playerIU);
playerIU = null;
}
else
{
sendPacket(new ItemList(this, false));
}
// Update current load as well
StatusUpdate su = new StatusUpdate(getObjectId());
su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
sendPacket(su);
su = null;
// If over capacity, drop the item
if(!isGM() && !_inventory.validateCapacity(item))
{
dropItem("InvDrop", item, null, true, true);
}
else if(CursedWeaponsManager.getInstance().isCursed(item.getItemId()))
{
CursedWeaponsManager.getInstance().activate(this, item);
}
item = null;
}
}
}
/**
* Destroy item from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
*
* @param process : String Identifier of process triggering this action
* @param item : L2ItemInstance to be destroyed
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in
* transformation
* @param sendMessage : boolean Specifies whether to send message to Client about this action
* @return boolean informing if the action was successfull
*/
public boolean destroyItem(String process, L2ItemInstance item, L2Object reference, boolean sendMessage)
{
item = _inventory.destroyItem(process, item, this, reference);
if(item == null)
{
if(sendMessage)
sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
return false;
}
// Send inventory update packet
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate playerIU = new InventoryUpdate();
playerIU.addItem(item);
sendPacket(playerIU);
playerIU = null;
}
else
{
sendPacket(new ItemList(this, false));
}
// Update current load as well
StatusUpdate su = new StatusUpdate(getObjectId());
su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
sendPacket(su);
su = null;
// Sends message to client if requested
if (sendMessage)
{
if (count > 1)
{
SystemMessage sm = new SystemMessage(SystemMessageId.DISSAPEARED_ITEM);
sm.addItemName(item.getItemId());
sm.addNumber(count);
sendPacket(sm);
sm = null;
}
else
{
SystemMessage sm = new SystemMessage(SystemMessageId.S1_HAS_DISAPPEARED);
sm.addItemName(item.getItemId());
sendPacket(sm);
sm = null;
}
}
return true;
}
/**
* Destroys item from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
*
* @param process : String Identifier of process triggering this action
* @param objectId : int Item Instance identifier of the item to be destroyed
* @param count : int Quantity of items to be destroyed
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in
* transformation
* @param sendMessage : boolean Specifies whether to send message to Client about this action
* @return boolean informing if the action was successfull
*/
@Override
public boolean destroyItem(String process, int objectId, int count, L2Object reference, boolean sendMessage)
{
L2ItemInstance item = _inventory.getItemByObjectId(objectId);
if(item == null || item.getCount() < count || _inventory.destroyItem(process, objectId, count, this, reference) == null)
{
if(sendMessage)
sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
return false;
}
// Send inventory update packet
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate playerIU = new InventoryUpdate();
playerIU.addItem(item);
sendPacket(playerIU);
playerIU = null;
}
else
{
sendPacket(new ItemList(this, false));
}
// Update current load as well
StatusUpdate su = new StatusUpdate(getObjectId());
su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
sendPacket(su);
su = null;
// Sends message to client if requested
if (sendMessage)
{
if (count > 1)
{
SystemMessage sm = new SystemMessage(SystemMessageId.DISSAPEARED_ITEM);
sm.addItemName(item.getItemId());
sm.addNumber(count);
sendPacket(sm);
sm = null;
}
else
{
SystemMessage sm = new SystemMessage(SystemMessageId.S1_HAS_DISAPPEARED);
sm.addItemName(item.getItemId());
sendPacket(sm);
sm = null;
}
}
item = null;
return true;
}
/**
* Destroys shots from inventory without logging and only occasional saving to database. Sends a Server->Client
* InventoryUpdate packet to the L2PcInstance.
*
* @param process : String Identifier of process triggering this action
* @param objectId : int Item Instance identifier of the item to be destroyed
* @param count : int Quantity of items to be destroyed
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in
* transformation
* @param sendMessage : boolean Specifies whether to send message to Client about this action
* @return boolean informing if the action was successfull
*/
public boolean destroyItemWithoutTrace(String process, int objectId, int count, L2Object reference, boolean sendMessage)
{
L2ItemInstance item = _inventory.getItemByObjectId(objectId);
if(item == null || item.getCount() < count)
{
if(sendMessage)
{
sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
}
return false;
}
// Adjust item quantity
if(item.getCount() > count)
{
synchronized (item)
{
item.changeCountWithoutTrace(process, -count, this, reference);
item.setLastChange(L2ItemInstance.MODIFIED);
// could do also without saving, but let's save approx 1 of 10
if(GameTimeController.getGameTicks() % 10 == 0)
{
item.updateDatabase();
}
_inventory.refreshWeight();
}
}
else
{
// Destroy entire item and save to database
_inventory.destroyItem(process, item, this, reference);
}
// Send inventory update packet
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate playerIU = new InventoryUpdate();
playerIU.addItem(item);
sendPacket(playerIU);
playerIU = null;
}
else
{
sendPacket(new ItemList(this, false));
}
// Update current load as well
StatusUpdate su = new StatusUpdate(getObjectId());
su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
sendPacket(su);
su = null;
// Sends message to client if requested
if(sendMessage)
{
SystemMessage sm = new SystemMessage(SystemMessageId.S1_HAS_DISAPPEARED);
sm.addNumber(count);
sm.addItemName(item.getItemId());
sendPacket(sm);
sm = null;
}
item = null;
return true;
}
/**
* Destroy item from inventory by using its <B>itemId</B> and send a Server->Client InventoryUpdate packet to the
* L2PcInstance.
*
* @param process : String Identifier of process triggering this action
* @param itemId : int Item identifier of the item to be destroyed
* @param count : int Quantity of items to be destroyed
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in
* transformation
* @param sendMessage : boolean Specifies whether to send message to Client about this action
* @return boolean informing if the action was successfull
*/
@Override
public boolean destroyItemByItemId(String process, int itemId, int count, L2Object reference, boolean sendMessage)
{
L2ItemInstance item = _inventory.getItemByItemId(itemId);
if(item == null || item.getCount() < count || _inventory.destroyItemByItemId(process, itemId, count, this, reference) == null)
{
if(sendMessage)
sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
return false;
}
// Send inventory update packet
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate playerIU = new InventoryUpdate();
playerIU.addItem(item);
sendPacket(playerIU);
playerIU = null;
}
else
{
sendPacket(new ItemList(this, false));
}
// Update current load as well
StatusUpdate su = new StatusUpdate(getObjectId());
su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
sendPacket(su);
su = null;
// Sends message to client if requested
if (sendMessage)
{
if (count > 1)
{
SystemMessage sm = new SystemMessage(SystemMessageId.DISSAPEARED_ITEM);
sm.addItemName(item.getItemId());
sm.addNumber(count);
sendPacket(sm);
sm = null;
}
else
{
SystemMessage sm = new SystemMessage(SystemMessageId.S1_HAS_DISAPPEARED);
sm.addItemName(item.getItemId());
sendPacket(sm);
sm = null;
}
}
item = null;
return true;
}
/**
* Destroy all weared items from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
*
* @param process : String Identifier of process triggering this action
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in
* transformation
* @param sendMessage : boolean Specifies whether to send message to Client about this action
*/
public void destroyWearedItems(String process, L2Object reference, boolean sendMessage)
{
// Go through all Items of the inventory
for(L2ItemInstance item : getInventory().getItems())
{
// Check if the item is a Try On item in order to remove it
if(item.isWear())
{
if(item.isEquipped())
{
getInventory().unEquipItemInSlotAndRecord(item.getEquipSlot());
}
if(_inventory.destroyItem(process, item, this, reference) == null)
{
_log.warning("Player " + getName() + " can't destroy weared item: " + item.getName() + "[ " + item.getObjectId() + " ]");
continue;
}
// Send an Unequipped Message in system window of the player for each Item
SystemMessage sm = new SystemMessage(SystemMessageId.S1_DISARMED);
sm.addItemName(item.getItemId());
sendPacket(sm);
sm = null;
}
}
// Send the StatusUpdate Server->Client Packet to the player with new CUR_LOAD (0x0e) information
StatusUpdate su = new StatusUpdate(getObjectId());
su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
sendPacket(su);
su = null;
// Send the ItemList Server->Client Packet to the player in order to refresh its Inventory
ItemList il = new ItemList(getInventory().getItems(), true);
sendPacket(il);
il = null;
// Send a Server->Client packet UserInfo to this L2PcInstance and CharInfo to all L2PcInstance in its _KnownPlayers
broadcastUserInfo();
// Sends message to client if requested
sendMessage("Trying-on mode has ended.");
}
/**
* Transfers item to another ItemContainer and send a Server->Client InventoryUpdate packet to the L2PcInstance.
*
* @param process : String Identifier of process triggering this action
* @param objectId the object id
* @param count : int Quantity of items to be transfered
* @param target the target
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in
* transformation
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
*/
public L2ItemInstance transferItem(String process, int objectId, int count, Inventory target, L2Object reference)
{
L2ItemInstance oldItem = checkItemManipulation(objectId, count, "transfer");
if(oldItem == null)
return null;
L2ItemInstance newItem = getInventory().transferItem(process, objectId, count, target, this, reference);
if(newItem == null)
return null;
// Send inventory update packet
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate playerIU = new InventoryUpdate();
if(oldItem.getCount() > 0 && oldItem != newItem)
{
playerIU.addModifiedItem(oldItem);
}
else
{
playerIU.addRemovedItem(oldItem);
}
sendPacket(playerIU);
playerIU = null;
}
else
{
sendPacket(new ItemList(this, false));
}
// Update current load as well
StatusUpdate playerSU = new StatusUpdate(getObjectId());
playerSU.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
sendPacket(playerSU);
playerSU = null;
// Send target update packet
if(target instanceof PcInventory)
{
L2PcInstance targetPlayer = ((PcInventory) target).getOwner();
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate playerIU = new InventoryUpdate();
if(newItem.getCount() > count)
{
playerIU.addModifiedItem(newItem);
}
else
{
playerIU.addNewItem(newItem);
}
targetPlayer.sendPacket(playerIU);
}
else
{
targetPlayer.sendPacket(new ItemList(targetPlayer, false));
}
// Update current load as well
playerSU = new StatusUpdate(targetPlayer.getObjectId());
playerSU.addAttribute(StatusUpdate.CUR_LOAD, targetPlayer.getCurrentLoad());
targetPlayer.sendPacket(playerSU);
targetPlayer = null;
playerSU = null;
}
else if(target instanceof PetInventory)
{
PetInventoryUpdate petIU = new PetInventoryUpdate();
if(newItem.getCount() > count)
{
petIU.addModifiedItem(newItem);
}
else
{
petIU.addNewItem(newItem);
}
((PetInventory) target).getOwner().getOwner().sendPacket(petIU);
petIU = null;
}
oldItem = null;
return newItem;
}
/**
* Drop item from inventory and send a Server->Client InventoryUpdate packet to the L2PcInstance.
*
* @param process : String Identifier of process triggering this action
* @param item : L2ItemInstance to be dropped
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in
* transformation
* @param sendMessage : boolean Specifies whether to send message to Client about this action
* @param protectItem the protect item
* @return boolean informing if the action was successfull
*/
public boolean dropItem(String process, L2ItemInstance item, L2Object reference, boolean sendMessage, boolean protectItem)
{
item = _inventory.dropItem(process, item, this, reference);
if(item == null)
{
if(sendMessage)
{
sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
}
return false;
}
item.dropMe(this, getClientX() + Rnd.get(50) - 25, getClientY() + Rnd.get(50) - 25, getClientZ() + 20);
if(Config.DESTROY_DROPPED_PLAYER_ITEM
&& !Config.LIST_PROTECTED_ITEMS.contains(item.getItemId())){
if(Config.AUTODESTROY_ITEM_AFTER > 0){ //autodestroy enabled
if(item.isEquipable() && Config.DESTROY_EQUIPABLE_PLAYER_ITEM || !item.isEquipable())
{
ItemsAutoDestroy.getInstance().addItem(item);
item.setProtected(false);
}else{
item.setProtected(true);
}
}else{
item.setProtected(true);
}
}else{
item.setProtected(true);
}
if (protectItem)
item.getDropProtection().protect(this);
// Send inventory update packet
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate playerIU = new InventoryUpdate();
playerIU.addItem(item);
sendPacket(playerIU);
playerIU = null;
}
else
{
sendPacket(new ItemList(this, false));
}
// Update current load as well
StatusUpdate su = new StatusUpdate(getObjectId());
su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
sendPacket(su);
su = null;
// Sends message to client if requested
if(sendMessage)
{
SystemMessage sm = new SystemMessage(SystemMessageId.YOU_DROPPED_S1);
sm.addItemName(item.getItemId());
sendPacket(sm);
sm = null;
}
return true;
}
/**
* Drop item from inventory by using its <B>objectID</B> and send a Server->Client InventoryUpdate packet to the
* L2PcInstance.
*
* @param process : String Identifier of process triggering this action
* @param objectId : int Item Instance identifier of the item to be dropped
* @param count : int Quantity of items to be dropped
* @param x : int coordinate for drop X
* @param y : int coordinate for drop Y
* @param z : int coordinate for drop Z
* @param reference : L2Object Object referencing current action like NPC selling item or previous item in
* transformation
* @param sendMessage : boolean Specifies whether to send message to Client about this action
* @param protectItem the protect item
* @return L2ItemInstance corresponding to the new item or the updated item in inventory
*/
public L2ItemInstance dropItem(String process, int objectId, int count, int x, int y, int z, L2Object reference, boolean sendMessage, boolean protectItem)
{
L2ItemInstance invitem = _inventory.getItemByObjectId(objectId);
L2ItemInstance item = _inventory.dropItem(process, objectId, count, this, reference);
if(item == null)
{
if(sendMessage)
{
sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
}
return null;
}
item.dropMe(this, x, y, z);
if(Config.AUTODESTROY_ITEM_AFTER > 0 && Config.DESTROY_DROPPED_PLAYER_ITEM && !Config.LIST_PROTECTED_ITEMS.contains(item.getItemId()))
{
if(item.isEquipable() && Config.DESTROY_EQUIPABLE_PLAYER_ITEM || !item.isEquipable())
{
ItemsAutoDestroy.getInstance().addItem(item);
}
}
if(Config.DESTROY_DROPPED_PLAYER_ITEM)
{
if(!item.isEquipable() || item.isEquipable() && Config.DESTROY_EQUIPABLE_PLAYER_ITEM)
{
item.setProtected(false);
}
else
{
item.setProtected(true);
}
}
else
{
item.setProtected(true);
}
if (protectItem)
item.getDropProtection().protect(this);
// Send inventory update packet
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate playerIU = new InventoryUpdate();
playerIU.addItem(invitem);
sendPacket(playerIU);
playerIU = null;
}
else
{
sendPacket(new ItemList(this, false));
}
// Update current load as well
StatusUpdate su = new StatusUpdate(getObjectId());
su.addAttribute(StatusUpdate.CUR_LOAD, getCurrentLoad());
sendPacket(su);
su = null;
// Sends message to client if requested
if(sendMessage)
{
SystemMessage sm = new SystemMessage(SystemMessageId.YOU_DROPPED_S1);
sm.addItemName(item.getItemId());
sendPacket(sm);
sm = null;
}
invitem = null;
return item;
}
/**
* Check item manipulation.
*
* @param objectId the object id
* @param count the count
* @param action the action
* @return the l2 item instance
*/
public L2ItemInstance checkItemManipulation(int objectId, int count, String action)
{
if(L2World.getInstance().findObject(objectId) == null)
{
_log.finest(getObjectId() + ": player tried to " + action + " item not available in L2World");
return null;
}
L2ItemInstance item = getInventory().getItemByObjectId(objectId);
if(item == null || item.getOwnerId() != getObjectId())
{
_log.finest(getObjectId() + ": player tried to " + action + " item he is not owner of");
return null;
}
if(count < 0 || count > 1 && !item.isStackable())
{
_log.finest(getObjectId() + ": player tried to " + action + " item with invalid count: " + count);
return null;
}
if(count > item.getCount())
{
_log.finest(getObjectId() + ": player tried to " + action + " more items than he owns");
return null;
}
// Pet is summoned and not the item that summoned the pet AND not the buggle from strider you're mounting
if(getPet() != null && getPet().getControlItemId() == objectId || getMountObjectID() == objectId)
{
if(Config.DEBUG)
{
_log.finest(getObjectId() + ": player tried to " + action + " item controling pet");
}
return null;
}
if(getActiveEnchantItem() != null && getActiveEnchantItem().getObjectId() == objectId)
{
if(Config.DEBUG)
{
_log.finest(getObjectId() + ":player tried to " + action + " an enchant scroll he was using");
}
return null;
}
if(item.isWear())
// cannot drop/trade wear-items
return null;
return item;
}
/**
* Set _protectEndTime according settings.
* @param protect the new protection
*/
public void setProtection(boolean protect)
{
if (Config.DEVELOPER && (protect || _protectEndTime > 0))
_log.info(getName() + ": Protection " + (protect ? "ON " + (GameTimeController.getGameTicks() + Config.PLAYER_SPAWN_PROTECTION * GameTimeController.TICKS_PER_SECOND) : "OFF") + " (currently " + GameTimeController.getGameTicks() + ")");
if (isInOlympiadMode())
return;
_protectEndTime = protect ? GameTimeController.getGameTicks() + Config.PLAYER_SPAWN_PROTECTION * GameTimeController.TICKS_PER_SECOND : 0;
if (protect)
ThreadPoolManager.getInstance().scheduleGeneral(new TeleportProtectionFinalizer(this), (Config.PLAYER_SPAWN_PROTECTION - 1) * 1000);
}
/**
* Set _teleportProtectEndTime according settings.
* @param protect the new protection
*/
public void setTeleportProtection(boolean protect)
{
if (Config.DEVELOPER && (protect || _teleportProtectEndTime > 0))
_log.warning(getName() + ": Tele Protection " + (protect ? "ON " + (GameTimeController.getGameTicks() + Config.PLAYER_TELEPORT_PROTECTION * GameTimeController.TICKS_PER_SECOND) : "OFF") + " (currently " + GameTimeController.getGameTicks() + ")");
_teleportProtectEndTime = protect ? GameTimeController.getGameTicks() + Config.PLAYER_TELEPORT_PROTECTION * GameTimeController.TICKS_PER_SECOND : 0;
if (protect)
ThreadPoolManager.getInstance().scheduleGeneral(new TeleportProtectionFinalizer(this), (Config.PLAYER_TELEPORT_PROTECTION - 1) * 1000);
if (Config.EFFECT_TELEPORT_PROTECTION)
{
if (protect)
startAbnormalEffect(2097152);
else if (!protect)
stopAbnormalEffect(2097152);
}
}
static class TeleportProtectionFinalizer implements Runnable
{
private L2PcInstance _activeChar;
TeleportProtectionFinalizer(L2PcInstance activeChar)
{
_activeChar = activeChar;
}
@Override
public void run()
{
try
{
if (_activeChar.isSpawnProtected())
_activeChar.sendMessage("The effect of Spawn Protection has been removed.");
else if (_activeChar.isTeleportProtected())
_activeChar.sendMessage("The effect of Teleport Spawn Protection has been removed.");
if (Config.PLAYER_SPAWN_PROTECTION > 0)
_activeChar.setProtection(false);
if (Config.PLAYER_TELEPORT_PROTECTION > 0)
_activeChar.setTeleportProtection(false);
}
catch (Throwable e)
{
if (Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
}
}
}
/**
* Set protection from agro mobs when getting up from fake death, according settings.
*
* @param protect the new recent fake death
*/
public void setRecentFakeDeath(boolean protect)
{
_recentFakeDeathEndTime = protect ? GameTimeController.getGameTicks() + Config.PLAYER_FAKEDEATH_UP_PROTECTION * GameTimeController.TICKS_PER_SECOND : 0;
}
/**
* Checks if is recent fake death.
*
* @return true, if is recent fake death
*/
public boolean isRecentFakeDeath()
{
return _recentFakeDeathEndTime > GameTimeController.getGameTicks();
}
/**
* Get the client owner of this char.<BR>
* <BR>
*
* @return the client
*/
public L2GameClient getClient()
{
return _client;
}
/**
* Sets the client.
*
* @param client the new client
*/
public void setClient(L2GameClient client)
{
_client = client;
updateOnlineStatus();
}
/**
* Close the active connection with the client.<BR>
* <BR>
*/
public void closeNetConnection()
{
if(_client != null)
{
_client.close(new LeaveWorld());
setClient(null);
}
}
/**
* Manage actions when a player click on this L2PcInstance.<BR>
* <BR>
* <B><U> Actions on first click on the L2PcInstance (Select it)</U> :</B><BR>
* <BR>
* <li>Set the target of the player</li> <li>Send a Server->Client packet MyTargetSelected to the player (display the select window)</li><BR>
* <BR>
* <B><U> Actions on second click on the L2PcInstance (Follow it/Attack it/Intercat with it)</U> :</B><BR>
* <BR>
* <li>Send a Server->Client packet MyTargetSelected to the player (display the select window)</li> <li>If this L2PcInstance has a Private Store, notify the player AI with AI_INTENTION_INTERACT</li> <li>If this L2PcInstance is autoAttackable, notify the player AI with AI_INTENTION_ATTACK</li><BR>
* <BR>
* <li>If this L2PcInstance is NOT autoAttackable, notify the player AI with AI_INTENTION_FOLLOW</li><BR>
* <BR>
* <B><U> Example of use </U> :</B><BR>
* <BR>
* <li>Client packet : Action, AttackRequest</li><BR>
* <BR>
* @param player The player that start an action on this L2PcInstance
*/
@Override
public void onAction(L2PcInstance player)
{
// Check if the L2PcInstance is confused
if (player.isOutOfControl())
{
// Send a Server->Client packet ActionFailed to the player
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Check if the player already target this L2PcInstance
if (player.getTarget() != this)
{
// Set the target of the player
player.setTarget(this);
// Send a Server->Client packet MyTargetSelected to the player
// The color to display in the select window is White
player.sendPacket(new MyTargetSelected(getObjectId(), 0));
if (player != this)
{
player.sendPacket(new ValidateLocation(this));
// To be sure update also the pvp flag / war tag status
if (!player.inObserverMode())
this.broadcastUserInfo();
}
}
else
{
if (player != this)
{
player.sendPacket(new ValidateLocation(this));
}
// Check if this L2PcInstance has a Private Store
if (getPrivateStoreType() != 0)
{
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
// Calculate the distance between the L2PcInstance
if (canInteract(player))
{
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
}
}
else
{
/*
* //during teleport phase, players cant do any attack if((TvT.is_teleport() && _inEventTvT) || (CTF.is_teleport() && _inEventCTF) || (DM.is_teleport() && _inEventDM)){ player.sendPacket(ActionFailed.STATIC_PACKET); return; } if (TvT.is_started()) { if ((_inEventTvT &&
* player._teamNameTvT.equals(_teamNameTvT))) { player.sendPacket(ActionFailed.STATIC_PACKET); return; } } if(CTF.is_started()){ if ((_inEventCTF && player._teamNameCTF.equals(_teamNameCTF))) { player.sendPacket(ActionFailed.STATIC_PACKET); return; } }
*/
// Check if this L2PcInstance is autoAttackable
// if (isAutoAttackable(player) || (player._inEventTvT && TvT._started) || (player._inEventCTF && CTF._started) || (player._inEventDM && DM._started) || (player._inEventVIP && VIP._started))
if (isAutoAttackable(player))
{
if (Config.ALLOW_CHAR_KILL_PROTECT)
{
Siege siege = SiegeManager.getInstance().getSiege(player);
if (siege != null && siege.getIsInProgress())
{
if (player.getLevel() > 20 && ((L2Character) player.getTarget()).getLevel() < 20)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() > 40 && ((L2Character) player.getTarget()).getLevel() < 40)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() > 52 && ((L2Character) player.getTarget()).getLevel() < 52)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() > 61 && ((L2Character) player.getTarget()).getLevel() < 61)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() > 76 && ((L2Character) player.getTarget()).getLevel() < 76)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() < 20 && ((L2Character) player.getTarget()).getLevel() > 20)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() < 40 && ((L2Character) player.getTarget()).getLevel() > 40)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() < 52 && ((L2Character) player.getTarget()).getLevel() > 52)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() < 61 && ((L2Character) player.getTarget()).getLevel() > 61)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() < 76 && ((L2Character) player.getTarget()).getLevel() > 76)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
}
siege = null;
}
if (player.getLevel() < Config.ALT_PLAYER_PROTECTION_LEVEL || getLevel() < Config.ALT_PLAYER_PROTECTION_LEVEL)
{
player.sendMessage("You Can't Hit a Player That Is Lower Level From You. Target's Level: " + String.valueOf(Config.ALT_PLAYER_PROTECTION_LEVEL));
player.sendPacket(ActionFailed.STATIC_PACKET);
}
// Player with lvl < 21 can't attack a cursed weapon holder
// And a cursed weapon holder can't attack players with lvl < 21
if (isCursedWeaponEquiped() && player.getLevel() < 21 || player.isCursedWeaponEquiped() && getLevel() < 21)
{
player.sendPacket(ActionFailed.STATIC_PACKET);
}
else
{
if (Config.GEODATA > 0)
{
if (GeoData.getInstance().canSeeTarget(player, this))
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
player.onActionRequest();
}
}
else
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
player.onActionRequest();
}
}
}
else
{
if (Config.GEODATA > 0)
{
if (GeoData.getInstance().canSeeTarget(player, this))
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
}
}
else
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
}
}
}
}
}
/*
* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Object#onActionShift(com.l2jfrozen.gameserver.model.actor.instance.L2PcInstance)
*/
@Override
public void onActionShift(L2PcInstance player)
{
L2Weapon currentWeapon = player.getActiveWeaponItem();
if (player.isGM())
{
if (this != player.getTarget())
{
player.setTarget(this);
player.sendPacket(new MyTargetSelected(getObjectId(), 0));
if (player != this)
{
player.sendPacket(new ValidateLocation(this));
// To be sure update also the pvp flag / war tag status
if (!player.inObserverMode())
this.broadcastUserInfo();
}
}
else
{
AdminEditChar.gatherCharacterInfo(player, this, "charinfo.htm");
}
}
else
// Like L2OFF set the target of the L2PcInstance player
{
if (((TvT.is_started() || TvT.is_teleport()) && !Config.TVT_ALLOW_INTERFERENCE) || ((CTF.is_started() || CTF.is_teleport()) && !Config.CTF_ALLOW_INTERFERENCE) || ((DM.is_started() || DM.is_teleport()) && !Config.DM_ALLOW_INTERFERENCE))
{
if ((_inEventTvT && !player._inEventTvT) || (!_inEventTvT && player._inEventTvT))
{
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
else if ((_inEventCTF && !player._inEventCTF) || (!_inEventCTF && player._inEventCTF))
{
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
else if ((_inEventDM && !player._inEventDM) || (!_inEventDM && player._inEventDM))
{
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
// Check if the L2PcInstance is confused
if (player.isOutOfControl())
{
// Send a Server->Client packet ActionFailed to the player
player.sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Check if the player already target this L2PcInstance
if (player.getTarget() != this)
{
// Set the target of the player
player.setTarget(this);
// Send a Server->Client packet MyTargetSelected to the player
// The color to display in the select window is White
player.sendPacket(new MyTargetSelected(getObjectId(), 0));
if (player != this)
{
player.sendPacket(new ValidateLocation(this));
}
}
else
{
if (player != this)
{
player.sendPacket(new ValidateLocation(this));
}
// Check if this L2PcInstance has a Private Store
if (getPrivateStoreType() != 0)
{
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
// Calculate the distance between the L2PcInstance
if (canInteract(player))
{
// Notify the L2PcInstance AI with AI_INTENTION_INTERACT
player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
}
}
else
{
// Check if this L2PcInstance is autoAttackable
// if (isAutoAttackable(player) || (player._inEventTvT && TvT._started) || (player._inEventCTF && CTF._started) || (player._inEventDM && DM._started) || (player._inEventVIP && VIP._started))
if (isAutoAttackable(player))
{
if (Config.ALLOW_CHAR_KILL_PROTECT)
{
Siege siege = SiegeManager.getInstance().getSiege(player);
if (siege != null && siege.getIsInProgress())
{
if (player.getLevel() > 20 && ((L2Character) player.getTarget()).getLevel() < 20)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() > 40 && ((L2Character) player.getTarget()).getLevel() < 40)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() > 52 && ((L2Character) player.getTarget()).getLevel() < 52)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() > 61 && ((L2Character) player.getTarget()).getLevel() < 61)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() > 76 && ((L2Character) player.getTarget()).getLevel() < 76)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() < 20 && ((L2Character) player.getTarget()).getLevel() > 20)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() < 40 && ((L2Character) player.getTarget()).getLevel() > 40)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() < 52 && ((L2Character) player.getTarget()).getLevel() > 52)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() < 61 && ((L2Character) player.getTarget()).getLevel() > 61)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
if (player.getLevel() < 76 && ((L2Character) player.getTarget()).getLevel() > 76)
{
player.sendMessage("Your target is not in your grade!");
player.sendPacket(ActionFailed.STATIC_PACKET);
}
}
siege = null;
}
if (player.getLevel() < Config.ALT_PLAYER_PROTECTION_LEVEL || getLevel() < Config.ALT_PLAYER_PROTECTION_LEVEL)
{
player.sendMessage("You Can't Hit a Player That Is Lower Level From You. Target's Level: " + String.valueOf(Config.ALT_PLAYER_PROTECTION_LEVEL));
player.sendPacket(ActionFailed.STATIC_PACKET);
}
// Player with lvl < 21 can't attack a cursed weapon holder
// And a cursed weapon holder can't attack players with lvl < 21
if (isCursedWeaponEquiped() && player.getLevel() < 21 || player.isCursedWeaponEquiped() && getLevel() < 21)
{
player.sendPacket(ActionFailed.STATIC_PACKET);
}
else
{
if (Config.GEODATA > 0)
{
if (GeoData.getInstance().canSeeTarget(player, this))
{
// Calculate the distance between the L2PcInstance
// Only archer can hit from long
if (currentWeapon != null && currentWeapon.getItemType() == L2WeaponType.BOW)
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
player.onActionRequest();
}
else if (canInteract(player))
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
player.onActionRequest();
}
else
{
player.sendPacket(ActionFailed.STATIC_PACKET);
}
}
}
else
{
// Calculate the distance between the L2PcInstance
// Only archer can hit from long
if (currentWeapon != null && currentWeapon.getItemType() == L2WeaponType.BOW)
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
player.onActionRequest();
}
else if (canInteract(player))
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
player.onActionRequest();
}
else
{
player.sendPacket(ActionFailed.STATIC_PACKET);
}
}
}
}
else
{
if (Config.GEODATA > 0)
{
if (GeoData.getInstance().canSeeTarget(player, this))
{
// Calculate the distance between the L2PcInstance
// Only archer can hit from long
if (currentWeapon != null && currentWeapon.getItemType() == L2WeaponType.BOW)
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
}
else if (canInteract(player))
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
}
else
{
player.sendPacket(ActionFailed.STATIC_PACKET);
}
}
}
else
{
// Calculate the distance between the L2PcInstance
// Only archer can hit from long
if (currentWeapon != null && currentWeapon.getItemType() == L2WeaponType.BOW)
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
}
else if (canInteract(player))
{
player.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, this);
}
else
{
player.sendPacket(ActionFailed.STATIC_PACKET);
}
}
}
}
}
}
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.actor.instance.L2PlayableInstance#isInFunEvent()
*/
@Override
public boolean isInFunEvent()
{
return (atEvent || isInStartedTVTEvent() || isInStartedDMEvent() || isInStartedCTFEvent() || isInStartedVIPEvent());
}
public boolean isInStartedTVTEvent()
{
return (TvT.is_started() && _inEventTvT);
}
public boolean isRegisteredInTVTEvent()
{
return _inEventTvT;
}
public boolean isInStartedDMEvent(){
return (DM.is_started() && _inEventDM);
}
public boolean isRegisteredInDMEvent(){
return _inEventDM;
}
public boolean isInStartedCTFEvent(){
return (CTF.is_started() && _inEventCTF);
}
public boolean isRegisteredInCTFEvent(){
return _inEventCTF;
}
public boolean isInStartedVIPEvent(){
return (VIP._started && _inEventVIP);
}
public boolean isRegisteredInVIPEvent(){
return _inEventVIP;
}
/**
* Checks if is registered in fun event.
*
* @return true, if is registered in fun event
*/
public boolean isRegisteredInFunEvent(){
return (atEvent || (_inEventTvT) || (_inEventDM) || (_inEventCTF) || (_inEventVIP) || Olympiad.getInstance().isRegistered(this));
}
//To Avoid Offensive skills when locked (during oly start or TODO other events start)
/**
* Are player offensive skills locked.
*
* @return true, if successful
*/
public boolean arePlayerOffensiveSkillsLocked(){
return isInOlympiadMode() && !isOlympiadStart();
}
/**
* Returns true if cp update should be done, false if not.
*
* @param barPixels the bar pixels
* @return boolean
*/
private boolean needCpUpdate(int barPixels)
{
double currentCp = getCurrentCp();
if(currentCp <= 1.0 || getMaxCp() < barPixels)
return true;
if(currentCp <= _cpUpdateDecCheck || currentCp >= _cpUpdateIncCheck)
{
if(currentCp == getMaxCp())
{
_cpUpdateIncCheck = currentCp + 1;
_cpUpdateDecCheck = currentCp - _cpUpdateInterval;
}
else
{
double doubleMulti = currentCp / _cpUpdateInterval;
int intMulti = (int) doubleMulti;
_cpUpdateDecCheck = _cpUpdateInterval * (doubleMulti < intMulti ? intMulti-- : intMulti);
_cpUpdateIncCheck = _cpUpdateDecCheck + _cpUpdateInterval;
}
return true;
}
return false;
}
/**
* Returns true if mp update should be done, false if not.
*
* @param barPixels the bar pixels
* @return boolean
*/
private boolean needMpUpdate(int barPixels)
{
double currentMp = getCurrentMp();
if(currentMp <= 1.0 || getMaxMp() < barPixels)
return true;
if(currentMp <= _mpUpdateDecCheck || currentMp >= _mpUpdateIncCheck)
{
if(currentMp == getMaxMp())
{
_mpUpdateIncCheck = currentMp + 1;
_mpUpdateDecCheck = currentMp - _mpUpdateInterval;
}
else
{
double doubleMulti = currentMp / _mpUpdateInterval;
int intMulti = (int) doubleMulti;
_mpUpdateDecCheck = _mpUpdateInterval * (doubleMulti < intMulti ? intMulti-- : intMulti);
_mpUpdateIncCheck = _mpUpdateDecCheck + _mpUpdateInterval;
}
return true;
}
return false;
}
/**
* Send packet StatusUpdate with current HP,MP and CP to the L2PcInstance and only current HP, MP and Level to all
* other L2PcInstance of the Party.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Send the Server->Client packet StatusUpdate with current HP, MP and CP to this L2PcInstance</li><BR>
* <li>Send the Server->Client packet PartySmallWindowUpdate with current HP, MP and Level to all other L2PcInstance
* of the Party</li><BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T SEND current HP and MP to all L2PcInstance of the
* _statusListener</B></FONT><BR>
* <BR>
*/
@Override
public void broadcastStatusUpdate()
{
//We mustn't send these informations to other players
// Send the Server->Client packet StatusUpdate with current HP and MP to all L2PcInstance that must be informed of HP/MP updates of this L2PcInstance
//super.broadcastStatusUpdate();
// Send the Server->Client packet StatusUpdate with current HP, MP and CP to this L2PcInstance
if(Config.FORCE_COMPLETE_STATUS_UPDATE){
StatusUpdate su = new StatusUpdate(this);
sendPacket(su);
su = null;
}else{
StatusUpdate su = new StatusUpdate(getObjectId());
su.addAttribute(StatusUpdate.CUR_HP, (int) getCurrentHp());
su.addAttribute(StatusUpdate.CUR_MP, (int) getCurrentMp());
su.addAttribute(StatusUpdate.CUR_CP, (int) getCurrentCp());
su.addAttribute(StatusUpdate.MAX_CP, getMaxCp());
sendPacket(su);
su = null;
}
// Check if a party is in progress and party window update is usefull
if(isInParty() && (needCpUpdate(352) || super.needHpUpdate(352) || needMpUpdate(352)))
{
if(Config.DEBUG)
{
_log.fine("Send status for party window of " + getObjectId() + "(" + getName() + ") to his party. CP: " + getCurrentCp() + " HP: " + getCurrentHp() + " MP: " + getCurrentMp());
}
// Send the Server->Client packet PartySmallWindowUpdate with current HP, MP and Level to all other L2PcInstance of the Party
PartySmallWindowUpdate update = new PartySmallWindowUpdate(this);
getParty().broadcastToPartyMembers(this, update);
update = null;
}
if (isInOlympiadMode())
{
// TODO: implement new OlympiadUserInfo
for (L2PcInstance player : getKnownList().getKnownPlayers().values())
{
if (player.getOlympiadGameId()==getOlympiadGameId() && player.isOlympiadStart())
{
if (Config.DEBUG)
{
_log.fine("Send status for Olympia window of " + getObjectId() + "(" + getName() + ") to " + player.getObjectId() + "(" + player.getName() +"). CP: " + getCurrentCp() + " HP: " + getCurrentHp() + " MP: " + getCurrentMp());
}
player.sendPacket(new ExOlympiadUserInfo(this, 1));
}
}
if(Olympiad.getInstance().getSpectators(_olympiadGameId) != null && this.isOlympiadStart())
{
for(L2PcInstance spectator : Olympiad.getInstance().getSpectators(_olympiadGameId))
{
if (spectator == null) continue;
spectator.sendPacket(new ExOlympiadUserInfo(this, getOlympiadSide()));
}
}
}
if(isInDuel())
{
ExDuelUpdateUserInfo update = new ExDuelUpdateUserInfo(this);
DuelManager.getInstance().broadcastToOppositTeam(this, update);
update = null;
}
}
// Custom PVP Color System - Start
/**
* Update pvp color.
*
* @param pvpKillAmount the pvp kill amount
*/
public void updatePvPColor(int pvpKillAmount)
{
if(Config.PVP_COLOR_SYSTEM_ENABLED)
{
//Check if the character has GM access and if so, let them be.
if(isGM())
return;
//Check if the character is donator and if so, let them be.
if(isDonator())
return;
if(pvpKillAmount >= Config.PVP_AMOUNT1 && pvpKillAmount < Config.PVP_AMOUNT2)
{
getAppearance().setNameColor(Config.NAME_COLOR_FOR_PVP_AMOUNT1);
}
else if(pvpKillAmount >= Config.PVP_AMOUNT2 && pvpKillAmount < Config.PVP_AMOUNT3)
{
getAppearance().setNameColor(Config.NAME_COLOR_FOR_PVP_AMOUNT2);
}
else if(pvpKillAmount >= Config.PVP_AMOUNT3 && pvpKillAmount < Config.PVP_AMOUNT4)
{
getAppearance().setNameColor(Config.NAME_COLOR_FOR_PVP_AMOUNT3);
}
else if(pvpKillAmount >= Config.PVP_AMOUNT4 && pvpKillAmount < Config.PVP_AMOUNT5)
{
getAppearance().setNameColor(Config.NAME_COLOR_FOR_PVP_AMOUNT4);
}
else if(pvpKillAmount >= Config.PVP_AMOUNT5)
{
getAppearance().setNameColor(Config.NAME_COLOR_FOR_PVP_AMOUNT5);
}
}
}
//Custom PVP Color System - End
// Custom Pk Color System - Start
/**
* Update pk color.
*
* @param pkKillAmount the pk kill amount
*/
public void updatePkColor(int pkKillAmount)
{
if(Config.PK_COLOR_SYSTEM_ENABLED)
{
//Check if the character has GM access and if so, let them be, like above.
if(isGM())
return;
if(pkKillAmount >= Config.PK_AMOUNT1 && pkKillAmount < Config.PVP_AMOUNT2)
{
getAppearance().setTitleColor(Config.TITLE_COLOR_FOR_PK_AMOUNT1);
}
else if(pkKillAmount >= Config.PK_AMOUNT2 && pkKillAmount < Config.PVP_AMOUNT3)
{
getAppearance().setTitleColor(Config.TITLE_COLOR_FOR_PK_AMOUNT2);
}
else if(pkKillAmount >= Config.PK_AMOUNT3 && pkKillAmount < Config.PVP_AMOUNT4)
{
getAppearance().setTitleColor(Config.TITLE_COLOR_FOR_PK_AMOUNT3);
}
else if(pkKillAmount >= Config.PK_AMOUNT4 && pkKillAmount < Config.PVP_AMOUNT5)
{
getAppearance().setTitleColor(Config.TITLE_COLOR_FOR_PK_AMOUNT4);
}
else if(pkKillAmount >= Config.PK_AMOUNT5)
{
getAppearance().setTitleColor(Config.TITLE_COLOR_FOR_PK_AMOUNT5);
}
}
}
//Custom Pk Color System - End
/**
* Send a Server->Client packet UserInfo to this L2PcInstance and CharInfo to all L2PcInstance in its _KnownPlayers.<BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* Others L2PcInstance in the detection area of the L2PcInstance are identified in <B>_knownPlayers</B>. In order to
* inform other players of this L2PcInstance state modifications, server just need to go through _knownPlayers to
* send Server->Client Packet<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Send a Server->Client packet UserInfo to this L2PcInstance (Public and Private Data)</li> <li>Send a
* Server->Client packet CharInfo to all L2PcInstance in _KnownPlayers of the L2PcInstance (Public data only)</li><BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : DON'T SEND UserInfo packet to other players instead of CharInfo packet.
* Indeed, UserInfo packet contains PRIVATE DATA as MaxHP, STR, DEX...</B></FONT><BR>
* <BR>
*/
public final void broadcastUserInfo()
{
// Send a Server->Client packet UserInfo to this L2PcInstance
sendPacket(new UserInfo(this));
// Send a Server->Client packet CharInfo to all L2PcInstance in _KnownPlayers of the L2PcInstance
if(Config.DEBUG)
{
_log.fine("players to notify:" + getKnownList().getKnownPlayers().size() + " packet: [S] 03 CharInfo");
}
Broadcast.toKnownPlayers(this, new CharInfo(this));
}
/**
* Broadcast title info.
*/
public final void broadcastTitleInfo()
{
// Send a Server->Client packet UserInfo to this L2PcInstance
sendPacket(new UserInfo(this));
// Send a Server->Client packet TitleUpdate to all L2PcInstance in _KnownPlayers of the L2PcInstance
if(Config.DEBUG)
{
_log.fine("players to notify:" + getKnownList().getKnownPlayers().size() + " packet: [S] cc TitleUpdate");
}
Broadcast.toKnownPlayers(this, new TitleUpdate(this));
}
/**
* Return the Alliance Identifier of the L2PcInstance.<BR>
* <BR>
*
* @return the ally id
*/
public int getAllyId()
{
if(_clan == null)
return 0;
return _clan.getAllyId();
}
/**
* Gets the ally crest id.
*
* @return the ally crest id
*/
public int getAllyCrestId()
{
if(getClanId() == 0 || getClan()==null)
return 0;
if(getClan().getAllyId() == 0)
return 0;
return getClan().getAllyCrestId();
}
/**
* Manage Interact Task with another L2PcInstance.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>If the private store is a STORE_PRIVATE_SELL, send a Server->Client PrivateBuyListSell packet to the
* L2PcInstance</li> <li>If the private store is a STORE_PRIVATE_BUY, send a Server->Client PrivateBuyListBuy packet
* to the L2PcInstance</li> <li>If the private store is a STORE_PRIVATE_MANUFACTURE, send a Server->Client
* RecipeShopSellList packet to the L2PcInstance</li><BR>
* <BR>
*
* @param target The L2Character targeted
*/
public void doInteract(L2Character target)
{
if(target instanceof L2PcInstance)
{
L2PcInstance temp = (L2PcInstance) target;
sendPacket(ActionFailed.STATIC_PACKET);
if(temp.getPrivateStoreType() == STORE_PRIVATE_SELL || temp.getPrivateStoreType() == STORE_PRIVATE_PACKAGE_SELL)
{
sendPacket(new PrivateStoreListSell(this, temp));
}
else if(temp.getPrivateStoreType() == STORE_PRIVATE_BUY)
{
sendPacket(new PrivateStoreListBuy(this, temp));
}
else if(temp.getPrivateStoreType() == STORE_PRIVATE_MANUFACTURE)
{
sendPacket(new RecipeShopSellList(this, temp));
}
temp = null;
}
else
{
// _interactTarget=null should never happen but one never knows ^^;
if(target != null)
{
target.onAction(this);
}
}
}
/**
* Manage AutoLoot Task.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Send a System Message to the L2PcInstance : YOU_PICKED_UP_S1_ADENA or YOU_PICKED_UP_S1_S2</li> <li>Add the
* Item to the L2PcInstance inventory</li> <li>Send a Server->Client packet InventoryUpdate to this L2PcInstance
* with NewItem (use a new slot) or ModifiedItem (increase amount)</li> <li>Send a Server->Client packet
* StatusUpdate to this L2PcInstance with current weight</li><BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : If a Party is in progress, distribute Items between party
* members</B></FONT><BR>
* <BR>
*
* @param target The L2ItemInstance dropped
* @param item the item
*/
public void doAutoLoot(L2Attackable target, L2Attackable.RewardItem item)
{
if(isInParty())
{
getParty().distributeItem(this, item, false, target);
}
else if(item.getItemId() == 57)
{
addAdena("AutoLoot", item.getCount(), target, true);
}
else
{
addItem("AutoLoot", item.getItemId(), item.getCount(), target, true);
}
}
/**
* Manage Pickup Task.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Send a Server->Client packet StopMove to this L2PcInstance</li> <li>Remove the L2ItemInstance from the world and send server->client GetItem packets</li> <li>Send a System Message to the L2PcInstance : YOU_PICKED_UP_S1_ADENA or YOU_PICKED_UP_S1_S2</li> <li>Add the Item to the L2PcInstance
* inventory</li> <li>Send a Server->Client packet InventoryUpdate to this L2PcInstance with NewItem (use a new slot) or ModifiedItem (increase amount)</li> <li>Send a Server->Client packet StatusUpdate to this L2PcInstance with current weight</li> <BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : If a Party is in progress, distribute Items between party members</B></FONT><BR>
* <BR>
* @param object The L2ItemInstance to pick up
*/
protected void doPickupItem(L2Object object)
{
if (isAlikeDead() || isFakeDeath())
return;
// Set the AI Intention to AI_INTENTION_IDLE
getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
// Check if the L2Object to pick up is a L2ItemInstance
if (!(object instanceof L2ItemInstance))
{
// dont try to pickup anything that is not an item :)
_log.warning(this + "trying to pickup wrong target." + getTarget());
return;
}
L2ItemInstance target = (L2ItemInstance) object;
// Send a Server->Client packet ActionFailed to this L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
// Send a Server->Client packet StopMove to this L2PcInstance
StopMove sm = new StopMove(this);
if (Config.DEBUG)
_log.fine("pickup pos: " + target.getX() + " " + target.getY() + " " + target.getZ());
sendPacket(sm);
sm = null;
synchronized (target)
{
// Check if the target to pick up is visible
if (!target.isVisible())
{
// Send a Server->Client packet ActionFailed to this L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
if (!target.getDropProtection().tryPickUp(this) && target.getItemId() != 8190 && target.getItemId() != 8689)
{
sendPacket(ActionFailed.STATIC_PACKET);
SystemMessage smsg = new SystemMessage(SystemMessageId.FAILED_TO_PICKUP_S1);
smsg.addItemName(target.getItemId());
sendPacket(smsg);
return;
}
if ((isInParty() && getParty().getLootDistribution() == L2Party.ITEM_LOOTER || !isInParty()) && !_inventory.validateCapacity(target))
{
sendPacket(ActionFailed.STATIC_PACKET);
sendPacket(new SystemMessage(SystemMessageId.SLOTS_FULL));
return;
}
if (isInvul() && !isGM())
{
sendPacket(ActionFailed.STATIC_PACKET);
SystemMessage smsg = new SystemMessage(SystemMessageId.FAILED_TO_PICKUP_S1);
smsg.addItemName(target.getItemId());
sendPacket(smsg);
smsg = null;
return;
}
if (target.getOwnerId() != 0 && target.getOwnerId() != getObjectId() && !isInLooterParty(target.getOwnerId()))
{
sendPacket(ActionFailed.STATIC_PACKET);
if (target.getItemId() == 57)
{
SystemMessage smsg = new SystemMessage(SystemMessageId.FAILED_TO_PICKUP_S1_ADENA);
smsg.addNumber(target.getCount());
sendPacket(smsg);
smsg = null;
}
else if (target.getCount() > 1)
{
SystemMessage smsg = new SystemMessage(SystemMessageId.FAILED_TO_PICKUP_S2_S1_S);
smsg.addItemName(target.getItemId());
smsg.addNumber(target.getCount());
sendPacket(smsg);
smsg = null;
}
else
{
SystemMessage smsg = new SystemMessage(SystemMessageId.FAILED_TO_PICKUP_S1);
smsg.addItemName(target.getItemId());
sendPacket(smsg);
smsg = null;
}
return;
}
if (target.getItemId() == 57 && _inventory.getAdena() == Integer.MAX_VALUE)
{
sendMessage("You have reached the maximum amount of adena, please spend or deposit the adena so you may continue obtaining adena.");
return;
}
if (target.getItemLootShedule() != null && (target.getOwnerId() == getObjectId() || isInLooterParty(target.getOwnerId())))
{
target.resetOwnerTimer();
}
// Fixed it's not possible pick up the object if you exceed the maximum weight.
if (_inventory.getTotalWeight() + target.getItem().getWeight() * target.getCount() > getMaxLoad())
{
sendMessage("You have reached the maximun weight.");
return;
}
// Remove the L2ItemInstance from the world and send server->client GetItem packets
target.pickupMe(this);
if (Config.SAVE_DROPPED_ITEM)
ItemsOnGroundManager.getInstance().removeObject(target);
}
// Auto use herbs - pick up
if (target.getItemType() == L2EtcItemType.HERB)
{
IItemHandler handler = ItemHandler.getInstance().getItemHandler(target.getItemId());
if (handler == null)
_log.fine("No item handler registered for item ID " + target.getItemId() + ".");
else
handler.useItem(this, target);
ItemTable.getInstance().destroyItem("Consume", target, this, null);
handler = null;
}
// Cursed Weapons are not distributed
else if (CursedWeaponsManager.getInstance().isCursed(target.getItemId()))
{
/*
* Lineage2.com: When a player that controls Akamanah acquires Zariche,
* the newly-acquired Zariche automatically disappeared,
* and the equipped Akamanah's level increases by 1.
* The same rules also apply in the opposite instance.
*/
addItem("Pickup", target, null, true);
}
else if (FortSiegeManager.getInstance().isCombat(target.getItemId()))
{
addItem("Pickup", target, null, true);
}
else
{
// if item is instance of L2ArmorType or L2WeaponType broadcast an "Attention" system message
if (target.getItemType() instanceof L2ArmorType || target.getItemType() instanceof L2WeaponType || target.getItem() instanceof L2Armor || target.getItem() instanceof L2Weapon)
{
if (target.getEnchantLevel() > 0)
{
SystemMessage msg = new SystemMessage(SystemMessageId.ATTENTION_S1_PICKED_UP_S2_S3);
msg.addString(getName());
msg.addNumber(target.getEnchantLevel());
msg.addItemName(target.getItemId());
broadcastPacket(msg, 1400);
}
else
{
SystemMessage msg = new SystemMessage(SystemMessageId.ATTENTION_S1_PICKED_UP_S2);
msg.addString(getName());
msg.addItemName(target.getItemId());
broadcastPacket(msg, 1400);
}
}
// Check if a Party is in progress
if (isInParty())
{
getParty().distributeItem(this, target);
}
else if (target.getItemId() == 57 && getInventory().getAdenaInstance() != null)
{
addAdena("Pickup", target.getCount(), null, true);
ItemTable.getInstance().destroyItem("Pickup", target, this, null);
}
// Target is regular item
else
{
addItem("Pickup", target, null, true);
// Like L2OFF Auto-Equip arrows if player has a bow and player picks up arrows.
if (target.getItem() != null && target.getItem().getItemType() == L2EtcItemType.ARROW)
checkAndEquipArrows();
}
}
target = null;
}
/**
* Set a target.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Remove the L2PcInstance from the _statusListener of the old target if it was a L2Character</li> <li>Add the
* L2PcInstance to the _statusListener of the new target if it's a L2Character</li> <li>Target the new L2Object (add
* the target to the L2PcInstance _target, _knownObject and L2PcInstance to _KnownObject of the L2Object)</li><BR>
* <BR>
*
* @param newTarget The L2Object to target
*/
@Override
public void setTarget(L2Object newTarget)
{
// Check if the new target is visible
if(newTarget != null && !newTarget.isVisible())
{
newTarget = null;
}
// Prevents /target exploiting
if(newTarget != null)
{
if(!(newTarget instanceof L2PcInstance) || !isInParty() || !((L2PcInstance) newTarget).isInParty() || getParty().getPartyLeaderOID() != ((L2PcInstance) newTarget).getParty().getPartyLeaderOID())
{
if(Math.abs(newTarget.getZ() - getZ()) > Config.DIFFERENT_Z_NEW_MOVIE)
{
newTarget = null;
}
}
}
if(!isGM())
{
// Can't target and attack festival monsters if not participant
if(newTarget instanceof L2FestivalMonsterInstance && !isFestivalParticipant())
{
newTarget = null;
}
else if(isInParty() && getParty().isInDimensionalRift())
{
byte riftType = getParty().getDimensionalRift().getType();
byte riftRoom = getParty().getDimensionalRift().getCurrentRoom();
if(newTarget != null && !DimensionalRiftManager.getInstance().getRoom(riftType, riftRoom).checkIfInZone(newTarget.getX(), newTarget.getY(), newTarget.getZ()))
{
newTarget = null;
}
}
}
// Get the current target
L2Object oldTarget = getTarget();
if(oldTarget != null)
{
if(oldTarget.equals(newTarget))
return; // no target change
// Remove the L2PcInstance from the _statusListener of the old target if it was a L2Character
if(oldTarget instanceof L2Character)
{
((L2Character) oldTarget).removeStatusListener(this);
}
}
oldTarget = null;
// Add the L2PcInstance to the _statusListener of the new target if it's a L2Character
if(newTarget != null && newTarget instanceof L2Character)
{
((L2Character) newTarget).addStatusListener(this);
TargetSelected my = new TargetSelected(getObjectId(), newTarget.getObjectId(), getX(), getY(), getZ());
broadcastPacket(my);
my = null;
}
// Target the new L2Object (add the target to the L2PcInstance _target, _knownObject and L2PcInstance to _KnownObject of the L2Object)
super.setTarget(newTarget);
}
/**
* Return the active weapon instance (always equiped in the right hand).<BR>
* <BR>
*
* @return the active weapon instance
*/
@Override
public L2ItemInstance getActiveWeaponInstance()
{
return getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
}
/**
* Return the active weapon item (always equiped in the right hand).<BR>
* <BR>
*
* @return the active weapon item
*/
@Override
public L2Weapon getActiveWeaponItem()
{
L2ItemInstance weapon = getActiveWeaponInstance();
if(weapon == null)
return getFistsWeaponItem();
return (L2Weapon) weapon.getItem();
}
/**
* Gets the chest armor instance.
*
* @return the chest armor instance
*/
public L2ItemInstance getChestArmorInstance()
{
return getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST);
}
/**
* Gets the legs armor instance.
*
* @return the legs armor instance
*/
public L2ItemInstance getLegsArmorInstance()
{
return getInventory().getPaperdollItem(Inventory.PAPERDOLL_LEGS);
}
/**
* Gets the active chest armor item.
*
* @return the active chest armor item
*/
public L2Armor getActiveChestArmorItem()
{
L2ItemInstance armor = getChestArmorInstance();
if(armor == null)
return null;
return (L2Armor) armor.getItem();
}
/**
* Gets the active legs armor item.
*
* @return the active legs armor item
*/
public L2Armor getActiveLegsArmorItem()
{
L2ItemInstance legs = getLegsArmorInstance();
if (legs == null)
return null;
return (L2Armor) legs.getItem();
}
/**
* Checks if is wearing heavy armor.
*
* @return true, if is wearing heavy armor
*/
public boolean isWearingHeavyArmor()
{
L2ItemInstance legs = getLegsArmorInstance();
L2ItemInstance armor = getChestArmorInstance();
if (armor != null && legs != null)
{
if ((L2ArmorType)legs.getItemType() == L2ArmorType.HEAVY
&& ((L2ArmorType)armor.getItemType() == L2ArmorType.HEAVY))
return true;
}
if (armor != null)
{
if ((getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST).getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR
&& (L2ArmorType)armor.getItemType() == L2ArmorType.HEAVY))
return true;
}
return false;
}
/**
* Checks if is wearing light armor.
*
* @return true, if is wearing light armor
*/
public boolean isWearingLightArmor()
{
L2ItemInstance legs = getLegsArmorInstance();
L2ItemInstance armor = getChestArmorInstance();
if (armor != null && legs != null)
{
if ((L2ArmorType)legs.getItemType() == L2ArmorType.LIGHT
&& ((L2ArmorType)armor.getItemType() == L2ArmorType.LIGHT))
return true;
}
if (armor != null)
{
if ((getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST).getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR
&& (L2ArmorType)armor.getItemType() == L2ArmorType.LIGHT))
return true;
}
return false;
}
/**
* Checks if is wearing magic armor.
*
* @return true, if is wearing magic armor
*/
public boolean isWearingMagicArmor()
{
L2ItemInstance legs = getLegsArmorInstance();
L2ItemInstance armor = getChestArmorInstance();
if (armor != null && legs != null)
{
if ((L2ArmorType)legs.getItemType() == L2ArmorType.MAGIC
&& ((L2ArmorType)armor.getItemType() == L2ArmorType.MAGIC))
return true;
}
if (armor != null)
{
if ((getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST).getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR
&& (L2ArmorType)armor.getItemType() == L2ArmorType.MAGIC))
return true;
}
return false;
}
/**
* Checks if is wearing formal wear.
*
* @return true, if is wearing formal wear
*/
public boolean isWearingFormalWear()
{
return _IsWearingFormalWear;
}
/**
* Sets the checks if is wearing formal wear.
*
* @param value the new checks if is wearing formal wear
*/
public void setIsWearingFormalWear(boolean value)
{
_IsWearingFormalWear = value;
}
/**
* Checks if is married.
*
* @return true, if is married
*/
public boolean isMarried()
{
return _married;
}
/**
* Sets the married.
*
* @param state the new married
*/
public void setMarried(boolean state)
{
_married = state;
}
/**
* Married type.
*
* @return the int
*/
public int marriedType()
{
return _marriedType;
}
/**
* Sets the married type.
*
* @param type the new married type
*/
public void setmarriedType(int type)
{
_marriedType = type;
}
/**
* Checks if is engage request.
*
* @return true, if is engage request
*/
public boolean isEngageRequest()
{
return _engagerequest;
}
/**
* Sets the engage request.
*
* @param state the state
* @param playerid the playerid
*/
public void setEngageRequest(boolean state, int playerid)
{
_engagerequest = state;
_engageid = playerid;
}
/**
* Sets the mary request.
*
* @param state the new mary request
*/
public void setMaryRequest(boolean state)
{
_marryrequest = state;
}
/**
* Checks if is mary request.
*
* @return true, if is mary request
*/
public boolean isMaryRequest()
{
return _marryrequest;
}
/**
* Sets the marry accepted.
*
* @param state the new marry accepted
*/
public void setMarryAccepted(boolean state)
{
_marryaccepted = state;
}
/**
* Checks if is marry accepted.
*
* @return true, if is marry accepted
*/
public boolean isMarryAccepted()
{
return _marryaccepted;
}
/**
* Gets the engage id.
*
* @return the engage id
*/
public int getEngageId()
{
return _engageid;
}
/**
* Gets the partner id.
*
* @return the partner id
*/
public int getPartnerId()
{
return _partnerId;
}
/**
* Sets the partner id.
*
* @param partnerid the new partner id
*/
public void setPartnerId(int partnerid)
{
_partnerId = partnerid;
}
/**
* Gets the couple id.
*
* @return the couple id
*/
public int getCoupleId()
{
return _coupleId;
}
/**
* Sets the couple id.
*
* @param coupleId the new couple id
*/
public void setCoupleId(int coupleId)
{
_coupleId = coupleId;
}
/**
* Engage answer.
*
* @param answer the answer
*/
public void EngageAnswer(int answer)
{
if(!_engagerequest)
return;
else if(_engageid == 0)
return;
else
{
L2PcInstance ptarget = (L2PcInstance) L2World.getInstance().findObject(_engageid);
setEngageRequest(false, 0);
if(ptarget != null)
{
if(answer == 1)
{
CoupleManager.getInstance().createCouple(ptarget, L2PcInstance.this);
ptarget.sendMessage("Request to Engage has been >ACCEPTED<");
}
else
{
ptarget.sendMessage("Request to Engage has been >DENIED<!");
}
ptarget = null;
}
}
}
/**
* Return the secondary weapon instance (always equiped in the left hand).<BR>
* <BR>
*
* @return the secondary weapon instance
*/
@Override
public L2ItemInstance getSecondaryWeaponInstance()
{
return getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
}
/**
* Return the secondary weapon item (always equiped in the left hand) or the fists weapon.<BR>
* <BR>
*
* @return the secondary weapon item
*/
@Override
public L2Weapon getSecondaryWeaponItem()
{
L2ItemInstance weapon = getSecondaryWeaponInstance();
if(weapon == null)
return getFistsWeaponItem();
L2Item item = weapon.getItem();
if(item instanceof L2Weapon)
return (L2Weapon) item;
weapon = null;
return null;
}
/**
* Kill the L2Character, Apply Death Penalty, Manage gain/loss Karma and Item Drop.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Reduce the Experience of the L2PcInstance in function of the calculated Death Penalty</li> <li>If necessary, unsummon the Pet of the killed L2PcInstance</li> <li>Manage Karma gain for attacker and Karam loss for the killed L2PcInstance</li> <li>If the killed L2PcInstance has Karma, manage
* Drop Item</li> <li>Kill the L2PcInstance</li><BR>
* <BR>
* @param killer the killer
* @return true, if successful
*/
@Override
public boolean doDie(L2Character killer)
{
if (Config.TW_RESS_ON_DIE)
{
int x1, y1, z1;
x1 = getX();
y1 = getY();
z1 = getZ();
L2TownZone Town;
Town = TownManager.getInstance().getTown(x1, y1, z1);
if (Town != null && isinTownWar())
{
if (Town.getTownId() == Config.TW_TOWN_ID && !Config.TW_ALL_TOWNS)
{
reviveRequest(this, null, false);
}
else if (Config.TW_ALL_TOWNS)
{
reviveRequest(this, null, false);
}
}
}
// Kill the L2PcInstance
if (!super.doDie(killer))
return false;
Castle castle = null;
if (getClan() != null)
{
castle = CastleManager.getInstance().getCastleByOwner(getClan());
if (castle != null)
{
castle.destroyClanGate();
castle = null;
}
}
if (killer != null)
{
final L2PcInstance pk = killer.getActingPlayer();
if (pk != null)
{
if (Config.ENABLE_PK_INFO)
{
doPkInfo(pk);
}
if (LastManStanding.isActive())
{
if(isInLMS() && ((L2PcInstance) killer).isInLMS())
{
setTeam(0);
sendMessage("You have been killed and is now out of the event. Thank you for participating.");
sendMessage("You can watch the event with the Broadcasting Tower in the lobby.");
ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
{
@Override
public void run()
{
teleToLocation(MapRegionTable.TeleportWhereType.Town);
if(isDead())
{
doRevive();
}
}
}, 10000);
}
LastManStanding.joined--;
switch(LastManStanding.joined)
{
case 2:
{
for (L2PcInstance player : LastManStanding.players)
player.sendMessage("There are only two players left! Now its 1 versus 1");
break;
}
case 1:
{
LastManStanding.winner = (L2PcInstance) killer;
for (L2PcInstance player : LastManStanding.players)
player.sendMessage(LastManStanding.winner + " is the winner of the event.");
LastManStanding.endAndReward();
break;
}
}
}
if (atEvent)
{
pk.kills.add(getName());
}
if (_inEventTvT && pk._inEventTvT)
{
if (TvT.is_teleport() || TvT.is_started())
{
if (!(pk._teamNameTvT.equals(_teamNameTvT)))
{
PlaySound ps = new PlaySound(0, "ItemSound.quest_itemget", 1, getObjectId(), getX(), getY(), getZ());
_countTvTdies++;
pk._countTvTkills++;
pk.setTitle("Kills: " + pk._countTvTkills);
pk.sendPacket(ps);
pk.broadcastUserInfo();
TvT.setTeamKillsCount(pk._teamNameTvT, TvT.teamKillsCount(pk._teamNameTvT) + 1);
pk.broadcastUserInfo();
}
else
{
pk.sendMessage("You are a teamkiller !!! Teamkills not counting.");
}
sendMessage("You will be revived and teleported to team spot in " + Config.TVT_REVIVE_DELAY / 1000 + " seconds!");
ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
{
@Override
public void run()
{
teleToLocation(TvT._teamsX.get(TvT._teams.indexOf(_teamNameTvT)) + Rnd.get(201) - 100, TvT._teamsY.get(TvT._teams.indexOf(_teamNameTvT)) + Rnd.get(201) - 100, TvT._teamsZ.get(TvT._teams.indexOf(_teamNameTvT)), false);
doRevive();
}
}, Config.TVT_REVIVE_DELAY);
}
}
else if (_inEventTvT)
{
if (TvT.is_teleport() || TvT.is_started())
{
sendMessage("You will be revived and teleported to team spot in " + Config.TVT_REVIVE_DELAY / 1000 + " seconds!");
ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
{
@Override
public void run()
{
teleToLocation(TvT._teamsX.get(TvT._teams.indexOf(_teamNameTvT)), TvT._teamsY.get(TvT._teams.indexOf(_teamNameTvT)), TvT._teamsZ.get(TvT._teams.indexOf(_teamNameTvT)), false);
doRevive();
broadcastPacket(new SocialAction(getObjectId(), 15));
}
}, Config.TVT_REVIVE_DELAY);
}
}
else if (_inEventCTF)
{
if (CTF.is_teleport() || CTF.is_started())
{
sendMessage("You will be revived and teleported to team flag in 20 seconds!");
if (_haveFlagCTF)
removeCTFFlagOnDie();
ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
{
@Override
public void run()
{
teleToLocation(CTF._teamsX.get(CTF._teams.indexOf(_teamNameCTF)), CTF._teamsY.get(CTF._teams.indexOf(_teamNameCTF)), CTF._teamsZ.get(CTF._teams.indexOf(_teamNameCTF)), false);
doRevive();
}
}, 20000);
}
}
else if (_inEventDM && pk._inEventDM)
{
if (DM.is_teleport() || DM.is_started())
{
pk._countDMkills++;
PlaySound ps = new PlaySound(0, "ItemSound.quest_itemget", 1, getObjectId(), getX(), getY(), getZ());
pk.setTitle("Kills: " + pk._countDMkills);
pk.sendPacket(ps);
pk.broadcastUserInfo();
if (Config.DM_ENABLE_KILL_REWARD)
{
L2Item reward = ItemTable.getInstance().getTemplate(Config.DM_KILL_REWARD_ID);
pk.getInventory().addItem("DM Kill Reward", Config.DM_KILL_REWARD_ID, Config.DM_KILL_REWARD_AMOUNT, this, null);
pk.sendMessage("You have earned " + Config.DM_KILL_REWARD_AMOUNT + " item(s) of ID " + reward.getName() + ".");
}
sendMessage("You will be revived and teleported to spot in 20 seconds!");
ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
{
@Override
public void run()
{
doRevive();
}
}, Config.DM_REVIVE_DELAY);
}
}
else if (_inEventDM)
{
if (DM.is_teleport() || DM.is_started())
{
sendMessage("You will be revived and teleported to spot in 20 seconds!");
ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
{
@Override
public void run()
{
doRevive();
}
}, 20000);
}
}
else if (_inEventRaid)
{
if (Raid._teleport || Raid._started)
{
sendMessage("You will be revived and teleported to team spot in 10 seconds!");
ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
{
@Override
public void run()
{
doRevive();
teleToLocation(Raid._startX, Raid._startY, Raid._startZ, false);
}
}, 10000);
}
}
else if (_inEventVIP && VIP._started)
{
if (_isTheVIP && !pk._inEventVIP)
{
Announcements.getInstance().announceToAll("VIP Killed by non-event character. VIP going back to initial spawn.");
doRevive();
teleToLocation(VIP._startX, VIP._startY, VIP._startZ);
}
else
{
if (_isTheVIP && pk._inEventVIP)
{
VIP.vipDied();
}
else
{
sendMessage("You will be revived and teleported to team spot in 20 seconds!");
ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
{
@Override
public void run()
{
doRevive();
if (_isVIP)
teleToLocation(VIP._startX, VIP._startY, VIP._startZ);
else
teleToLocation(VIP._endX, VIP._endY, VIP._endZ);
}
}, 20000);
}
}
broadcastUserInfo();
}
}
else if (_inEventRaid)
{
if (Raid._teleport || Raid._started)
{
sendMessage("You will be revived and teleported to team spot in 10 seconds!");
ThreadPoolManager.getInstance().scheduleGeneral(new Runnable()
{
@Override
public void run()
{
doRevive();
teleToLocation(Raid._startX, Raid._startY, Raid._startZ, false);
}
}, 10000);
}
}
// Clear resurrect xp calculation
setExpBeforeDeath(0);
if (isCursedWeaponEquiped())
{
CursedWeaponsManager.getInstance().drop(_cursedWeaponEquipedId, killer);
}
else
{
if (pk == null || !pk.isCursedWeaponEquiped())
{
// if (getKarma() > 0)
onDieDropItem(killer); // Check if any item should be dropped
if (!(isInsideZone(ZONE_CHAOTIC) || !(isInsideZone(ZONE_EVENT) || !(isInsideZone(ZONE_PVP) && !isInsideZone(ZONE_SIEGE)))))
{
if ((pk != null) && pk.getClan() != null && getClan() != null && !isAcademyMember() && !pk.isAcademyMember() && _clan.isAtWarWith(pk.getClanId()) && pk.getClan().isAtWarWith(_clan.getClanId()))
{
if (getClan().getReputationScore() > 0)
{
pk.getClan().setReputationScore(((L2PcInstance) killer).getClan().getReputationScore() + 2, true);
pk.getClan().broadcastToOnlineMembers(new PledgeShowInfoUpdate(pk.getClan())); // Update status to all members
}
if (pk.getClan().getReputationScore() > 0)
{
_clan.setReputationScore(_clan.getReputationScore() - 2, true);
_clan.broadcastToOnlineMembers(new PledgeShowInfoUpdate(_clan)); // Update status to all members
}
}
if (Config.ALT_GAME_DELEVEL)
{
// Reduce the Experience of the L2PcInstance in function of the calculated Death Penalty
// NOTE: deathPenalty +- Exp will update karma
if (getSkillLevel(L2Skill.SKILL_LUCKY) < 0 || getStat().getLevel() > 9)
{
deathPenalty((pk != null && getClan() != null && pk.getClan() != null && pk.getClan().isAtWarWith(getClanId())));
}
}
else
{
onDieUpdateKarma(); // Update karma if delevel is not allowed
}
}
}
}
}
// Unsummon Cubics
unsummonAllCubics();
if (_forceBuff != null)
{
abortCast();
}
for (L2Character character : getKnownList().getKnownCharacters())
if (character.getTarget() == this)
{
if (character.isCastingNow())
character.abortCast();
}
if (isInParty() && getParty().isInDimensionalRift())
{
getParty().getDimensionalRift().getDeadMemberList().add(this);
}
// calculate death penalty buff
calculateDeathPenaltyBuffLevel(killer);
stopRentPet();
stopWaterTask();
quakeSystem = 0;
// leave war legend aura if enabled
heroConsecutiveKillCount = 0;
if (Config.WAR_LEGEND_AURA && !_hero && isPVPHero)
{
setHeroAura(false);
this.sendMessage("You leaved War Legend State");
}
// Refresh focus force like L2OFF
sendPacket(new EtcStatusUpdate(this));
return true;
}
/**
* Removes the ctf flag on die.
*/
public void removeCTFFlagOnDie()
{
CTF._flagsTaken.set(CTF._teams.indexOf(_teamNameHaveFlagCTF), false);
CTF.spawnFlag(_teamNameHaveFlagCTF);
CTF.removeFlagFromPlayer(this);
broadcastUserInfo();
_haveFlagCTF = false;
Announcements.getInstance().gameAnnounceToAll(CTF.get_eventName() + "(CTF): " + _teamNameHaveFlagCTF + "'s flag returned.");
}
/**
* On die drop item.
*
* @param killer the killer
*/
private void onDieDropItem(L2Character killer)
{
if(atEvent || (TvT.is_started() && _inEventTvT) || (DM.is_started() && _inEventDM) || (CTF.is_started() && _inEventCTF) || (VIP._started && _inEventVIP) || killer == null)
return;
if ((Raid._started && _inEventRaid))
{
return;
}
if (isInsideZone(ZONE_CHAOTIC))
{
return;
}
if (isInsideZone(ZONE_EVENT))
{
return;
}
if(getKarma() <= 0 && killer instanceof L2PcInstance && ((L2PcInstance) killer).getClan() != null && getClan() != null && ((L2PcInstance) killer).getClan().isAtWarWith(getClanId()))
//|| this.getClan().isAtWarWith(((L2PcInstance)killer).getClanId()))
return;
if(!isInsideZone(ZONE_PVP) && (!isGM() || Config.KARMA_DROP_GM))
{
boolean isKarmaDrop = false;
boolean isKillerNpc = killer instanceof L2NpcInstance;
int pkLimit = Config.KARMA_PK_LIMIT;
int dropEquip = 0;
int dropEquipWeapon = 0;
int dropItem = 0;
int dropLimit = 0;
int dropPercent = 0;
if(getKarma() > 0 && getPkKills() >= pkLimit)
{
isKarmaDrop = true;
dropPercent = Config.KARMA_RATE_DROP;
dropEquip = Config.KARMA_RATE_DROP_EQUIP;
dropEquipWeapon = Config.KARMA_RATE_DROP_EQUIP_WEAPON;
dropItem = Config.KARMA_RATE_DROP_ITEM;
dropLimit = Config.KARMA_DROP_LIMIT;
}
else if(isKillerNpc && getLevel() > 4 && !isFestivalParticipant())
{
dropPercent = Config.PLAYER_RATE_DROP;
dropEquip = Config.PLAYER_RATE_DROP_EQUIP;
dropEquipWeapon = Config.PLAYER_RATE_DROP_EQUIP_WEAPON;
dropItem = Config.PLAYER_RATE_DROP_ITEM;
dropLimit = Config.PLAYER_DROP_LIMIT;
}
int dropCount = 0;
while(dropPercent > 0 && Rnd.get(100) < dropPercent && dropCount < dropLimit)
{
int itemDropPercent = 0;
List<Integer> nonDroppableList = new FastList<Integer>();
List<Integer> nonDroppableListPet = new FastList<Integer>();
nonDroppableList = Config.KARMA_LIST_NONDROPPABLE_ITEMS;
nonDroppableListPet = Config.KARMA_LIST_NONDROPPABLE_ITEMS;
for(L2ItemInstance itemDrop : getInventory().getItems())
{
// Don't drop
if(itemDrop.isAugmented() || // Dont drop augmented items
itemDrop.isShadowItem() || // Dont drop Shadow Items
itemDrop.getItemId() == 57 || // Adena
itemDrop.getItem().getType2() == L2Item.TYPE2_QUEST || // Quest Items
nonDroppableList.contains(itemDrop.getItemId()) || // Item listed in the non droppable item list
nonDroppableListPet.contains(itemDrop.getItemId()) || // Item listed in the non droppable pet item list
getPet() != null && getPet().getControlItemId() == itemDrop.getItemId() // Control Item of active pet
)
{
continue;
}
if(itemDrop.isEquipped())
{
// Set proper chance according to Item type of equipped Item
itemDropPercent = itemDrop.getItem().getType2() == L2Item.TYPE2_WEAPON ? dropEquipWeapon : dropEquip;
getInventory().unEquipItemInSlotAndRecord(itemDrop.getEquipSlot());
}
else
{
itemDropPercent = dropItem; // Item in inventory
}
// NOTE: Each time an item is dropped, the chance of another item being dropped gets lesser (dropCount * 2)
if(Rnd.get(100) < itemDropPercent)
{
if(isKarmaDrop)
{
dropItem("DieDrop", itemDrop, killer, true, false);
String text = getName() + " has karma and dropped id = " + itemDrop.getItemId() + ", count = " + itemDrop.getCount();
Log.add(text, "karma_dieDrop");
}
else
{
dropItem("DieDrop", itemDrop, killer, true, true);
String text = getName() + " dropped id = " + itemDrop.getItemId() + ", count = " + itemDrop.getCount();
Log.add(text, "dieDrop");
}
dropCount++;
break;
}
}
}
}
}
/**
* On die update karma.
*/
private void onDieUpdateKarma()
{
// Karma lose for server that does not allow delevel
if(getKarma() > 0)
{
// this formula seems to work relatively well:
// baseKarma * thisLVL * (thisLVL/100)
// Calculate the new Karma of the attacker : newKarma = baseKarma*pkCountMulti*lvlDiffMulti
double karmaLost = Config.KARMA_LOST_BASE;
karmaLost *= getLevel(); // multiply by char lvl
karmaLost *= getLevel() / 100.0; // divide by 0.charLVL
karmaLost = Math.round(karmaLost);
if ( karmaLost < 0 ) karmaLost = 1;
// Decrease Karma of the L2PcInstance and Send it a Server->Client StatusUpdate packet with Karma and PvP Flag if necessary
setKarma(getKarma() - (int) karmaLost);
}
}
/**
* On kill update pvp karma.
* @param target the target
*/
public void onKillUpdatePvPKarma(L2Character target)
{
// Rank PvP System by Masterio
_rankPvpSystemPc.runPvpTask(this, target);
if (target == null)
return;
if (!(target instanceof L2PlayableInstance))
return;
//if ((_inEventCTF && CTF.is_started()) || (_inEventTvT && TvT.is_started()) || (_inEventVIP && VIP._started) || (_inEventDM && DM.is_started() || (_inEventRaid && Raid._started)))
//return;
if (isInLMS())
return;
if (isCursedWeaponEquipped())
{
CursedWeaponsManager.getInstance().increaseKills(_cursedWeaponEquipedId);
// Custom message for time left
// CursedWeapon cw = CursedWeaponsManager.getInstance().getCursedWeapon(_cursedWeaponEquipedId);
// SystemMessage msg = new SystemMessage(SystemMessageId.THERE_IS_S1_HOUR_AND_S2_MINUTE_LEFT_OF_THE_FIXED_USAGE_TIME);
// int timeLeftInHours = (int)(((cw.getTimeLeft()/60000)/60));
// msg.addItemName(_cursedWeaponEquipedId);
// msg.addNumber(timeLeftInHours);
// sendPacket(msg);
return;
}
L2PcInstance targetPlayer = null;
if (target instanceof L2PcInstance)
{
targetPlayer = (L2PcInstance) target;
}
else if (target instanceof L2Summon)
{
targetPlayer = ((L2Summon) target).getOwner();
}
if (targetPlayer == null)
return; // Target player is null
if (targetPlayer == this)
{
targetPlayer = null;
return; // Target player is self
}
if (isCursedWeaponEquiped())
{
CursedWeaponsManager.getInstance().increaseKills(_cursedWeaponEquipedId);
return;
}
// If in duel and you kill (only can kill l2summon), do nothing
if (isInDuel() && targetPlayer.isInDuel())
return;
if (isInsideZone(ZONE_EVENT) || targetPlayer.isInsideZone(ZONE_EVENT))
return;
// If in Arena, do nothing
if (isInsideZone(ZONE_PVP) || targetPlayer.isInsideZone(ZONE_PVP))
{
// Until the zone was a siege zone. Check also if victim was a player. Randomers aren't counted.
if (target instanceof L2PcInstance && getSiegeState() > 0 && targetPlayer.getSiegeState() > 0 && getSiegeState() != targetPlayer.getSiegeState())
{
// Now check clan relations.
final L2Clan killerClan = getClan();
if (killerClan != null)
killerClan.setSiegeKills(killerClan.getSiegeKills() + 1);
final L2Clan targetClan = targetPlayer.getClan();
if (targetClan != null)
targetClan.setSiegeDeaths(targetClan.getSiegeDeaths() + 1);
}
return;
}
// check anti-farm
if (!checkAntiFarm(targetPlayer))
return;
if (this.getHWid() != null && this.getHWid().length() != 0)
{
List<String> players_in_boxes = this.active_boxes_characters;
L2PcInstance pc = null;
for(String character_name: players_in_boxes)
{
pc = L2World.getInstance().getPlayer(character_name);
if (pc != null && targetPlayer.getHWid().equals(pc.getHWid()))
{
this.sendMessage("Farming pvp/pk/rpc points is not allowed!");
return;
}
}
}
if (Config.ANTI_FARM_SUMMON)
{
if (target instanceof L2SummonInstance)
return;
}
// Check if it's pvp
if (checkIfPvP(target) && targetPlayer.getPvpFlag() != 0 || isInsideZone(ZONE_PVP) && targetPlayer.isInsideZone(ZONE_PVP))
{
increasePvpKills();
if (Config.ENABLE_PVP_SKILLS)
{
pvpSkillsSystem();
}
}
else
{
// check about wars
if (targetPlayer.getClan() != null && getClan() != null)
{
if (getClan().isAtWarWith(targetPlayer.getClanId()))
{
if (targetPlayer.getClan().isAtWarWith(getClanId()))
{
// 'Both way war' -> 'PvP Kill'
increasePvpKills();
if (target instanceof L2PcInstance && Config.ANNOUNCE_PVP_KILL)
{
Announcements.getInstance().announceToAll("Player " + getName() + " hunted Player " + target.getName());
}
else if (target instanceof L2PcInstance && Config.ANNOUNCE_ALL_KILL)
{
Announcements.getInstance().announceToAll("Player " + getName() + " killed Player " + target.getName());
}
addItemReward(targetPlayer);
return;
}
}
}
// 'No war' or 'One way war' -> 'Normal PK'
if (!(_inEventTvT && TvT.is_started()) || !(_inEventCTF && CTF.is_started()) || !(_inEventVIP && VIP._started) || !(_inEventDM && DM.is_started()))
{
if (targetPlayer.getKarma() > 0) // Target player has karma
{
if (Config.KARMA_AWARD_PK_KILL)
{
increasePvpKills();
}
if (target instanceof L2PcInstance && Config.ANNOUNCE_PVP_KILL)
{
Announcements.getInstance().announceToAll("Player " + getName() + " hunted Player " + target.getName());
}
}
else if (targetPlayer.getPvpFlag() == 0) // Target player doesn't have karma
{
increasePkKillsAndKarma(targetPlayer.getLevel());
if (target instanceof L2PcInstance && Config.ANNOUNCE_PK_KILL)
{
Announcements.getInstance().announceToAll("Player " + getName() + " has assassinated Player " + target.getName());
}
}
}
}
if (target instanceof L2PcInstance && Config.ANNOUNCE_ALL_KILL)
{
Announcements.getInstance().announceToAll("Player " + getName() + " killed Player " + target.getName());
}
if (_inEventDM && DM.is_started())
{
return;
}
if (targetPlayer.getObjectId() == _lastKill)
{
count += 1;
}
else
{
count = 1;
_lastKill = targetPlayer.getObjectId();
}
if (Config.REWARD_PROTECT == 0 || count <= Config.REWARD_PROTECT)
{
addItemReward(targetPlayer);
}
}
/**
* Check anti farm.
*
* @param targetPlayer the target player
* @return true, if successful
*/
private boolean checkAntiFarm(L2PcInstance targetPlayer)
{
if(Config.ANTI_FARM_ENABLED)
{
//Anti FARM Clan - Ally
if(Config.ANTI_FARM_CLAN_ALLY_ENABLED && (getClanId() > 0 && targetPlayer.getClanId() > 0 && getClanId() == targetPlayer.getClanId()) || (getAllyId() > 0 && targetPlayer.getAllyId() > 0 && getAllyId() == targetPlayer.getAllyId()))
{
_log.warning("PVP POINT FARM ATTEMPT, " + this.getName() + " and " + targetPlayer.getName() +". CLAN or ALLY.");
return false;
}
//Anti FARM level player < 40
if(Config.ANTI_FARM_LVL_DIFF_ENABLED && targetPlayer.getLevel() < Config.ANTI_FARM_MAX_LVL_DIFF)
{
this.sendMessage("Farm is punishable with Ban! Don't kill new players! Gm informed.");
_log.warning("PVP POINT FARM ATTEMPT, " + this.getName() + " and " + targetPlayer.getName() +". LVL DIFF.");
return false;
}
//Anti FARM pdef < 300
if(Config.ANTI_FARM_PDEF_DIFF_ENABLED && targetPlayer.getPDef(targetPlayer) < Config.ANTI_FARM_MAX_PDEF_DIFF)
{
this.sendMessage("Farm is punishable with Ban! Gm informed.");
_log.warning("PVP POINT FARM ATTEMPT, " + this.getName() + " and " + targetPlayer.getName() +". MAX PDEF DIFF.");
return false;
}
//Anti FARM p atk < 300
if(Config.ANTI_FARM_PATK_DIFF_ENABLED && targetPlayer.getPAtk(targetPlayer) < Config.ANTI_FARM_MAX_PATK_DIFF)
{
this.sendMessage("Farm is punishable with Ban! Gm informed.");
_log.warning("PVP POINT FARM ATTEMPT, " + this.getName() + " and " + targetPlayer.getName() +". MAX PATK DIFF.");
return false;
}
//Anti FARM Party
if(Config.ANTI_FARM_PARTY_ENABLED && this.getParty() != null
&& targetPlayer.getParty() != null
&& this.getParty().equals(targetPlayer.getParty()))
{
_log.warning("PVP POINT FARM ATTEMPT, " + this.getName() + " and " + targetPlayer.getName() +". SAME PARTY.");
return false;
}
//Anti FARM same Ip
if(Config.ANTI_FARM_IP_ENABLED){
if(this.getClient() != null && targetPlayer.getClient() != null)
{
String ip1 = this.getClient().getConnection().getInetAddress().getHostAddress();
String ip2 = targetPlayer.getClient().getConnection().getInetAddress().getHostAddress();
if (ip1.equals(ip2))
{
_log.warning("PVP POINT FARM ATTEMPT: " + this.getName() + " and " + targetPlayer.getName() +". SAME IP.");
return false;
}
}
}
return true;
}
return true;
}
/**
* Adds the item reword.
* @param targetPlayer the target player
*/
private void addItemReward(L2PcInstance targetPlayer)
{
// IP check
if (targetPlayer.getClient() != null && targetPlayer.getClient().getConnection() != null)
{
if (targetPlayer.getClient().getConnection().getInetAddress() != getClient().getConnection().getInetAddress())
{
if (targetPlayer.getKarma() > 0 || targetPlayer.getPvpFlag() > 0) // killing target pk or in pvp
{
if (Config.PVP_REWARD_ENABLED)
{
int item = Config.PVP_REWARD_ID;
L2Item reward = ItemTable.getInstance().getTemplate(item);
int amount = Config.PVP_REWARD_AMOUNT;
getInventory().addItem("Winning PvP", Config.PVP_REWARD_ID, Config.PVP_REWARD_AMOUNT, this, null);
sendMessage("You have earned " + amount + " item(s) of " + reward.getName() + ".");
}
if (!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
iu.addItem(_inventory.getItemByItemId(Config.PVP_REWARD_ID));
sendPacket(iu);
iu = null;
}
}
else
// target is not pk and not in pvp ---> PK KILL
{
if (Config.PK_REWARD_ENABLED)
{
int item = Config.PK_REWARD_ID;
L2Item reward = ItemTable.getInstance().getTemplate(item);
int amount = Config.PK_REWARD_AMOUNT;
getInventory().addItem("Winning PK", Config.PK_REWARD_ID, Config.PK_REWARD_AMOUNT, this, null);
sendMessage("You have earned " + amount + " item(s) of " + reward.getName() + ".");
}
if (!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
iu.addItem(_inventory.getItemByItemId(Config.PK_REWARD_ID));
sendPacket(iu);
iu = null;
}
}
}
else
{
this.sendMessage("Farm is punishable with Ban! Don't kill your Box!");
_log.warning("PVP POINT FARM ATTEMPT: " + this.getName() + " and " + targetPlayer.getName() + ". SAME IP.");
}
}
}
/**
* Increase the pvp kills count and send the info to the player.
*/
public void increasePvpKills()
{
int x,y,z;
x = getX();
y = getY();
z = getZ();
L2TownZone Town;
Town = TownManager.getInstance().getTown(x,y,z);
if(Town != null && isinTownWar())
{
if(Town.getTownId() == Config.TW_TOWN_ID && !Config.TW_ALL_TOWNS)
{
getInventory().addItem("TownWar", Config.TW_ITEM_ID, Config.TW_ITEM_AMOUNT, this, this);
sendMessage("You received your prize for a town war kill!");
}
else if(Config.TW_ALL_TOWNS)
{
getInventory().addItem("TownWar", Config.TW_ITEM_ID, Config.TW_ITEM_AMOUNT, this, this);
sendMessage("You received your prize for a town war kill!");
}
}
if((TvT.is_started() && _inEventTvT) || (DM.is_started() && _inEventDM) || (CTF.is_started() && _inEventCTF) || (VIP._started && _inEventVIP))
{
setPvpKills(getPvpKills() + 1);
}
// Add karma to attacker and increase its PK counter
if(!RankPvpSystemConfig.LEGAL_COUNTER_ALTT_ENABLED)
setPvpKills(getPvpKills() + 1);
// Increase the kill count for a special hero aura
heroConsecutiveKillCount++;
// If heroConsecutiveKillCount == 30 give hero aura
if(heroConsecutiveKillCount == Config.KILLS_TO_GET_WAR_LEGEND_AURA && Config.WAR_LEGEND_AURA)
{
setHeroAura(true);
Announcements.getInstance().gameAnnounceToAll(getName()+" becames War Legend with "+Config.KILLS_TO_GET_WAR_LEGEND_AURA+" PvP!!");
}
if(Config.PVPEXPSP_SYSTEM)
{
addExpAndSp(Config.ADD_EXP, Config.ADD_SP);
{
sendMessage("Earned Exp & SP for a pvp kill");
}
}
if(Config.PVP_PK_TITLE)
{
updateTitle();
}
//Update the character's name color if they reached any of the 5 PvP levels.
updatePvPColor(getPvpKills());
broadcastUserInfo();
QuakeSystem();
// Send a Server->Client UserInfo packet to attacker with its Karma and PK Counter
sendPacket(new UserInfo(this));
}
/**
* Quake system.
*/
public void QuakeSystem()
{
quakeSystem++;
switch (quakeSystem)
{
case 3:
{
Announcements.getInstance().announceToAll(""+ getName() + " is Killing Spree!",true);
}
break;
case 5:
{
Announcements.getInstance().announceToAll(""+ getName() + " is Unstoppable!!",true);
}
break;
case 8:
{
Announcements.getInstance().announceToAll(""+ getName() + " is Owning!",true);
}
break;
case 10:
{
Announcements.getInstance().announceToAll(""+ getName() + " is on Rampage!",true);
}
break;
case 12:
{
Announcements.getInstance().announceToAll(""+ getName() + " is on a Monster Kill!",true);
}
break;
case 15:
{
Announcements.getInstance().announceToAll(""+ getName() + " is on an Ultra Kill!",true);
}
break;
case 20:
{
Announcements.getInstance().announceToAll(""+ getName() + " is Wicked Sick!",true);
}
break;
case 25:
{
Announcements.getInstance().announceToAll(""+ getName() + " is Godlike!",true);
}
break;
case 30:
{
Announcements.getInstance().announceToAll(""+ getName() + " is Beyond Godlike!",true);
}
break;
}
}
/**
* Get info on pk's from pk table.
*
* @param PlayerWhoKilled the player who killed
*/
public void doPkInfo(L2PcInstance PlayerWhoKilled)
{
String killer = PlayerWhoKilled.getName();
String killed = getName();
int kills = 0;
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement("SELECT kills FROM pkkills WHERE killerId=? AND killedId=?");
statement.setString(1, killer);
statement.setString(2, killed);
final ResultSet rset = statement.executeQuery();
if (rset.next())
{
kills = rset.getInt("kills");
}
rset.close();
statement.close();
}
catch(SQLException e)
{
e.printStackTrace();
}
finally
{
CloseUtil.close(con);
}
if(kills >= 1)
{
kills++;
String UPDATE_PKKILLS = "UPDATE pkkills SET kills=? WHERE killerId=? AND killedId=?";
Connection conect = null;
try
{
conect = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = conect.prepareStatement(UPDATE_PKKILLS);
statement.setInt(1, kills);
statement.setString(2, killer);
statement.setString(3, killed);
statement.execute();
statement.close();
statement = null;
UPDATE_PKKILLS = null;
}
catch(SQLException e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
System.out.println("Could not update pkKills, got: " + e.getMessage());
}
finally
{
CloseUtil.close(conect);
conect = null;
}
sendMessage("You have been killed " + kills + " times by " + PlayerWhoKilled.getName() + ".");
PlayerWhoKilled.sendMessage("You have killed " + getName() + " " + kills + " times.");
}
else
{
String ADD_PKKILLS = "INSERT INTO pkkills (killerId,killedId,kills) VALUES (?,?,?)";
Connection conect2 = null;
try
{
conect2 = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = conect2.prepareStatement(ADD_PKKILLS);
statement.setString(1, killer);
statement.setString(2, killed);
statement.setInt(3, 1);
statement.execute();
statement.close();
ADD_PKKILLS = null;
statement = null;
}
catch(SQLException e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
System.out.println("Could not add pkKills, got: " + e.getMessage());
}
finally
{
CloseUtil.close(conect2);
conect2 = null;
}
sendMessage("This is the first time you have been killed by " + PlayerWhoKilled.getName() + ".");
PlayerWhoKilled.sendMessage("You have killed " + getName() + " for the first time.");
}
killer = null;
killed = null;
}
/**
* Increase pk count, karma and send the info to the player.
*
* @param targLVL : level of the killed player
*/
public void increasePkKillsAndKarma(int targLVL)
{
if((TvT.is_started() && _inEventTvT) || (DM.is_started() && _inEventDM) || (CTF.is_started() && _inEventCTF) || (VIP._started && _inEventVIP))
return;
int baseKarma = Config.KARMA_MIN_KARMA;
int newKarma = baseKarma;
int karmaLimit = Config.KARMA_MAX_KARMA;
int pkLVL = getLevel();
int pkPKCount = getPkKills();
int lvlDiffMulti = 0;
int pkCountMulti = 0;
// Check if the attacker has a PK counter greater than 0
if(pkPKCount > 0)
{
pkCountMulti = pkPKCount / 2;
}
else
{
pkCountMulti = 1;
}
if(pkCountMulti < 1)
{
pkCountMulti = 1;
}
// Calculate the level difference Multiplier between attacker and killed L2PcInstance
if(pkLVL > targLVL)
{
lvlDiffMulti = pkLVL / targLVL;
}
else
{
lvlDiffMulti = 1;
}
if(lvlDiffMulti < 1)
{
lvlDiffMulti = 1;
}
// Calculate the new Karma of the attacker : newKarma = baseKarma*pkCountMulti*lvlDiffMulti
newKarma *= pkCountMulti;
newKarma *= lvlDiffMulti;
// Make sure newKarma is less than karmaLimit and higher than baseKarma
if(newKarma < baseKarma)
{
newKarma = baseKarma;
}
if(newKarma > karmaLimit)
{
newKarma = karmaLimit;
}
// Fix to prevent overflow (=> karma has a max value of 2 147 483 647)
if(getKarma() > Integer.MAX_VALUE - newKarma)
{
newKarma = Integer.MAX_VALUE - getKarma();
}
// Add karma to attacker and increase its PK counter
int x,y,z;
x = getX();
y = getY();
z = getZ();
//get local town
L2TownZone Town = TownManager.getInstance().getTown(x,y,z);
setPkKills(getPkKills() + 1);
/*if(!Config.TW_ALLOW_KARMA && Town != null && isinTownWar())
{
//nothing
}
else */
if(Town == null || (isinTownWar() && Config.TW_ALLOW_KARMA))
{
setKarma(getKarma() + newKarma);
}
/*else if()
{
setKarma(getKarma() + newKarma);
}*/
if(Town != null && isinTownWar())
{
if(Town.getTownId() == Config.TW_TOWN_ID && !Config.TW_ALL_TOWNS)
{
getInventory().addItem("TownWar", Config.TW_ITEM_ID, Config.TW_ITEM_AMOUNT, this, this);
sendMessage("You received your prize for a town war kill!");
}
else if(Config.TW_ALL_TOWNS && Town.getTownId() != 0)
{
getInventory().addItem("TownWar", Config.TW_ITEM_ID, Config.TW_ITEM_AMOUNT, this, this);
sendMessage("You received your prize for a town war kill!");
}
}
if(Config.PVP_PK_TITLE)
{
updateTitle();
}
//Update the character's title color if they reached any of the 5 PK levels.
updatePkColor(getPkKills());
broadcastUserInfo();
// Send a Server->Client UserInfo packet to attacker with its Karma and PK Counter
sendPacket(new UserInfo(this));
}
/**
* Calculate karma lost.
*
* @param exp the exp
* @return the int
*/
public int calculateKarmaLost(long exp)
{
// KARMA LOSS
// When a PKer gets killed by another player or a L2MonsterInstance, it loses a certain amount of Karma based on their level.
// this (with defaults) results in a level 1 losing about ~2 karma per death, and a lvl 70 loses about 11760 karma per death...
// You lose karma as long as you were not in a pvp zone and you did not kill urself.
// NOTE: exp for death (if delevel is allowed) is based on the players level
long expGained = Math.abs(exp);
expGained /= Config.KARMA_XP_DIVIDER;
int karmaLost = 0;
if(expGained > Integer.MAX_VALUE)
karmaLost = Integer.MAX_VALUE;
else
karmaLost = (int) expGained;
if (karmaLost < Config.KARMA_LOST_BASE) karmaLost = Config.KARMA_LOST_BASE;
if (karmaLost > getKarma()) karmaLost = getKarma();
return karmaLost;
}
/**
* Update pvp status.
*/
public void updatePvPStatus()
{
if((TvT.is_started() && _inEventTvT) || (CTF.is_started() && _inEventCTF) || (DM.is_started() && _inEventDM) || (VIP._started && _inEventVIP))
return;
if((Raid._started && _inEventRaid))
return;
if(isInsideZone(ZONE_PVP))
return;
if(isInsideZone(ZONE_EVENT))
return;
setPvpFlagLasts(System.currentTimeMillis() + Config.PVP_NORMAL_TIME);
if(getPvpFlag() == 0)
{
startPvPFlag();
}
}
/**
* Update pvp status.
*
* @param target the target
*/
public void updatePvPStatus(L2Character target)
{
L2PcInstance player_target = null;
if(target instanceof L2PcInstance)
{
player_target = (L2PcInstance) target;
}
else if(target instanceof L2Summon)
{
player_target = ((L2Summon) target).getOwner();
}
if(player_target == null)
return;
if((TvT.is_started() && _inEventTvT && player_target._inEventTvT) || (DM.is_started() && _inEventDM && player_target._inEventDM) || (CTF.is_started() && _inEventCTF && player_target._inEventCTF) || (VIP._started && _inEventVIP && player_target._inEventVIP))
return;
if(isInDuel() && player_target.getDuelId() == getDuelId())
return;
if((Raid._started && _inEventRaid))
return;
if(isInsideZone(ZONE_EVENT))
return;
if((!isInsideZone(ZONE_PVP) || !player_target.isInsideZone(ZONE_PVP)) && player_target.getKarma() == 0)
{
if(checkIfPvP(player_target))
{
setPvpFlagLasts(System.currentTimeMillis() + Config.PVP_PVP_TIME);
}
else
{
setPvpFlagLasts(System.currentTimeMillis() + Config.PVP_NORMAL_TIME);
}
if(getPvpFlag() == 0)
{
startPvPFlag();
}
}
player_target = null;
}
/**
* Restore the specified % of experience this L2PcInstance has lost and sends a Server->Client StatusUpdate packet.<BR>
* <BR>
*
* @param restorePercent the restore percent
*/
public void restoreExp(double restorePercent)
{
if(getExpBeforeDeath() > 0)
{
// Restore the specified % of lost experience.
getStat().addExp((int) Math.round((getExpBeforeDeath() - getExp()) * restorePercent / 100));
setExpBeforeDeath(0);
}
}
/**
* Reduce the Experience (and level if necessary) of the L2PcInstance in function of the calculated Death Penalty.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Calculate the Experience loss</li> <li>Set the value of _expBeforeDeath</li> <li>Set the new Experience value
* of the L2PcInstance and Decrease its level if necessary</li> <li>Send a Server->Client StatusUpdate packet with
* its new Experience</li><BR>
* <BR>
*
* @param atwar the atwar
*/
public void deathPenalty(boolean atwar)
{
// Get the level of the L2PcInstance
final int lvl = getLevel();
//The death steal you some Exp
double percentLost = 4.0; //standart 4% (lvl>20)
if(getLevel() < 20)
{
percentLost = 10.0;
}
else if(getLevel() >= 20 && getLevel() < 40)
{
percentLost = 7.0;
}
else if(getLevel() >= 40 && getLevel() < 75)
{
percentLost = 4.0;
}
else if(getLevel() >= 75 && getLevel() < 81)
{
percentLost = 2.0;
}
if(getKarma() > 0)
{
percentLost *= Config.RATE_KARMA_EXP_LOST;
}
if(isFestivalParticipant() || atwar || isInsideZone(ZONE_SIEGE))
{
percentLost /= 4.0;
}
// Calculate the Experience loss
long lostExp = 0;
if (!atEvent && !(_inEventTvT && TvT.is_started()) && !(_inEventDM && DM.is_started()) && !(_inEventCTF && CTF.is_started()) && !(_inEventVIP && VIP._started) && !(_inEventRaid && Raid._started))
{
final byte maxLvl = ExperienceData.getInstance().getMaxLevel();
if(lvl < maxLvl)
{
lostExp = Math.round((getStat().getExpForLevel(lvl + 1) - getStat().getExpForLevel(lvl)) * percentLost / 100);
}
else
{
lostExp = Math.round((getStat().getExpForLevel(maxLvl) - getStat().getExpForLevel(maxLvl - 1)) * percentLost / 100);
}
}
// Get the Experience before applying penalty
setExpBeforeDeath(getExp());
if(getCharmOfCourage())
{
if(getSiegeState() > 0 && isInsideZone(ZONE_SIEGE))
{
lostExp = 0;
}
setCharmOfCourage(false);
}
if(Config.DEBUG)
{
_log.fine(getName() + " died and lost " + lostExp + " experience.");
}
// Set the new Experience value of the L2PcInstance
getStat().addExp(-lostExp);
}
/**
* Manage the increase level task of a L2PcInstance (Max MP, Max MP, Recommandation, Expertise and beginner
* skills...).<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Send a Server->Client System Message to the L2PcInstance : YOU_INCREASED_YOUR_LEVEL</li> <li>Send a
* Server->Client packet StatusUpdate to the L2PcInstance with new LEVEL, MAX_HP and MAX_MP</li> <li>Set the current
* HP and MP of the L2PcInstance, Launch/Stop a HP/MP/CP Regeneration Task and send StatusUpdate packet to all other
* L2PcInstance to inform (exclusive broadcast)</li> <li>Recalculate the party level</li> <li>Recalculate the number
* of Recommandation that the L2PcInstance can give</li> <li>Give Expertise skill of this level and remove beginner
* Lucky skill</li><BR>
* <BR>
*/
public void increaseLevel()
{
// Set the current HP and MP of the L2Character, Launch/Stop a HP/MP/CP Regeneration Task and send StatusUpdate packet to all other L2PcInstance to inform (exclusive broadcast)
setCurrentHpMp(getMaxHp(), getMaxMp());
setCurrentCp(getMaxCp());
}
/**
* Stop the HP/MP/CP Regeneration task.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Set the RegenActive flag to False</li> <li>Stop the HP/MP/CP Regeneration task</li><BR>
* <BR>
*/
public void stopAllTimers()
{
stopHpMpRegeneration();
stopWarnUserTakeBreak();
stopWaterTask();
stopRentPet();
stopPvpRegTask();
stopPunishTask(true);
stopBotChecker();
quakeSystem = 0;
}
/**
* Return the L2Summon of the L2PcInstance or null.<BR>
* <BR>
*
* @return the pet
*/
@Override
public L2Summon getPet()
{
return _summon;
}
/**
* Set the L2Summon of the L2PcInstance.<BR>
* <BR>
*
* @param summon the new pet
*/
public void setPet(L2Summon summon)
{
_summon = summon;
}
/**
* Return the L2Summon of the L2PcInstance or null.<BR>
* <BR>
*
* @return the trained beast
*/
public L2TamedBeastInstance getTrainedBeast()
{
return _tamedBeast;
}
/**
* Set the L2Summon of the L2PcInstance.<BR>
* <BR>
*
* @param tamedBeast the new trained beast
*/
public void setTrainedBeast(L2TamedBeastInstance tamedBeast)
{
_tamedBeast = tamedBeast;
}
/**
* Return the L2PcInstance requester of a transaction (ex : FriendInvite, JoinAlly, JoinParty...).<BR>
* <BR>
*
* @return the request
*/
public L2Request getRequest()
{
return _request;
}
/**
* Set the L2PcInstance requester of a transaction (ex : FriendInvite, JoinAlly, JoinParty...).<BR>
* <BR>
*
* @param requester the new active requester
*/
public synchronized void setActiveRequester(L2PcInstance requester)
{
_activeRequester = requester;
}
/**
* Return the L2PcInstance requester of a transaction (ex : FriendInvite, JoinAlly, JoinParty...).<BR>
* <BR>
*
* @return the active requester
*/
public synchronized L2PcInstance getActiveRequester()
{
L2PcInstance requester = _activeRequester;
if (requester != null)
{
if (requester.isRequestExpired() && _activeTradeList == null)
_activeRequester = null;
}
return _activeRequester;
}
/**
* Return True if a transaction is in progress.<BR>
* <BR>
*
* @return true, if is processing request
*/
public boolean isProcessingRequest()
{
return _activeRequester != null || _requestExpireTime > GameTimeController.getGameTicks();
}
/**
* Return True if a transaction is in progress.<BR>
* <BR>
*
* @return true, if is processing transaction
*/
public boolean isProcessingTransaction()
{
return _activeRequester != null || _activeTradeList != null || _requestExpireTime > GameTimeController.getGameTicks();
}
/**
* Select the Warehouse to be used in next activity.<BR>
* <BR>
*
* @param partner the partner
*/
public void onTransactionRequest(L2PcInstance partner)
{
_requestExpireTime = GameTimeController.getGameTicks() + REQUEST_TIMEOUT * GameTimeController.TICKS_PER_SECOND;
if (partner != null)
{
partner.setActiveRequester(this);
}
}
/**
* Select the Warehouse to be used in next activity.<BR>
* <BR>
*/
public void onTransactionResponse()
{
_requestExpireTime = 0;
}
/**
* Select the Warehouse to be used in next activity.<BR>
* <BR>
*
* @param warehouse the new active warehouse
*/
public void setActiveWarehouse(ItemContainer warehouse)
{
_activeWarehouse = warehouse;
}
/**
* Return active Warehouse.<BR>
* <BR>
*
* @return the active warehouse
*/
public ItemContainer getActiveWarehouse()
{
return _activeWarehouse;
}
/**
* Select the TradeList to be used in next activity.<BR>
* <BR>
*
* @param tradeList the new active trade list
*/
public void setActiveTradeList(TradeList tradeList)
{
_activeTradeList = tradeList;
}
/**
* Return active TradeList.<BR>
* <BR>
*
* @return the active trade list
*/
public TradeList getActiveTradeList()
{
return _activeTradeList;
}
/**
* On trade start.
*
* @param partner the partner
*/
public void onTradeStart(L2PcInstance partner)
{
_activeTradeList = new TradeList(this);
_activeTradeList.setPartner(partner);
SystemMessage msg = new SystemMessage(SystemMessageId.BEGIN_TRADE_WITH_S1);
msg.addString(partner.getName());
sendPacket(msg);
sendPacket(new TradeStart(this));
msg = null;
}
/**
* On trade confirm.
*
* @param partner the partner
*/
public void onTradeConfirm(L2PcInstance partner)
{
SystemMessage msg = new SystemMessage(SystemMessageId.S1_CONFIRMED_TRADE);
msg.addString(partner.getName());
sendPacket(msg);
msg = null;
partner.sendPacket(TradePressOwnOk.STATIC_PACKET);
sendPacket(TradePressOtherOk.STATIC_PACKET);
}
/**
* On trade cancel.
*
* @param partner the partner
*/
public void onTradeCancel(L2PcInstance partner)
{
if(_activeTradeList == null)
return;
_activeTradeList.lock();
_activeTradeList = null;
sendPacket(new SendTradeDone(0));
SystemMessage msg = new SystemMessage(SystemMessageId.S1_CANCELED_TRADE);
msg.addString(partner.getName());
sendPacket(msg);
msg = null;
}
/**
* On trade finish.
*
* @param successfull the successfull
*/
public void onTradeFinish(boolean successfull)
{
_activeTradeList = null;
sendPacket(new SendTradeDone(1));
if(successfull)
{
sendPacket(new SystemMessage(SystemMessageId.TRADE_SUCCESSFUL));
}
}
/**
* Start trade.
*
* @param partner the partner
*/
public void startTrade(L2PcInstance partner)
{
onTradeStart(partner);
partner.onTradeStart(this);
}
/**
* Cancel active trade.
*/
public void cancelActiveTrade()
{
if(_activeTradeList == null)
return;
L2PcInstance partner = _activeTradeList.getPartner();
if(partner != null)
{
partner.onTradeCancel(this);
partner = null;
}
onTradeCancel(this);
}
/**
* Return the _createList object of the L2PcInstance.<BR>
* <BR>
*
* @return the creates the list
*/
public L2ManufactureList getCreateList()
{
return _createList;
}
/**
* Set the _createList object of the L2PcInstance.<BR>
* <BR>
*
* @param x the new creates the list
*/
public void setCreateList(L2ManufactureList x)
{
_createList = x;
}
/**
* Return the _sellList object of the L2PcInstance.<BR>
* <BR>
*
* @return the sell list
*/
public TradeList getSellList()
{
if(_sellList == null)
{
_sellList = new TradeList(this);
}
return _sellList;
}
/**
* Return the _buyList object of the L2PcInstance.<BR>
* <BR>
*
* @return the buy list
*/
public TradeList getBuyList()
{
if(_buyList == null)
{
_buyList = new TradeList(this);
}
return _buyList;
}
/**
* Set the Private Store type of the L2PcInstance.<BR>
* <BR>
* <B><U> Values </U> :</B><BR>
* <BR>
* <li>0 : STORE_PRIVATE_NONE</li>
* <li>1 : STORE_PRIVATE_SELL</li>
* <li>2 : sellmanage</li><BR>
* <li>3 : STORE_PRIVATE_BUY</li><BR>
* <li>4 : buymanage</li><BR>
* <li>5 : STORE_PRIVATE_MANUFACTURE</li><BR>
*
* @param type the new private store type
*/
public void setPrivateStoreType(int type)
{
_privatestore = type;
if (_privatestore == STORE_PRIVATE_NONE && (getClient() == null || isOffline()))
{
/*if(this._originalNameColorOffline!=0)
getAppearance().setNameColor(this._originalNameColorOffline);
else
getAppearance().setNameColor(_accessLevel.getNameColor());
*/
this.store();
if (Config.OFFLINE_DISCONNECT_FINISHED) {
this.deleteMe();
if(this.getClient() != null)
{
this.getClient().setActiveChar(null); // prevent deleteMe from being called a second time on disconnection
}
}
}
}
/**
* Return the Private Store type of the L2PcInstance.<BR>
* <BR>
* <B><U> Values </U> :</B><BR>
* <BR>
* <li>0 : STORE_PRIVATE_NONE</li> <li>1 : STORE_PRIVATE_SELL</li> <li>2 : sellmanage</li><BR>
* <li>3 : STORE_PRIVATE_BUY</li><BR>
* <li>4 : buymanage</li><BR>
* <li>5 : STORE_PRIVATE_MANUFACTURE</li><BR>
*
* @return the private store type
*/
public int getPrivateStoreType()
{
return _privatestore;
}
/**
* Set the _skillLearningClassId object of the L2PcInstance.<BR>
* <BR>
*
* @param classId the new skill learning class id
*/
public void setSkillLearningClassId(ClassId classId)
{
_skillLearningClassId = classId;
}
/**
* Return the _skillLearningClassId object of the L2PcInstance.<BR>
* <BR>
*
* @return the skill learning class id
*/
public ClassId getSkillLearningClassId()
{
return _skillLearningClassId;
}
/**
* Set the _clan object, _clanId, _clanLeader Flag and title of the L2PcInstance.<BR>
* <BR>
*
* @param clan the new clan
*/
public void setClan(L2Clan clan)
{
_clan = clan;
setTitle("");
if(clan == null)
{
_clanId = 0;
_clanPrivileges = 0;
_pledgeType = 0;
_powerGrade = 0;
_lvlJoinedAcademy = 0;
_apprentice = 0;
_sponsor = 0;
return;
}
if(!clan.isMember(getName()))
{
// char has been kicked from clan
setClan(null);
return;
}
_clanId = clan.getClanId();
// Add clan leader skills if clanleader
if(isClanLeader() && clan.getLevel()>= 4)
{
addClanLeaderSkills(true);
}else{
addClanLeaderSkills(false);
}
}
/**
* Return the _clan object of the L2PcInstance.<BR>
* <BR>
*
* @return the clan
*/
public L2Clan getClan()
{
return _clan;
}
/**
* Return True if the L2PcInstance is the leader of its clan.<BR>
* <BR>
*
* @return true, if is clan leader
*/
public boolean isClanLeader()
{
if(getClan() == null)
return false;
return getObjectId() == getClan().getLeaderId();
}
/**
* Reduce the number of arrows owned by the L2PcInstance and send it Server->Client Packet InventoryUpdate or
* ItemList (to unequip if the last arrow was consummed).<BR>
* <BR>
*/
@Override
protected void reduceArrowCount()
{
L2ItemInstance arrows = getInventory().destroyItem("Consume", getInventory().getPaperdollObjectId(Inventory.PAPERDOLL_LHAND), 1, this, null);
if(Config.DEBUG)
{
_log.fine("arrow count:" + (arrows == null ? 0 : arrows.getCount()));
}
if(arrows == null || arrows.getCount() == 0)
{
getInventory().unEquipItemInSlot(Inventory.PAPERDOLL_LHAND);
_arrowItem = null;
if(Config.DEBUG)
{
_log.fine("removed arrows count");
}
sendPacket(new ItemList(this, false));
}
else
{
if(!Config.FORCE_INVENTORY_UPDATE)
{
InventoryUpdate iu = new InventoryUpdate();
iu.addModifiedItem(arrows);
sendPacket(iu);
}
else
{
sendPacket(new ItemList(this, false));
}
arrows = null;
}
}
/**
* Equip arrows needed in left hand and send a Server->Client packet ItemList to the L2PcINstance then return True.<BR>
* <BR>
*
* @return true, if successful
*/
@Override
protected boolean checkAndEquipArrows()
{
// Check if nothing is equiped in left hand
if(getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND) == null)
{
// Get the L2ItemInstance of the arrows needed for this bow
_arrowItem = getInventory().findArrowForBow(getActiveWeaponItem());
if(_arrowItem != null)
{
// Equip arrows needed in left hand
getInventory().setPaperdollItem(Inventory.PAPERDOLL_LHAND, _arrowItem);
// Send a Server->Client packet ItemList to this L2PcINstance to update left hand equipement
ItemList il = new ItemList(this, false);
sendPacket(il);
}
}
else
{
// Get the L2ItemInstance of arrows equiped in left hand
_arrowItem = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
}
return _arrowItem != null;
}
/**
* Disarm the player's weapon and shield.<BR>
* <BR>
*
* @return true, if successful
*/
public boolean disarmWeapons()
{
// Don't allow disarming a cursed weapon
if(isCursedWeaponEquiped() && !getAccessLevel().isGm())
return false;
// Unequip the weapon
L2ItemInstance wpn = getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
if(wpn == null)
{
wpn = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LRHAND);
}
if(wpn != null)
{
if(wpn.isWear())
return false;
// Remove augementation boni on unequip
if(wpn.isAugmented())
{
wpn.getAugmentation().removeBoni(this);
}
L2ItemInstance[] unequiped = getInventory().unEquipItemInBodySlotAndRecord(wpn.getItem().getBodyPart());
InventoryUpdate iu = new InventoryUpdate();
for(L2ItemInstance element : unequiped)
{
iu.addModifiedItem(element);
}
sendPacket(iu);
iu = null;
abortAttack();
broadcastUserInfo();
// this can be 0 if the user pressed the right mousebutton twice very fast
if(unequiped.length > 0)
{
SystemMessage sm = null;
if(unequiped[0].getEnchantLevel() > 0)
{
sm = new SystemMessage(SystemMessageId.EQUIPMENT_S1_S2_REMOVED);
sm.addNumber(unequiped[0].getEnchantLevel());
sm.addItemName(unequiped[0].getItemId());
}
else
{
sm = new SystemMessage(SystemMessageId.S1_DISARMED);
sm.addItemName(unequiped[0].getItemId());
}
sendPacket(sm);
sm = null;
}
wpn = null;
unequiped = null;
}
// Unequip the shield
L2ItemInstance sld = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LHAND);
if(sld != null)
{
if(sld.isWear())
return false;
L2ItemInstance[] unequiped = getInventory().unEquipItemInBodySlotAndRecord(sld.getItem().getBodyPart());
InventoryUpdate iu = new InventoryUpdate();
for(L2ItemInstance element : unequiped)
{
iu.addModifiedItem(element);
}
sendPacket(iu);
iu = null;
abortAttack();
broadcastUserInfo();
// this can be 0 if the user pressed the right mousebutton twice very fast
if(unequiped.length > 0)
{
SystemMessage sm = null;
if(unequiped[0].getEnchantLevel() > 0)
{
sm = new SystemMessage(SystemMessageId.EQUIPMENT_S1_S2_REMOVED);
sm.addNumber(unequiped[0].getEnchantLevel());
sm.addItemName(unequiped[0].getItemId());
}
else
{
sm = new SystemMessage(SystemMessageId.S1_DISARMED);
sm.addItemName(unequiped[0].getItemId());
}
sendPacket(sm);
sm = null;
}
sld = null;
unequiped = null;
}
return true;
}
/**
* Return True if the L2PcInstance use a dual weapon.<BR>
* <BR>
*
* @return true, if is using dual weapon
*/
@Override
public boolean isUsingDualWeapon()
{
L2Weapon weaponItem = getActiveWeaponItem();
if(weaponItem == null)
return false;
if(weaponItem.getItemType() == L2WeaponType.DUAL)
return true;
else if(weaponItem.getItemType() == L2WeaponType.DUALFIST)
return true;
else if(weaponItem.getItemId() == 248) // orc fighter fists
return true;
else if(weaponItem.getItemId() == 252) // orc mage fists
return true;
else
return false;
}
/**
* Sets the uptime.
*
* @param time the new uptime
*/
public void setUptime(long time)
{
_uptime = time;
}
/**
* Gets the uptime.
*
* @return the uptime
*/
public long getUptime()
{
return System.currentTimeMillis() - _uptime;
}
/**
* Return True if the L2PcInstance is invulnerable.<BR>
* <BR>
*
* @return true, if is invul
*/
@Override
public boolean isInvul()
{
return _isInvul || _isTeleporting || _protectEndTime > GameTimeController.getGameTicks() || _teleportProtectEndTime > GameTimeController.getGameTicks();
}
/**
* Return True if the L2PcInstance has a Party in progress.<BR>
* <BR>
*
* @return true, if is in party
*/
@Override
public boolean isInParty()
{
return _party != null;
}
/**
* Set the _party object of the L2PcInstance (without joining it).<BR>
* <BR>
*
* @param party the new party
*/
public void setParty(L2Party party)
{
_party = party;
}
/**
* Set the _party object of the L2PcInstance AND join it.<BR>
* <BR>
*
* @param party the party
*/
public void joinParty(final L2Party party)
{
if(party == null){
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
if(party.getMemberCount()==9){
sendPacket(new SystemMessage(SystemMessageId.PARTY_FULL));
return;
}
if(party.getPartyMembers().contains(this)){
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
if(party.getMemberCount()<9)
{
// First set the party otherwise this wouldn't be considered
// as in a party into the L2Character.updateEffectIcons() call.
_party = party;
party.addPartyMember(this);
}
}
/**
* Return true if the L2PcInstance is a GM.<BR>
* <BR>
*
* @return true, if is gM
*/
public boolean isGM()
{
return getAccessLevel().isGm();
}
/**
* Return true if the L2PcInstance is a Administrator.<BR>
* <BR>
*
* @return true, if is administrator
*/
public boolean isAdministrator()
{
return getAccessLevel().getLevel() == Config.MASTERACCESS_LEVEL;
}
/**
* Return true if the L2PcInstance is a User.<BR>
* <BR>
*
* @return true, if is user
*/
public boolean isUser()
{
return getAccessLevel().getLevel() == Config.USERACCESS_LEVEL;
}
/**
* Checks if is normal gm.
*
* @return true, if is normal gm
*/
public boolean isNormalGm()
{
return !isAdministrator() && !isUser();
}
/**
* Manage the Leave Party task of the L2PcInstance.<BR>
* <BR>
*/
public void leaveParty()
{
if(isInParty())
{
_party.removePartyMember(this);
_party = null;
}
}
/**
* Return the _party object of the L2PcInstance.<BR>
* <BR>
*
* @return the party
*/
@Override
public L2Party getParty()
{
return _party;
}
/**
* Set the _isGm Flag of the L2PcInstance.<BR>
* <BR>
*
* @param firstlog the new first log
*/
// public void setIsGM(boolean status)
// {
// _isGm = status;
// }
public void setFirstLog(int firstlog)
{
_first_log = false;
if(firstlog == 1)
{
_first_log = true;
}
}
/**
* Sets the first log.
*
* @param firstlog the new first log
*/
public void setFirstLog(boolean firstlog)
{
_first_log = firstlog;
}
/**
* Gets the first log.
*
* @return the first log
*/
public boolean getFirstLog()
{
return _first_log;
}
/**
* Manage a cancel cast task for the L2PcInstance.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Set the Intention of the AI to AI_INTENTION_IDLE</li> <li>Enable all skills (set _allSkillsDisabled to False)
* </li> <li>Send a Server->Client Packet MagicSkillCanceld to the L2PcInstance and all L2PcInstance in the
* _KnownPlayers of the L2Character (broadcast)</li><BR>
* <BR>
*/
public void cancelCastMagic()
{
// Set the Intention of the AI to AI_INTENTION_IDLE
getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
// Enable all skills (set _allSkillsDisabled to False)
enableAllSkills();
// Send a Server->Client Packet MagicSkillCanceld to the L2PcInstance and all L2PcInstance in the _KnownPlayers of the L2Character (broadcast)
MagicSkillCanceld msc = new MagicSkillCanceld(getObjectId());
// Broadcast the packet to self and known players.
Broadcast.toSelfAndKnownPlayersInRadius(this, msc, 810000/*900*/);
msc = null;
}
/**
* Set the _accessLevel of the L2PcInstance.<BR>
* <BR>
*
* @param level the new access level
*/
public void setAccessLevel(int level)
{
if(level == Config.MASTERACCESS_LEVEL)
{
_log.warning("Admin Login at "+ fmt.format(new Date(System.currentTimeMillis())) +" " + getName() + " logs in game with AccessLevel "+ level +".");
_accessLevel = AccessLevels.getInstance()._masterAccessLevel;
}
else if(level == Config.USERACCESS_LEVEL)
{
_accessLevel = AccessLevels.getInstance()._userAccessLevel;
}
else
{ if(level > 0){
_log.warning("GM Login at "+ fmt.format(new Date(System.currentTimeMillis())) +" " + getName() + " logs in game with AccessLevel "+ level +".");}
AccessLevel accessLevel = AccessLevels.getInstance().getAccessLevel(level);
if(accessLevel == null)
{
if(level < 0)
{
AccessLevels.getInstance().addBanAccessLevel(level);
_accessLevel = AccessLevels.getInstance().getAccessLevel(level);
}
else
{
_log.warning("Tried to set unregistered access level " + level + " to character " + getName() + ". Setting access level without privileges!");
_accessLevel = AccessLevels.getInstance()._userAccessLevel;
}
}
else
{
_accessLevel = accessLevel;
}
accessLevel = null;
}
if(_accessLevel != AccessLevels.getInstance()._userAccessLevel)
{
//L2EMU_EDIT
if(getAccessLevel().useNameColor())
{
getAppearance().setNameColor(_accessLevel.getNameColor());
}
if(getAccessLevel().useTitleColor())
{
getAppearance().setTitleColor(_accessLevel.getTitleColor());
}
//L2EMU_EDIT
broadcastUserInfo();
}
}
/**
* Sets the account accesslevel.
*
* @param level the new account accesslevel
*/
public void setAccountAccesslevel(int level)
{
LoginServerThread.getInstance().sendAccessLevel(getAccountName(), level);
}
/**
* Return the _accessLevel of the L2PcInstance.<BR>
* <BR>
*
* @return the access level
*/
public AccessLevel getAccessLevel()
{
if(Config.EVERYBODY_HAS_ADMIN_RIGHTS)
return AccessLevels.getInstance()._masterAccessLevel;
else if(_accessLevel == null)
{
setAccessLevel(Config.USERACCESS_LEVEL);
}
return _accessLevel;
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character#getLevelMod()
*/
@Override
public double getLevelMod()
{
return (100.0 - 11 + getLevel()) / 100.0;
}
/**
* Update Stats of the L2PcInstance client side by sending Server->Client packet UserInfo/StatusUpdate to this
* L2PcInstance and CharInfo/StatusUpdate to all L2PcInstance in its _KnownPlayers (broadcast).<BR>
* <BR>
*
* @param broadcastType the broadcast type
*/
public void updateAndBroadcastStatus(int broadcastType)
{
refreshOverloaded();
refreshExpertisePenalty();
// Send a Server->Client packet UserInfo to this L2PcInstance and CharInfo to all L2PcInstance in its _KnownPlayers (broadcast)
if(broadcastType == 1)
{
this.sendPacket(new UserInfo(this));
}
if(broadcastType == 2)
{
broadcastUserInfo();
}
}
/**
* Send a Server->Client StatusUpdate packet with Karma and PvP Flag to the L2PcInstance and all L2PcInstance to
* inform (broadcast).<BR>
* <BR>
*
* @param flag the new karma flag
*/
public void setKarmaFlag(int flag)
{
sendPacket(new UserInfo(this));
for(L2PcInstance player : getKnownList().getKnownPlayers().values())
{
player.sendPacket(new RelationChanged(this, getRelation(player), isAutoAttackable(player)));
if(getPet()!=null){
getPet().broadcastPacket(new NpcInfo(getPet(), null));
}
}
}
/**
* Send a Server->Client StatusUpdate packet with Karma to the L2PcInstance and all L2PcInstance to inform
* (broadcast).<BR>
* <BR>
*/
public void broadcastKarma()
{
sendPacket(new UserInfo(this));
for(L2PcInstance player : getKnownList().getKnownPlayers().values())
{
player.sendPacket(new RelationChanged(this, getRelation(player), isAutoAttackable(player)));
if(getPet()!=null){
getPet().broadcastPacket(new NpcInfo(getPet(), null));
}
}
}
/**
* Set the online Flag to True or False and update the characters table of the database with online status and
* lastAccess (called when login and logout).<BR>
* <BR>
*
* @param isOnline the new online status
*/
public void setOnlineStatus(boolean isOnline)
{
if(_isOnline != isOnline)
{
_isOnline = isOnline;
}
// Update the characters table of the database with online status and lastAccess (called when login and logout)
updateOnlineStatus();
}
/**
* Sets the checks if is in7s dungeon.
*
* @param isIn7sDungeon the new checks if is in7s dungeon
*/
public void setIsIn7sDungeon(boolean isIn7sDungeon)
{
if(_isIn7sDungeon != isIn7sDungeon)
{
_isIn7sDungeon = isIn7sDungeon;
}
updateIsIn7sDungeonStatus();
}
/**
* Update the characters table of the database with online status and lastAccess of this L2PcInstance (called when
* login and logout).<BR>
* <BR>
*/
public void updateOnlineStatus()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement("UPDATE characters SET online=?, lastAccess=? WHERE obj_id=?");
statement.setInt(1, isOnline());
statement.setLong(2, System.currentTimeMillis());
statement.setInt(3, getObjectId());
statement.execute();
statement.close();
statement = null;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("could not set char online status:" + e);
}
finally
{
CloseUtil.close(con);
}
}
/**
* Update is in7s dungeon status.
*/
public void updateIsIn7sDungeonStatus()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement("UPDATE characters SET isIn7sDungeon=?, lastAccess=? WHERE obj_id=?");
statement.setInt(1, isIn7sDungeon() ? 1 : 0);
statement.setLong(2, System.currentTimeMillis());
statement.setInt(3, getObjectId());
statement.execute();
statement.close();
statement = null;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("could not set char isIn7sDungeon status:" + e);
}
finally
{
CloseUtil.close(con);
}
}
/**
* Update first log.
*/
public void updateFirstLog()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement("UPDATE characters SET first_log=? WHERE obj_id=?");
int _fl;
if(getFirstLog())
{
_fl = 1;
}
else
{
_fl = 0;
}
statement.setInt(1, _fl);
statement.setInt(2, getObjectId());
statement.execute();
statement.close();
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("could not set char first login:" + e);
}
finally
{
CloseUtil.close(con);
con = null;
}
}
/**
* Create a new player in the characters table of the database.<BR>
* <BR>
*
* @return true, if successful
*/
private boolean createDb()
{
boolean output = false;
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement;
statement = con.prepareStatement("INSERT INTO characters " + "(account_name,obj_Id,char_name,level,maxHp,curHp,maxCp,curCp,maxMp,curMp," + "acc,crit,evasion,mAtk,mDef,mSpd,pAtk,pDef,pSpd,runSpd,walkSpd," + "str,con,dex,_int,men,wit,face,hairStyle,hairColor,sex," + "movement_multiplier,attack_speed_multiplier,colRad,colHeight," + "exp,sp,karma,pvpkills,pkkills,clanid,maxload,race,classid,deletetime," + "cancraft,title,accesslevel,online,isin7sdungeon,clan_privs,wantspeace," + "base_class,newbie,nobless,power_grade,last_recom_date"/*,banchat_time,*/ + ",aio,aio_end) " + "values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
statement.setString(1, _accountName);
statement.setInt(2, getObjectId());
statement.setString(3, getName());
statement.setInt(4, getLevel());
statement.setInt(5, getMaxHp());
statement.setDouble(6, getCurrentHp());
statement.setInt(7, getMaxCp());
statement.setDouble(8, getCurrentCp());
statement.setInt(9, getMaxMp());
statement.setDouble(10, getCurrentMp());
statement.setInt(11, getAccuracy());
statement.setInt(12, getCriticalHit(null, null));
statement.setInt(13, getEvasionRate(null));
statement.setInt(14, getMAtk(null, null));
statement.setInt(15, getMDef(null, null));
statement.setInt(16, getMAtkSpd());
statement.setInt(17, getPAtk(null));
statement.setInt(18, getPDef(null));
statement.setInt(19, getPAtkSpd());
statement.setInt(20, getRunSpeed());
statement.setInt(21, getWalkSpeed());
statement.setInt(22, getSTR());
statement.setInt(23, getCON());
statement.setInt(24, getDEX());
statement.setInt(25, getINT());
statement.setInt(26, getMEN());
statement.setInt(27, getWIT());
statement.setInt(28, getAppearance().getFace());
statement.setInt(29, getAppearance().getHairStyle());
statement.setInt(30, getAppearance().getHairColor());
statement.setInt(31, getAppearance().getSex() ? 1 : 0);
statement.setDouble(32, 1/*getMovementMultiplier()*/);
statement.setDouble(33, 1/*getAttackSpeedMultiplier()*/);
statement.setDouble(34, getTemplate().collisionRadius/*getCollisionRadius()*/);
statement.setDouble(35, getTemplate().collisionHeight/*getCollisionHeight()*/);
statement.setLong(36, getExp());
statement.setInt(37, getSp());
statement.setInt(38, getKarma());
statement.setInt(39, getPvpKills());
statement.setInt(40, getPkKills());
statement.setInt(41, getClanId());
statement.setInt(42, getMaxLoad());
statement.setInt(43, getRace().ordinal());
statement.setInt(44, getClassId().getId());
statement.setLong(45, getDeleteTimer());
statement.setInt(46, hasDwarvenCraft() ? 1 : 0);
statement.setString(47, getTitle());
statement.setInt(48, getAccessLevel().getLevel());
statement.setInt(49, isOnline());
statement.setInt(50, isIn7sDungeon() ? 1 : 0);
statement.setInt(51, getClanPrivileges());
statement.setInt(52, getWantsPeace());
statement.setInt(53, getBaseClass());
statement.setInt(54, isNewbie() ? 1 : 0);
statement.setInt(55, isNoble() ? 1 : 0);
statement.setLong(56, 0);
statement.setLong(57, System.currentTimeMillis());
//statement.setString(58, StringToHex(Integer.toHexString(getAppearance().getNameColor()).toUpperCase()));
//statement.setString(59, StringToHex(Integer.toHexString(getAppearance().getTitleColor()).toUpperCase()));
statement.setInt(58, isAio() ? 1 :0);
statement.setLong(59, 0);
statement.executeUpdate();
statement.close();
statement = null;
output = true;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.severe("Could not insert char data: " + e);
}
finally
{
CloseUtil.close(con);
con = null;
}
if(output)
{
String text = "Created new character : " + getName() + " for account: " + _accountName;
Log.add(text, "New_chars");
}
return output;
}
/**
* Retrieve a L2PcInstance from the characters table of the database and add it in _allObjects of the L2world.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Retrieve the L2PcInstance from the characters table of the database</li> <li>Add the L2PcInstance object in
* _allObjects</li> <li>Set the x,y,z position of the L2PcInstance and make it invisible</li> <li>Update the
* overloaded status of the L2PcInstance</li><BR>
* <BR>
*
* @param objectId Identifier of the object to initialized
* @return The L2PcInstance loaded from the database
*/
private static L2PcInstance restore(int objectId)
{
L2PcInstance player = null;
double curHp = 0;
double curCp = 0;
double curMp = 0;
Connection con = null;
try
{
// Retrieve the L2PcInstance from the characters table of the database
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement(RESTORE_CHARACTER);
statement.setInt(1, objectId);
ResultSet rset = statement.executeQuery();
while(rset.next())
{
final int activeClassId = rset.getInt("classid");
final boolean female = rset.getInt("sex") != 0;
final L2PcTemplate template = CharTemplateTable.getInstance().getTemplate(activeClassId);
PcAppearance app = new PcAppearance(rset.getByte("face"), rset.getByte("hairColor"), rset.getByte("hairStyle"), female);
player = new L2PcInstance(objectId, template, rset.getString("account_name"), app);
player.setName(rset.getString("char_name"));
player._lastAccess = rset.getLong("lastAccess");
player.getStat().setExp(rset.getLong("exp"));
player.setExpBeforeDeath(rset.getLong("expBeforeDeath"));
player.getStat().setLevel(rset.getByte("level"));
player.getStat().setSp(rset.getInt("sp"));
player.setWantsPeace(rset.getInt("wantspeace"));
player.setHeading(rset.getInt("heading"));
player.setKarma(rset.getInt("karma"));
player.setPvpKills(rset.getInt("pvpkills"));
player.setPkKills(rset.getInt("pkkills"));
player.setOnlineTime(rset.getLong("onlinetime"));
player.setNewbie(rset.getInt("newbie") == 1);
player.setNoble(rset.getInt("nobless") == 1);
player.setClanJoinExpiryTime(rset.getLong("clan_join_expiry_time"));
player.setFirstLog(rset.getInt("first_log"));
player.pcBangPoint = rset.getInt("pc_point");
app = null;
if(player.getClanJoinExpiryTime() < System.currentTimeMillis())
{
player.setClanJoinExpiryTime(0);
}
player.setClanCreateExpiryTime(rset.getLong("clan_create_expiry_time"));
if(player.getClanCreateExpiryTime() < System.currentTimeMillis())
{
player.setClanCreateExpiryTime(0);
}
int clanId = rset.getInt("clanid");
player.setPowerGrade((int) rset.getLong("power_grade"));
player.setPledgeType(rset.getInt("subpledge"));
player.setLastRecomUpdate(rset.getLong("last_recom_date"));
//player.setApprentice(rset.getInt("apprentice"));
if(clanId > 0)
{
player.setClan(ClanTable.getInstance().getClan(clanId));
}
if(player.getClan() != null)
{
if(player.getClan().getLeaderId() != player.getObjectId())
{
if(player.getPowerGrade() == 0)
{
player.setPowerGrade(5);
}
player.setClanPrivileges(player.getClan().getRankPrivs(player.getPowerGrade()));
}
else
{
player.setClanPrivileges(L2Clan.CP_ALL);
player.setPowerGrade(1);
}
}
else
{
player.setClanPrivileges(L2Clan.CP_NOTHING);
}
player.setDeleteTimer(rset.getLong("deletetime"));
player.setTitle(rset.getString("title"));
player.setAccessLevel(rset.getInt("accesslevel"));
player.setFistsWeaponItem(player.findFistsWeaponItem(activeClassId));
player.setUptime(System.currentTimeMillis());
curHp = rset.getDouble("curHp");
curCp = rset.getDouble("curCp");
curMp = rset.getDouble("curMp");
/*
player.setCurrentHp(rset.getDouble("curHp"));
player.setCurrentCp(rset.getDouble("curCp"));
player.setCurrentMp(rset.getDouble("curMp"));
*/
//Check recs
player.checkRecom(rset.getInt("rec_have"), rset.getInt("rec_left"));
player._classIndex = 0;
try
{
player.setBaseClass(rset.getInt("base_class"));
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
player.setBaseClass(activeClassId);
}
// Restore Subclass Data (cannot be done earlier in function)
if(restoreSubClassData(player))
{
if(activeClassId != player.getBaseClass())
{
for(SubClass subClass : player.getSubClasses().values())
if(subClass.getClassId() == activeClassId)
{
player._classIndex = subClass.getClassIndex();
}
}
}
if(player.getClassIndex() == 0 && activeClassId != player.getBaseClass())
{
// Subclass in use but doesn't exist in DB -
// a possible restart-while-modifysubclass cheat has been attempted.
// Switching to use base class
player.setClassId(player.getBaseClass());
_log.warning("Player " + player.getName() + " reverted to base class. Possibly has tried a relogin exploit while subclassing.");
}
else
{
player._activeClass = activeClassId;
}
player.setApprentice(rset.getInt("apprentice"));
player.setSponsor(rset.getInt("sponsor"));
player.setLvlJoinedAcademy(rset.getInt("lvl_joined_academy"));
player.setIsIn7sDungeon(rset.getInt("isin7sdungeon") == 1 ? true : false);
player.setPunishLevel(rset.getInt("punish_level"));
if (player.getPunishLevel() != PunishLevel.NONE)
player.setPunishTimer(rset.getLong("punish_timer"));
else
player.setPunishTimer(0);
/*
player.setInJail(rset.getInt("in_jail") == 1 ? true : false);
if(player.isInJail())
{
player.setJailTimer(rset.getLong("jail_timer"));
}
else
{
player.setJailTimer(0);
}
player.setChatBanTimer(rset.getLong("banchat_time"));
player.updateChatBanState();
*/
try{
//player.getAppearance().setNameColor(Integer.decode(new StringBuilder().append("0x").append(rset.getString("name_color")).toString()).intValue());
//player.getAppearance().setTitleColor(Integer.decode(new StringBuilder().append("0x").append(rset.getString("title_color")).toString()).intValue());
}catch(Exception e){
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
//leave them as default
}
CursedWeaponsManager.getInstance().checkPlayer(player);
player.setAllianceWithVarkaKetra(rset.getInt("varka_ketra_ally"));
player.setDeathPenaltyBuffLevel(rset.getInt("death_penalty_level"));
player.setAio(rset.getInt("aio") == 1 ? true : false);
player.setAioEndTime(rset.getLong("aio_end"));
player.setArenaWins(rset.getInt("arena_wins"));
player.setArenaDefeats(rset.getInt("arena_defeats"));
// Add the L2PcInstance object in _allObjects
//L2World.getInstance().storeObject(player);
// Set the x,y,z position of the L2PcInstance and make it invisible
player.setXYZInvisible(rset.getInt("x"), rset.getInt("y"), rset.getInt("z"));
// Retrieve the name and ID of the other characters assigned to this account.
PreparedStatement stmt = con.prepareStatement("SELECT obj_Id, char_name FROM characters WHERE account_name=? AND obj_Id<>?");
stmt.setString(1, player._accountName);
stmt.setInt(2, objectId);
ResultSet chars = stmt.executeQuery();
while(chars.next())
{
Integer charId = chars.getInt("obj_Id");
String charName = chars.getString("char_name");
player._chars.put(charId, charName);
}
chars.close();
stmt.close();
chars = null;
stmt = null;
break;
}
rset.close();
statement.close();
if (player == null)
{
// TODO: Log this!
return null;
}
// Retrieve from the database all secondary data of this L2PcInstance
// and reward expertise/lucky skills if necessary.
// Note that Clan, Noblesse and Hero skills are given separately and not here.
player.restoreCharData();
player.rewardSkills();
// Restore pet if exists in the world
player.setPet(L2World.getInstance().getPet(player.getObjectId()));
if(player.getPet() != null)
{
player.getPet().setOwner(player);
}
// Update the overloaded status of the L2PcInstance
player.refreshOverloaded();
player.restoreFriendList();
}
catch(Exception e)
{
_log.severe("Could not restore char data: ");
e.printStackTrace();
}
finally
{
CloseUtil.close(con);
}
if(player != null)
{
player.fireEvent(EventType.LOAD.name, (Object[]) null);
try
{
Thread.sleep(100);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
//once restored all the skill status, update current CP, MP and HP
player.setCurrentHpDirect(curHp);
player.setCurrentCpDirect(curCp);
player.setCurrentMpDirect(curMp);
//player.setCurrentCp(curCp);
//player.setCurrentMp(curMp);
}
return player;
}
/**
* Gets the mail.
*
* @return the mail
*/
public Forum getMail()
{
if(_forumMail == null)
{
setMail(ForumsBBSManager.getInstance().getForumByName("MailRoot").getChildByName(getName()));
if(_forumMail == null)
{
ForumsBBSManager.getInstance().createNewForum(getName(), ForumsBBSManager.getInstance().getForumByName("MailRoot"), Forum.MAIL, Forum.OWNERONLY, getObjectId());
setMail(ForumsBBSManager.getInstance().getForumByName("MailRoot").getChildByName(getName()));
}
}
return _forumMail;
}
/**
* Sets the mail.
*
* @param forum the new mail
*/
public void setMail(Forum forum)
{
_forumMail = forum;
}
/**
* Gets the memo.
*
* @return the memo
*/
public Forum getMemo()
{
if(_forumMemo == null)
{
setMemo(ForumsBBSManager.getInstance().getForumByName("MemoRoot").getChildByName(_accountName));
if(_forumMemo == null)
{
ForumsBBSManager.getInstance().createNewForum(_accountName, ForumsBBSManager.getInstance().getForumByName("MemoRoot"), Forum.MEMO, Forum.OWNERONLY, getObjectId());
setMemo(ForumsBBSManager.getInstance().getForumByName("MemoRoot").getChildByName(_accountName));
}
}
return _forumMemo;
}
/**
* Sets the memo.
*
* @param forum the new memo
*/
public void setMemo(Forum forum)
{
_forumMemo = forum;
}
/**
* Restores sub-class data for the L2PcInstance, used to check the current class index for the character.
*
* @param player the player
* @return true, if successful
*/
private static boolean restoreSubClassData(L2PcInstance player)
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement(RESTORE_CHAR_SUBCLASSES);
statement.setInt(1, player.getObjectId());
ResultSet rset = statement.executeQuery();
while(rset.next())
{
SubClass subClass = new SubClass();
subClass.setClassId(rset.getInt("class_id"));
subClass.setLevel(rset.getByte("level"));
subClass.setExp(rset.getLong("exp"));
subClass.setSp(rset.getInt("sp"));
subClass.setClassIndex(rset.getInt("class_index"));
// Enforce the correct indexing of _subClasses against their class indexes.
player.getSubClasses().put(subClass.getClassIndex(), subClass);
}
statement.close();
rset.close();
rset = null;
statement = null;
}
catch(Exception e)
{
_log.warning("Could not restore classes for " + player.getName() + ": " + e);
e.printStackTrace();
}
finally
{
CloseUtil.close(con);
con = null;
}
return true;
}
/**
* Restores secondary data for the L2PcInstance, based on the current class index.
*/
private void restoreCharData()
{
// Retrieve from the database all skills of this L2PcInstance and add them to _skills.
restoreSkills();
// Retrieve from the database all macroses of this L2PcInstance and add them to _macroses.
_macroses.restore();
// Retrieve from the database all shortCuts of this L2PcInstance and add them to _shortCuts.
_shortCuts.restore();
// Retrieve from the database all henna of this L2PcInstance and add them to _henna.
restoreHenna();
// Retrieve from the database all recom data of this L2PcInstance and add to _recomChars.
if(Config.ALT_RECOMMEND)
{
restoreRecom();
}
// Retrieve from the database the recipe book of this L2PcInstance.
if(!isSubClassActive())
{
restoreRecipeBook();
}
}
/**
* Store recipe book data for this L2PcInstance, if not on an active sub-class.
*/
private synchronized void storeRecipeBook()
{
// If the player is on a sub-class don't even attempt to store a recipe book.
if(isSubClassActive())
return;
if(getCommonRecipeBook().length == 0 && getDwarvenRecipeBook().length == 0)
return;
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement("DELETE FROM character_recipebook WHERE char_id=?");
statement.setInt(1, getObjectId());
statement.execute();
statement.close();
statement = null;
L2RecipeList[] recipes = getCommonRecipeBook();
for(L2RecipeList recipe : recipes)
{
statement = con.prepareStatement("INSERT INTO character_recipebook (char_id, id, type) values(?,?,0)");
statement.setInt(1, getObjectId());
statement.setInt(2, recipe.getId());
statement.execute();
statement.close();
statement = null;
}
recipes = getDwarvenRecipeBook();
for(L2RecipeList recipe : recipes)
{
statement = con.prepareStatement("INSERT INTO character_recipebook (char_id, id, type) values(?,?,1)");
statement.setInt(1, getObjectId());
statement.setInt(2, recipe.getId());
statement.execute();
statement.close();
statement = null;
}
recipes = null;
}
catch(Exception e)
{
_log.warning("Could not store recipe book data: " + e);
e.printStackTrace();
}
finally
{
CloseUtil.close(con);
con = null;
}
}
/**
* Restore recipe book data for this L2PcInstance.
*/
private void restoreRecipeBook()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement("SELECT id, type FROM character_recipebook WHERE char_id=?");
statement.setInt(1, getObjectId());
ResultSet rset = statement.executeQuery();
L2RecipeList recipe;
while(rset.next())
{
recipe = RecipeTable.getInstance().getRecipeList(rset.getInt("id") - 1);
if(rset.getInt("type") == 1)
{
registerDwarvenRecipeList(recipe);
}
else
{
registerCommonRecipeList(recipe);
}
}
rset.close();
statement.close();
rset = null;
statement = null;
recipe = null;
}
catch(Exception e)
{
_log.warning("Could not restore recipe book data:" + e);
e.printStackTrace();
}
finally
{
CloseUtil.close(con);
}
}
/**
* Store.
* @param force the force
*/
public synchronized void store(boolean force)
{
// update client coords, if these look like true
if (!force && isInsideRadius(getClientX(), getClientY(), 1000, true))
{
setXYZ(getClientX(), getClientY(), getClientZ());
}
storeCharBase();
storeCharSub();
storeEffect();
storeRecipeBook();
fireEvent(EventType.STORE.name, (Object[]) null);
}
/**
* Update L2PcInstance stats in the characters table of the database.<BR>
* <BR>
*/
public synchronized void store()
{
store(false);
}
/**
* Store char base.
*/
private synchronized void storeCharBase()
{
Connection con = null;
try
{
// Get the exp, level, and sp of base class to store in base table
int currentClassIndex = getClassIndex();
_classIndex = 0;
long exp = getStat().getExp();
int level = getStat().getLevel();
int sp = getStat().getSp();
_classIndex = currentClassIndex;
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement;
// Update base class
statement = con.prepareStatement(UPDATE_CHARACTER);
statement.setInt(1, level);
statement.setInt(2, getMaxHp());
statement.setDouble(3, getCurrentHp());
statement.setInt(4, getMaxCp());
statement.setDouble(5, getCurrentCp());
statement.setInt(6, getMaxMp());
statement.setDouble(7, getCurrentMp());
statement.setInt(8, getSTR());
statement.setInt(9, getCON());
statement.setInt(10, getDEX());
statement.setInt(11, getINT());
statement.setInt(12, getMEN());
statement.setInt(13, getWIT());
statement.setInt(14, getAppearance().getFace());
statement.setInt(15, getAppearance().getHairStyle());
statement.setInt(16, getAppearance().getHairColor());
statement.setInt(17, getHeading());
statement.setInt(18, _observerMode ? _obsX : getX());
statement.setInt(19, _observerMode ? _obsY : getY());
statement.setInt(20, _observerMode ? _obsZ : getZ());
statement.setLong(21, exp);
statement.setLong(22, getExpBeforeDeath());
statement.setInt(23, sp);
statement.setInt(24, getKarma());
statement.setInt(25, getPvpKills());
statement.setInt(26, getPkKills());
statement.setInt(27, getRecomHave());
statement.setInt(28, getRecomLeft());
statement.setInt(29, getClanId());
statement.setInt(30, getMaxLoad());
statement.setInt(31, getRace().ordinal());
// if (!isSubClassActive())
// else
// statement.setInt(30, getBaseTemplate().race.ordinal());
statement.setInt(32, getClassId().getId());
statement.setLong(33, getDeleteTimer());
statement.setString(34, getTitle());
statement.setInt(35, getAccessLevel().getLevel());
if (_isOffline || isOnline() == 1)
{ // in offline mode or online
statement.setInt(36, 1);
}
else
statement.setInt(36, isOnline());
// statement.setInt(36, _isOffline ? 0 : isOnline());
statement.setInt(37, isIn7sDungeon() ? 1 : 0);
statement.setInt(38, getClanPrivileges());
statement.setInt(39, getWantsPeace());
statement.setInt(40, getBaseClass());
long totalOnlineTime = _onlineTime;
if (_onlineBeginTime > 0)
{
totalOnlineTime += (System.currentTimeMillis() - _onlineBeginTime) / 1000;
}
statement.setLong(41, totalOnlineTime);
// statement.setInt(42, isInJail() ? 1 : 0);
// statement.setLong(43, getJailTimer());
statement.setInt(42, getPunishLevel().value());
statement.setLong(43, getPunishTimer());
statement.setInt(44, isNewbie() ? 1 : 0);
statement.setInt(45, isNoble() ? 1 : 0);
statement.setLong(46, getPowerGrade());
statement.setInt(47, getPledgeType());
statement.setLong(48, getLastRecomUpdate());
statement.setInt(49, getLvlJoinedAcademy());
statement.setLong(50, getApprentice());
statement.setLong(51, getSponsor());
statement.setInt(52, getAllianceWithVarkaKetra());
statement.setLong(53, getClanJoinExpiryTime());
statement.setLong(54, getClanCreateExpiryTime());
statement.setString(55, getName());
statement.setLong(56, getDeathPenaltyBuffLevel());
statement.setInt(57, getPcBangScore());
//statement.setString(58, StringToHex(Integer.toHexString(_originalNameColorOffline).toUpperCase()));
//statement.setString(59, StringToHex(Integer.toHexString(getAppearance().getTitleColor()).toUpperCase()));
// TODO allow different colors support to players store
// statement.setString(58, StringToHex(Integer.toHexString(getAppearance().getNameColor()).toUpperCase()));
// statement.setString(59, StringToHex(Integer.toHexString(getAppearance().getTitleColor()).toUpperCase()));
statement.setInt(58, isAio() ? 1 : 0);
statement.setLong(59, getAioEndTime());
statement.setInt(60, arenaWins);
statement.setInt(61, arenaDefeats);
statement.setInt(62, getObjectId());
statement.execute();
statement.close();
statement = null;
}
catch (Exception e)
{
_log.warning("Could not store char base data: ");
e.printStackTrace();
}
finally
{
CloseUtil.close(con);
}
}
/**
* Store char sub.
*/
private synchronized void storeCharSub()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement;
if(getTotalSubClasses() > 0)
{
for(SubClass subClass : getSubClasses().values())
{
statement = con.prepareStatement(UPDATE_CHAR_SUBCLASS);
statement.setLong(1, subClass.getExp());
statement.setInt(2, subClass.getSp());
statement.setInt(3, subClass.getLevel());
statement.setInt(4, subClass.getClassId());
statement.setInt(5, getObjectId());
statement.setInt(6, subClass.getClassIndex());
statement.execute();
statement.close();
statement = null;
}
}
}
catch(Exception e)
{
_log.warning("Could not store sub class data for " + getName() + ": " + e);
e.printStackTrace();
}
finally
{
CloseUtil.close(con);
}
}
private synchronized void storeEffect()
{
if (!Config.STORE_SKILL_COOLTIME)
return;
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement;
// Delete all current stored effects for char to avoid dupe
statement = con.prepareStatement(DELETE_SKILL_SAVE);
statement.setInt(1, getObjectId());
statement.setInt(2, getClassIndex());
statement.execute();
statement.close();
// Store all effect data along with calulated remaining
// reuse delays for matching skills. 'restore_type'= 0.
final L2Effect[] effects = getAllEffects();
statement = con.prepareStatement(ADD_SKILL_SAVE);
List<Integer> storedSkills = new FastList<Integer>();
int buff_index = 0;
for (L2Effect effect : effects)
{
int skillId = effect.getSkill().getId();
if (storedSkills.contains(skillId))
continue;
storedSkills.add(skillId);
if (effect.getInUse() && !effect.getSkill().isToggle() && !effect.getStackType().equals("BattleForce") && !effect.getStackType().equals("SpellForce") && effect.getSkill().getSkillType() != SkillType.FORCE_BUFF)
{
statement.setInt(1, getObjectId());
statement.setInt(2, skillId);
statement.setInt(3, effect.getSkill().getLevel());
statement.setInt(4, effect.getCount());
statement.setInt(5, effect.getTime());
if (ReuseTimeStamps.containsKey(skillId))
{
TimeStamp t = ReuseTimeStamps.get(skillId);
statement.setLong(6, t.hasNotPassed() ? t.getRemaining() : 0);
statement.setLong(7, t.hasNotPassed() ? t.getStamp() : 0);
}
else
{
statement.setLong(6, 0);
statement.setLong(7, 0);
}
statement.setInt(8, 0);
statement.setInt(9, getClassIndex());
statement.setInt(10, ++buff_index);
statement.execute();
}
}
// Store the reuse delays of remaining skills which
// lost effect but still under reuse delay. 'restore_type' 1.
for (TimeStamp t : ReuseTimeStamps.values())
{
if (t.hasNotPassed())
{
int skillId = t.getSkill();
if (storedSkills.contains(skillId))
continue;
storedSkills.add(skillId);
statement.setInt(1, getObjectId());
statement.setInt(2, skillId);
statement.setInt(3, -1);
statement.setInt(4, -1);
statement.setInt(5, -1);
statement.setLong(6, t.getRemaining());
statement.setLong(7, t.getStamp());
statement.setInt(8, 1);
statement.setInt(9, getClassIndex());
statement.setInt(10, ++buff_index);
statement.execute();
}
}
statement.close();
}
catch (Exception e)
{
_log.warning("Could not store char effect data: ");
e.printStackTrace();
}
finally
{
CloseUtil.close(con);
}
}
/**
* Return True if the L2PcInstance is on line.<BR>
* <BR>
*
* @return the int
*/
public int isOnline()
{
return _isOnline ? 1 : 0;
}
/**
* Checks if is in7s dungeon.
*
* @return true, if is in7s dungeon
*/
public boolean isIn7sDungeon()
{
return _isIn7sDungeon;
}
/** Add a skill to the L2PcInstance _skills and its Func objects to the calculator set of the L2PcInstance and save update in the character_skills table of the database.<BR> <BR> <B><U> Concept</U> :</B><BR> <BR> All skills own by a L2PcInstance are identified in <B>_skills</B><BR> <BR> <B><U> Actions</U> :</B><BR> <BR> <li>Replace oldSkill by newSkill or Add the newSkill</li> <li>If an old skill has been replaced, remove all its Func objects of L2Character calculator set</li> <li>Add Func objects of newSkill to the calculator set of the L2Character</li><BR> <BR> */
private boolean _learningSkill = false;
/**
* Adds the skill.
*
* @param newSkill the new skill
* @param store the store
* @return the l2 skill
*/
public synchronized L2Skill addSkill(L2Skill newSkill, boolean store)
{
_learningSkill = true;
// Add a skill to the L2PcInstance _skills and its Func objects to the calculator set of the L2PcInstance
L2Skill oldSkill = super.addSkill(newSkill);
// Add or update a L2PcInstance skill in the character_skills table of the database
if(store)
{
storeSkill(newSkill, oldSkill, -1);
}
_learningSkill = false;
return oldSkill;
}
/**
* Checks if is learning skill.
*
* @return true, if is learning skill
*/
public boolean isLearningSkill(){
return _learningSkill;
}
/**
* Removes the skill.
*
* @param skill the skill
* @param store the store
* @return the l2 skill
*/
public L2Skill removeSkill(L2Skill skill, boolean store)
{
if(store)
return removeSkill(skill);
return super.removeSkill(skill);
}
/**
* Remove a skill from the L2Character and its Func objects from calculator set of the L2Character and save update
* in the character_skills table of the database.<BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* All skills own by a L2Character are identified in <B>_skills</B><BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Remove the skill from the L2Character _skills</li> <li>Remove all its Func objects from the L2Character
* calculator set</li><BR>
* <BR>
* <B><U> Overriden in </U> :</B><BR>
* <BR>
* <li>L2PcInstance : Save update in the character_skills table of the database</li><BR>
* <BR>
*
* @param skill The L2Skill to remove from the L2Character
* @return The L2Skill removed
*/
@Override
public L2Skill removeSkill(L2Skill skill)
{
// Remove a skill from the L2Character and its Func objects from calculator set of the L2Character
L2Skill oldSkill = super.removeSkill(skill);
Connection con = null;
try
{
// Remove or update a L2PcInstance skill from the character_skills table of the database
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement;
if(oldSkill != null)
{
statement = con.prepareStatement(DELETE_SKILL_FROM_CHAR);
statement.setInt(1, oldSkill.getId());
statement.setInt(2, getObjectId());
statement.setInt(3, getClassIndex());
statement.execute();
statement.close();
statement = null;
}
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("Error could not delete skill: " + e);
}
finally
{
CloseUtil.close(con);
}
L2ShortCut[] allShortCuts = getAllShortCuts();
for(L2ShortCut sc : allShortCuts)
{
if(sc != null && skill != null && sc.getId() == skill.getId() && sc.getType() == L2ShortCut.TYPE_SKILL)
{
deleteShortCut(sc.getSlot(), sc.getPage());
}
}
allShortCuts = null;
return oldSkill;
}
/**
* Add or update a L2PcInstance skill in the character_skills table of the database. <BR>
* <BR>
* If newClassIndex > -1, the skill will be stored with that class index, not the current one.
*
* @param newSkill the new skill
* @param oldSkill the old skill
* @param newClassIndex the new class index
*/
private void storeSkill(L2Skill newSkill, L2Skill oldSkill, int newClassIndex)
{
int classIndex = _classIndex;
if(newClassIndex > -1)
{
classIndex = newClassIndex;
}
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement;
if(oldSkill != null && newSkill != null)
{
statement = con.prepareStatement(UPDATE_CHARACTER_SKILL_LEVEL);
statement.setInt(1, newSkill.getLevel());
statement.setInt(2, oldSkill.getId());
statement.setInt(3, getObjectId());
statement.setInt(4, classIndex);
statement.execute();
statement.close();
}
else if(newSkill != null)
{
statement = con.prepareStatement(ADD_NEW_SKILL);
statement.setInt(1, getObjectId());
statement.setInt(2, newSkill.getId());
statement.setInt(3, newSkill.getLevel());
statement.setString(4, newSkill.getName());
statement.setInt(5, classIndex);
statement.execute();
statement.close();
}
else
{
_log.warning("could not store new skill. its NULL");
}
statement = null;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("Error could not store char skills: " + e);
}
finally
{
CloseUtil.close(con);
}
}
/**
* check player skills and remove unlegit ones (excludes hero, noblesse and cursed weapon skills).
*/
public void checkAllowedSkills()
{
boolean foundskill = false;
if(!isGM())
{
Collection<L2SkillLearn> skillTree = SkillTreeTable.getInstance().getAllowedSkills(getClassId());
// loop through all skills of player
for(L2Skill skill : getAllSkills())
{
int skillid = skill.getId();
//int skilllevel = skill.getLevel();
foundskill = false;
// loop through all skills in players skilltree
for(L2SkillLearn temp : skillTree)
{
// if the skill was found and the level is possible to obtain for his class everything is ok
if(temp.getId() == skillid)
{
foundskill = true;
}
}
// exclude noble skills
if(isNoble() && skillid >= 325 && skillid <= 397)
{
foundskill = true;
}
if(isNoble() && skillid >= 1323 && skillid <= 1327)
{
foundskill = true;
}
// exclude hero skills
if(isHero() && skillid >= 395 && skillid <= 396)
{
foundskill = true;
}
if(isHero() && skillid >= 1374 && skillid <= 1376)
{
foundskill = true;
}
// exclude cursed weapon skills
if(isCursedWeaponEquiped() && skillid == CursedWeaponsManager.getInstance().getCursedWeapon(_cursedWeaponEquipedId).getSkillId())
{
foundskill = true;
}
// exclude clan skills
if(getClan() != null && skillid >= 370 && skillid <= 391)
{
foundskill = true;
}
// exclude seal of ruler / build siege hq
if(getClan() != null && (skillid == 246 || skillid == 247))
if(getClan().getLeaderId() == getObjectId())
{
foundskill = true;
}
// exclude fishing skills and common skills + dwarfen craft
if(skillid >= 1312 && skillid <= 1322)
{
foundskill = true;
}
if(skillid >= 1368 && skillid <= 1373)
{
foundskill = true;
}
// exclude sa / enchant bonus / penality etc. skills
if(skillid >= 3000 && skillid < 7000)
{
foundskill = true;
}
// exclude Skills from AllowedSkills in options.properties
if(Config.ALLOWED_SKILLS_LIST.contains(skillid))
{
foundskill = true;
}
//exclude Donator character
if(isDonator())
{
foundskill = true;
}
// remove skill and do a lil log message
if(!foundskill)
{
removeSkill(skill);
if(Config.DEBUG){
//sendMessage("Skill " + skill.getName() + " removed and gm informed!");
_log.warning("Character " + getName() + " of Account " + getAccountName() + " got skill " + skill.getName() + ".. Removed!"/* + IllegalPlayerAction.PUNISH_KICK*/);
}
}
}
skillTree = null;
}
}
/**
* Retrieve from the database all skills of this L2PcInstance and add them to _skills.<BR>
* <BR>
*/
public synchronized void restoreSkills()
{
Connection con = null;
try
{
if(!Config.KEEP_SUBCLASS_SKILLS)
{
// Retrieve all skills of this L2PcInstance from the database
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement(RESTORE_SKILLS_FOR_CHAR);
statement.setInt(1, getObjectId());
statement.setInt(2, getClassIndex());
ResultSet rset = statement.executeQuery();
// Go though the recordset of this SQL query
while(rset.next())
{
int id = rset.getInt("skill_id");
int level = rset.getInt("skill_level");
if(id > 9000)
{
continue; // fake skills for base stats
}
// Create a L2Skill object for each record
L2Skill skill = SkillTable.getInstance().getInfo(id, level);
// Add the L2Skill object to the L2Character _skills and its Func objects to the calculator set of the L2Character
super.addSkill(skill);
}
rset.close();
statement.close();
rset = null;
statement = null;
}
else
{
// Retrieve all skills of this L2PcInstance from the database
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement(RESTORE_SKILLS_FOR_CHAR_ALT_SUBCLASS);
statement.setInt(1, getObjectId());
ResultSet rset = statement.executeQuery();
// Go though the recordset of this SQL query
while(rset.next())
{
int id = rset.getInt("skill_id");
int level = rset.getInt("skill_level");
if(id > 9000)
{
continue; // fake skills for base stats
}
// Create a L2Skill object for each record
L2Skill skill = SkillTable.getInstance().getInfo(id, level);
// Add the L2Skill object to the L2Character _skills and its Func objects to the calculator set of the L2Character
super.addSkill(skill);
}
rset.close();
statement.close();
rset = null;
statement = null;
}
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("Could not restore character skills: " + e);
}
finally
{
CloseUtil.close(con);
con = null;
}
}
public void restoreEffects()
{
restoreEffects(true);
}
/**
* Retrieve from the database all skill effects of this L2PcInstance and add them to the player.<BR>
* <BR>
* @param activateEffects
*/
public void restoreEffects(boolean activateEffects)
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement;
ResultSet rset;
/**
* Restore Type 0 These skill were still in effect on the character upon logout. Some of which were self
* casted and might still have had a long reuse delay which also is restored.
*/
statement = con.prepareStatement(RESTORE_SKILL_SAVE);
statement.setInt(1, getObjectId());
statement.setInt(2, getClassIndex());
statement.setInt(3, 0);
rset = statement.executeQuery();
while(rset.next())
{
int skillId = rset.getInt("skill_id");
int skillLvl = rset.getInt("skill_level");
int effectCount = rset.getInt("effect_count");
int effectCurTime = rset.getInt("effect_cur_time");
long reuseDelay = rset.getLong("reuse_delay");
// Just incase the admin minipulated this table incorrectly :x
if(skillId == -1 || effectCount == -1 || effectCurTime == -1 || reuseDelay < 0)
{
continue;
}
if(activateEffects){
L2Skill skill = SkillTable.getInstance().getInfo(skillId, skillLvl);
skill.getEffects(this, this,false,false,false);
skill = null;
for(L2Effect effect : getAllEffects())
{
if(effect.getSkill().getId() == skillId)
{
effect.setCount(effectCount);
effect.setFirstTime(effectCurTime);
}
}
}
if(reuseDelay > 10)
{
disableSkill(skillId, reuseDelay);
addTimeStamp(new TimeStamp(skillId, reuseDelay));
}
}
rset.close();
statement.close();
rset = null;
statement = null;
/**
* Restore Type 1 The remaning skills lost effect upon logout but were still under a high reuse delay.
*/
statement = con.prepareStatement(RESTORE_SKILL_SAVE);
statement.setInt(1, getObjectId());
statement.setInt(2, getClassIndex());
statement.setInt(3, 1);
rset = statement.executeQuery();
while(rset.next())
{
int skillId = rset.getInt("skill_id");
long reuseDelay = rset.getLong("reuse_delay");
if(reuseDelay <= 0)
{
continue;
}
disableSkill(skillId, reuseDelay);
addTimeStamp(new TimeStamp(skillId, reuseDelay));
}
rset.close();
statement.close();
rset = null;
statement = con.prepareStatement(DELETE_SKILL_SAVE);
statement.setInt(1, getObjectId());
statement.setInt(2, getClassIndex());
statement.executeUpdate();
statement.close();
statement = null;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("Could not restore active effect data: " + e);
}
finally
{
CloseUtil.close(con);
}
updateEffectIcons();
}
/**
* Retrieve from the database all Henna of this L2PcInstance, add them to _henna and calculate stats of the
* L2PcInstance.<BR>
* <BR>
*/
private void restoreHenna()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement(RESTORE_CHAR_HENNAS);
statement.setInt(1, getObjectId());
statement.setInt(2, getClassIndex());
ResultSet rset = statement.executeQuery();
for(int i = 0; i < 3; i++)
{
_henna[i] = null;
}
while(rset.next())
{
int slot = rset.getInt("slot");
if(slot < 1 || slot > 3)
{
continue;
}
int symbol_id = rset.getInt("symbol_id");
L2HennaInstance sym = null;
if(symbol_id != 0)
{
L2Henna tpl = HennaTable.getInstance().getTemplate(symbol_id);
if(tpl != null)
{
sym = new L2HennaInstance(tpl);
_henna[slot - 1] = sym;
tpl = null;
sym = null;
}
}
}
rset.close();
statement.close();
rset = null;
statement = null;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("could not restore henna: " + e);
}
finally
{
CloseUtil.close(con);
}
// Calculate Henna modifiers of this L2PcInstance
recalcHennaStats();
}
/**
* Retrieve from the database all Recommendation data of this L2PcInstance, add to _recomChars and calculate stats
* of the L2PcInstance.<BR>
* <BR>
*/
private void restoreRecom()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement(RESTORE_CHAR_RECOMS);
statement.setInt(1, getObjectId());
ResultSet rset = statement.executeQuery();
while(rset.next())
{
_recomChars.add(rset.getInt("target_id"));
}
rset.close();
statement.close();
rset = null;
statement = null;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("could not restore recommendations: " + e);
}
finally
{
CloseUtil.close(con);
con = null;
}
}
/**
* Return the number of Henna empty slot of the L2PcInstance.<BR>
* <BR>
*
* @return the henna empty slots
*/
public int getHennaEmptySlots()
{
int totalSlots = 1 + getClassId().level();
for(int i = 0; i < 3; i++)
if(_henna[i] != null)
{
totalSlots--;
}
if(totalSlots <= 0)
return 0;
return totalSlots;
}
/**
* Remove a Henna of the L2PcInstance, save update in the character_hennas table of the database and send
* Server->Client HennaInfo/UserInfo packet to this L2PcInstance.<BR>
* <BR>
*
* @param slot the slot
* @return true, if successful
*/
public boolean removeHenna(int slot)
{
if(slot < 1 || slot > 3)
return false;
slot--;
if(_henna[slot] == null)
return false;
L2HennaInstance henna = _henna[slot];
_henna[slot] = null;
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement(DELETE_CHAR_HENNA);
statement.setInt(1, getObjectId());
statement.setInt(2, slot + 1);
statement.setInt(3, getClassIndex());
statement.execute();
statement.close();
statement = null;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("could not remove char henna: " + e);
}
finally
{
CloseUtil.close(con);
con = null;
}
// Calculate Henna modifiers of this L2PcInstance
recalcHennaStats();
// Send Server->Client HennaInfo packet to this L2PcInstance
sendPacket(new HennaInfo(this));
// Send Server->Client UserInfo packet to this L2PcInstance
sendPacket(new UserInfo(this));
// Add the recovered dyes to the player's inventory and notify them.
getInventory().addItem("Henna", henna.getItemIdDye(), henna.getAmountDyeRequire() / 2, this, null);
SystemMessage sm = new SystemMessage(SystemMessageId.EARNED_S2_S1_S);
sm.addItemName(henna.getItemIdDye());
sm.addNumber(henna.getAmountDyeRequire() / 2);
sendPacket(sm);
sm = null;
henna = null;
return true;
}
/**
* Add a Henna to the L2PcInstance, save update in the character_hennas table of the database and send
* Server->Client HennaInfo/UserInfo packet to this L2PcInstance.<BR>
* <BR>
*
* @param henna the henna
* @return true, if successful
*/
public boolean addHenna(L2HennaInstance henna)
{
if(getHennaEmptySlots() == 0)
{
sendMessage("You may not have more than three equipped symbols at a time.");
return false;
}
// int slot = 0;
for(int i = 0; i < 3; i++)
{
if(_henna[i] == null)
{
_henna[i] = henna;
// Calculate Henna modifiers of this L2PcInstance
recalcHennaStats();
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement(ADD_CHAR_HENNA);
statement.setInt(1, getObjectId());
statement.setInt(2, henna.getSymbolId());
statement.setInt(3, i + 1);
statement.setInt(4, getClassIndex());
statement.execute();
statement.close();
statement = null;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("could not save char henna: " + e);
}
finally
{
CloseUtil.close(con);
con = null;
}
// Send Server->Client HennaInfo packet to this L2PcInstance
HennaInfo hi = new HennaInfo(this);
sendPacket(hi);
hi = null;
// Send Server->Client UserInfo packet to this L2PcInstance
UserInfo ui = new UserInfo(this);
sendPacket(ui);
ui = null;
getInventory().refreshWeight();
return true;
}
}
return false;
}
/**
* Calculate Henna modifiers of this L2PcInstance.<BR>
* <BR>
*/
private void recalcHennaStats()
{
_hennaINT = 0;
_hennaSTR = 0;
_hennaCON = 0;
_hennaMEN = 0;
_hennaWIT = 0;
_hennaDEX = 0;
for(int i = 0; i < 3; i++)
{
if(_henna[i] == null)
{
continue;
}
_hennaINT += _henna[i].getStatINT();
_hennaSTR += _henna[i].getStatSTR();
_hennaMEN += _henna[i].getStatMEM();
_hennaCON += _henna[i].getStatCON();
_hennaWIT += _henna[i].getStatWIT();
_hennaDEX += _henna[i].getStatDEX();
}
if(_hennaINT > 5)
{
_hennaINT = 5;
}
if(_hennaSTR > 5)
{
_hennaSTR = 5;
}
if(_hennaMEN > 5)
{
_hennaMEN = 5;
}
if(_hennaCON > 5)
{
_hennaCON = 5;
}
if(_hennaWIT > 5)
{
_hennaWIT = 5;
}
if(_hennaDEX > 5)
{
_hennaDEX = 5;
}
}
/**
* Return the Henna of this L2PcInstance corresponding to the selected slot.<BR>
* <BR>
*
* @param slot the slot
* @return the hennas
*/
public L2HennaInstance getHennas(int slot)
{
if(slot < 1 || slot > 3)
return null;
return _henna[slot - 1];
}
/**
* Return the INT Henna modifier of this L2PcInstance.<BR>
* <BR>
*
* @return the henna stat int
*/
public int getHennaStatINT()
{
return _hennaINT;
}
/**
* Return the STR Henna modifier of this L2PcInstance.<BR>
* <BR>
*
* @return the henna stat str
*/
public int getHennaStatSTR()
{
return _hennaSTR;
}
/**
* Return the CON Henna modifier of this L2PcInstance.<BR>
* <BR>
*
* @return the henna stat con
*/
public int getHennaStatCON()
{
return _hennaCON;
}
/**
* Return the MEN Henna modifier of this L2PcInstance.<BR>
* <BR>
*
* @return the henna stat men
*/
public int getHennaStatMEN()
{
return _hennaMEN;
}
/**
* Return the WIT Henna modifier of this L2PcInstance.<BR>
* <BR>
*
* @return the henna stat wit
*/
public int getHennaStatWIT()
{
return _hennaWIT;
}
/**
* Return the DEX Henna modifier of this L2PcInstance.<BR>
* <BR>
*
* @return the henna stat dex
*/
public int getHennaStatDEX()
{
return _hennaDEX;
}
/**
* Return True if the L2PcInstance is autoAttackable.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Check if the attacker isn't the L2PcInstance Pet</li> <li>Check if the attacker is L2MonsterInstance</li> <li>If the attacker is a L2PcInstance, check if it is not in the same party</li> <li>Check if the L2PcInstance has Karma</li> <li>If the attacker is a L2PcInstance, check if it is not
* in the same siege clan (Attacker, Defender)</li> <BR>
* <BR>
* @param attacker the attacker
* @return true, if is auto attackable
*/
@Override
public boolean isAutoAttackable(L2Character attacker)
{
// Check if the attacker isn't the L2PcInstance Pet
if (attacker == this || attacker == getPet())
return false;
// Check if the attacker is a L2MonsterInstance
if (attacker instanceof L2MonsterInstance)
return true;
// Check if the attacker is not in the same party, excluding duels like L2OFF
if (getParty() != null && getParty().getPartyMembers().contains(attacker) && !(getDuelState() == Duel.DUELSTATE_DUELLING && getDuelId() == ((L2PcInstance) attacker).getDuelId()))
return false;
// Check if the attacker is in olympia and olympia start
if (attacker instanceof L2PcInstance && ((L2PcInstance) attacker).isInOlympiadMode())
{
if (isInOlympiadMode() && isOlympiadStart() && ((L2PcInstance) attacker).getOlympiadGameId() == getOlympiadGameId())
{
if (isFakeDeath())
return false;
return true;
}
return false;
}
// Check if the attacker is not in the same clan, excluding duels like L2OFF
if (getClan() != null && attacker != null && getClan().isMember(attacker.getName()) && !(getDuelState() == Duel.DUELSTATE_DUELLING && getDuelId() == ((L2PcInstance) attacker).getDuelId()))
return false;
if (attacker instanceof L2PlayableInstance && isInFunEvent())
{
L2PcInstance player = null;
if (attacker instanceof L2PcInstance)
{
player = (L2PcInstance) attacker;
}
else if (attacker instanceof L2Summon)
{
player = ((L2Summon) attacker).getOwner();
}
if (player != null)
{
if (player.isInFunEvent())
{
// checks for events
if ((_inEventTvT && player._inEventTvT && TvT.is_started() && !_teamNameTvT.equals(player._teamNameTvT)) || (_inEventCTF && player._inEventCTF && CTF.is_started() && !_teamNameCTF.equals(player._teamNameCTF)) || (_inEventDM && player._inEventDM && DM.is_started()) || (_inEventVIP && player._inEventVIP && VIP._started))
{
return true;
}
return false;
}
return false;
}
}
if (L2Character.isInsidePeaceZone(attacker, this))
{
return false;
}
// Check if the L2PcInstance has Karma
if (getKarma() > 0 || getPvpFlag() > 0)
return true;
// Check if the attacker is a L2PcInstance
if (attacker instanceof L2PcInstance)
{
// is AutoAttackable if both players are in the same duel and the duel is still going on
if (getDuelState() == Duel.DUELSTATE_DUELLING && getDuelId() == ((L2PcInstance) attacker).getDuelId())
return true;
// Check if the L2PcInstance is in an arena or a siege area
if (isInsideZone(ZONE_PVP) && ((L2PcInstance) attacker).isInsideZone(ZONE_PVP))
return true;
if (isInsideZone(ZONE_EVENT) && ((L2PcInstance) attacker).isInsideZone(ZONE_EVENT))
return true;
if (isinTownWar() && ((L2PcInstance) attacker).isinTownWar())
return true;
if (isInsideZone(ZONE_CHAOTIC) && ((L2PcInstance) attacker).isInsideZone(ZONE_CHAOTIC))
return true;
if (getClan() != null)
{
Siege siege = SiegeManager.getInstance().getSiege(getX(), getY(), getZ());
FortSiege fortsiege = FortSiegeManager.getInstance().getSiege(getX(), getY(), getZ());
if (siege != null)
{
// Check if a siege is in progress and if attacker and the L2PcInstance aren't in the Defender clan
if (siege.checkIsDefender(((L2PcInstance) attacker).getClan()) && siege.checkIsDefender(getClan()))
{
siege = null;
return false;
}
// Check if a siege is in progress and if attacker and the L2PcInstance aren't in the Attacker clan
if (siege.checkIsAttacker(((L2PcInstance) attacker).getClan()) && siege.checkIsAttacker(getClan()))
{
siege = null;
return false;
}
}
if (fortsiege != null)
{
// Check if a siege is in progress and if attacker and the L2PcInstance aren't in the Defender clan
if (fortsiege.checkIsDefender(((L2PcInstance) attacker).getClan()) && fortsiege.checkIsDefender(getClan()))
{
fortsiege = null;
return false;
}
// Check if a siege is in progress and if attacker and the L2PcInstance aren't in the Attacker clan
if (fortsiege.checkIsAttacker(((L2PcInstance) attacker).getClan()) && fortsiege.checkIsAttacker(getClan()))
{
fortsiege = null;
return false;
}
}
// Check if clan is at war
if (getClan() != null && ((L2PcInstance) attacker).getClan() != null && getClan().isAtWarWith(((L2PcInstance) attacker).getClanId()) && getWantsPeace() == 0 && ((L2PcInstance) attacker).getWantsPeace() == 0 && !isAcademyMember())
return true;
}
}
else if (attacker instanceof L2SiegeGuardInstance)
{
if (getClan() != null)
{
Siege siege = SiegeManager.getInstance().getSiege(this);
return siege != null && siege.checkIsAttacker(getClan()) || DevastatedCastle.getInstance().getIsInProgress();
}
}
else if (attacker instanceof L2FortSiegeGuardInstance)
{
if (getClan() != null)
{
FortSiege fortsiege = FortSiegeManager.getInstance().getSiege(this);
return fortsiege != null && fortsiege.checkIsAttacker(getClan());
}
}
return false;
}
/**
* Check if the active L2Skill can be casted.<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Check if the skill isn't toggle and is offensive</li> <li>Check if the target is in the skill cast range</li>
* <li>Check if the skill is Spoil type and if the target isn't already spoiled</li> <li>Check if the caster owns
* enought consummed Item, enough HP and MP to cast the skill</li> <li>Check if the caster isn't sitting</li> <li>
* Check if all skills are enabled and this skill is enabled</li><BR>
* <BR>
* <li>Check if the caster own the weapon needed</li><BR>
* <BR>
* <li>Check if the skill is active</li><BR>
* <BR>
* <li>Check if all casting conditions are completed</li><BR>
* <BR>
* <li>Notify the AI with AI_INTENTION_CAST and target</li><BR>
* <BR>
*
* @param skill The L2Skill to use
* @param forceUse used to force ATTACK on players
* @param dontMove used to prevent movement, if not in range
*/
public void useMagic(L2Skill skill, boolean forceUse, boolean dontMove)
{
if(isDead())
{
abortCast();
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
if(skill == null){
abortCast();
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
int skill_id = skill.getId();
int curr_skill_id = -1;
SkillDat current = null;
if((current = getCurrentSkill())!=null){
curr_skill_id = current.getSkillId();
}
/*
if (isWearingFormalWear() && !skill.isPotion())
{
sendPacket(new SystemMessage(SystemMessageId.CANNOT_USE_ITEMS_SKILLS_WITH_FORMALWEAR));
sendPacket(ActionFailed.STATIC_PACKET);
abortCast();
return;
}
*/
if(inObserverMode())
{
sendPacket(new SystemMessage(SystemMessageId.OBSERVERS_CANNOT_PARTICIPATE));
abortCast();
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Check if the caster is sitting
if(isSitting() && !skill.isPotion())
{
// Send a System Message to the caster
sendPacket(new SystemMessage(SystemMessageId.CANT_MOVE_SITTING));
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Check if the skill type is TOGGLE
if(skill.isToggle())
{
// Like L2OFF you can't use fake death if you are mounted
if (skill.getId() == 60 && isMounted())
return;
// Get effects of the skill
L2Effect effect = getFirstEffect(skill);
// Like L2OFF toogle skills have little delay
if (TOGGLE_USE + 400 > System.currentTimeMillis())
{
return;
}
if(effect != null)
{
//fake death exception
if (skill.getId() != 60)
effect.exit(false);
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
TOGGLE_USE = System.currentTimeMillis();
}
// Check if the skill is active
if(skill.isPassive())
{
// just ignore the passive skill request. why does the client send it anyway ??
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
if(_disabledSkills != null && _disabledSkills.contains(skill_id))
{
SystemMessage sm = new SystemMessage(SystemMessageId.S1_PREPARED_FOR_REUSE);
sm.addSkillName(skill_id, skill.getLevel());
sendPacket(sm);
sm = null;
return;
}
// Check if it's ok to summon
// siege golem (13), Wild Hog Cannon (299), Swoop Cannon (448)
if((skill_id == 13 || skill_id == 299 || skill_id == 448) && !SiegeManager.getInstance().checkIfOkToSummon(this, false) && !FortSiegeManager.getInstance().checkIfOkToSummon(this, false))
return;
//************************************* Check Casting in Progress *******************************************
// If a skill is currently being used, queue this one if this is not the same
// Note that this check is currently imperfect: getCurrentSkill() isn't always null when a skill has
// failed to cast, or the casting is not yet in progress when this is rechecked
if(curr_skill_id != -1 && (isCastingNow() || isCastingPotionNow()))
{
SkillDat currentSkill = getCurrentSkill();
// Check if new skill different from current skill in progress
if (currentSkill != null && skill.getId() == currentSkill.getSkillId())
{
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
if(Config.DEBUG && getQueuedSkill() != null)
{
_log.info(getQueuedSkill().getSkill().getName() + " is already queued for " + getName() + ".");
}
// Create a new SkillDat object and queue it in the player _queuedSkill
setQueuedSkill(skill, forceUse, dontMove);
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Create a new SkillDat object and set the player _currentSkill
// This is used mainly to save & queue the button presses, since L2Character has
// _lastSkillCast which could otherwise replace it
setCurrentSkill(skill, forceUse, dontMove);
if (getQueuedSkill() != null) // wiping out previous values, after casting has been aborted
setQueuedSkill(null, false, false);
//triggered skills cannot be used directly
if(_triggeredSkills.size()>0){
if(Config.DEBUG){
System.out.println("Checking if Triggherable Skill: "+skill.getId());
System.out.println("Saved Triggherable Skills");
for(Integer skillId:_triggeredSkills.keySet()){
System.out.println(skillId);
}
}
if(_triggeredSkills.get(skill.getId()) != null){
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
//************************************* Check Target *******************************************
// Create and set a L2Object containing the target of the skill
L2Object target = null;
SkillTargetType sklTargetType = skill.getTargetType();
SkillType sklType = skill.getSkillType();
switch(sklTargetType)
{
// Target the player if skill type is AURA, PARTY, CLAN or SELF
case TARGET_AURA:
if(isInOlympiadMode() && !isOlympiadStart())
setTarget(this);
case TARGET_PARTY:
case TARGET_ALLY:
case TARGET_CLAN:
case TARGET_GROUND:
case TARGET_SELF:
target = this;
break;
case TARGET_PET:
target = getPet();
break;
default:
target = getTarget();
break;
}
// Check the validity of the target
if(target == null)
{
sendPacket(new SystemMessage(SystemMessageId.TARGET_CANT_FOUND));
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// skills can be used on Walls and Doors only durring siege
// Ignore skill UNLOCK
if(skill.isOffensive() && target instanceof L2DoorInstance )
{
boolean isCastle = (((L2DoorInstance) target).getCastle() != null
&& ((L2DoorInstance) target).getCastle().getCastleId() > 0
&& ((L2DoorInstance) target).getCastle().getSiege().getIsInProgress());
boolean isFort = (((L2DoorInstance) target).getFort() != null
&& ((L2DoorInstance) target).getFort().getFortId() > 0
&& ((L2DoorInstance) target).getFort().getSiege().getIsInProgress());
if ((!isCastle && !isFort))
return;
}
// Like L2OFF you can't heal random purple people without using CTRL
SkillDat skilldat = getCurrentSkill();
if (skilldat != null && skill.getSkillType() == SkillType.HEAL && !skilldat.isCtrlPressed() && target instanceof L2PcInstance && ((L2PcInstance) target).getPvpFlag() == 1 && this != target)
{
if ((getClanId() == 0 || ((L2PcInstance) target).getClanId() == 0) || (getClanId() != ((L2PcInstance) target).getClanId()))
{
if ((getAllyId() == 0 || ((L2PcInstance) target).getAllyId() == 0) || (getAllyId() != ((L2PcInstance) target).getAllyId()))
{
if ((getParty() == null || ((L2PcInstance) target).getParty() == null) || (!getParty().equals(((L2PcInstance) target).getParty())))
{
sendPacket(new SystemMessage(SystemMessageId.INCORRECT_TARGET));
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
}
}
// Are the target and the player in the same duel?
if(isInDuel())
{
if(!(target instanceof L2PcInstance && ((L2PcInstance) target).getDuelId() == getDuelId()) && !(target instanceof L2SummonInstance && ((L2Summon) target).getOwner().getDuelId() == getDuelId()))
{
sendMessage("You cannot do this while duelling.");
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
//************************************* Check skill availability *******************************************
// Check if this skill is enabled (ex : reuse time)
if(isSkillDisabled(skill_id) /* && !getAccessLevel().allowPeaceAttack() */)
{
// SystemMessage sm = new SystemMessage(SystemMessageId.SKILL_NOT_AVAILABLE);
// sm.addString(skill.getName());
// sendPacket(sm);
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Check if all skills are disabled
if(isAllSkillsDisabled() && !getAccessLevel().allowPeaceAttack())
{
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// prevent casting signets to peace zone
if(skill.getSkillType() == SkillType.SIGNET || skill.getSkillType() == SkillType.SIGNET_CASTTIME)
{
if(isInsidePeaceZone(this))
{
SystemMessage sm = new SystemMessage(SystemMessageId.S1_CANNOT_BE_USED);
sm.addSkillName(skill_id);
sendPacket(sm);
return;
}
}
//************************************* Check Consumables *******************************************
// Check if the caster has enough MP
if(getCurrentMp() < getStat().getMpConsume(skill) + getStat().getMpInitialConsume(skill))
{
// Send a System Message to the caster
sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_MP));
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Check if the caster has enough HP
if(getCurrentHp() <= skill.getHpConsume())
{
// Send a System Message to the caster
sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_HP));
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Check if the spell consummes an Item
if(skill.getItemConsume() > 0)
{
// Get the L2ItemInstance consummed by the spell
L2ItemInstance requiredItems = getInventory().getItemByItemId(skill.getItemConsumeId());
// Check if the caster owns enought consummed Item to cast
if(requiredItems == null || requiredItems.getCount() < skill.getItemConsume())
{
// Checked: when a summon skill failed, server show required consume item count
if(sklType == L2Skill.SkillType.SUMMON)
{
SystemMessage sm = new SystemMessage(SystemMessageId.SUMMONING_SERVITOR_COSTS_S2_S1);
sm.addItemName(skill.getItemConsumeId());
sm.addNumber(skill.getItemConsume());
sendPacket(sm);
}
else
{
// Send a System Message to the caster
sendPacket(new SystemMessage(SystemMessageId.NOT_ENOUGH_ITEMS));
}
return;
}
}
// Like L2OFF if you are mounted on wyvern you can't use own skills
if (isFlying())
{
if (skill_id != 327 && skill_id != 4289 && !skill.isPotion())
{
sendMessage("You cannot use skills while riding a wyvern.");
return;
}
}
// Like L2OFF if you have a summon you can't summon another one (ignore cubics)
if(sklType == L2Skill.SkillType.SUMMON && skill instanceof L2SkillSummon && !((L2SkillSummon) skill).isCubic())
{
if (getPet() != null || isMounted())
{
sendPacket(new SystemMessage(SystemMessageId.YOU_ALREADY_HAVE_A_PET));
return;
}
}
if(skill.getNumCharges() > 0
&& skill.getSkillType() != SkillType.CHARGE
&& skill.getSkillType() != SkillType.CHARGEDAM
&& skill.getSkillType() != SkillType.CHARGE_EFFECT
&& skill.getSkillType() != SkillType.PDAM)
{
EffectCharge effect = (EffectCharge) getFirstEffect(L2Effect.EffectType.CHARGE);
if(effect == null || effect.numCharges < skill.getNumCharges())
{
sendPacket(new SystemMessage(SystemMessageId.SKILL_NOT_AVAILABLE));
return;
}
effect.numCharges -= skill.getNumCharges();
sendPacket(new EtcStatusUpdate(this));
if(effect.numCharges == 0)
{
effect.exit(false);
}
}
//************************************* Check Casting Conditions *******************************************
// Check if the caster own the weapon needed
if(!skill.getWeaponDependancy(this))
{
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Check if all casting conditions are completed
if(!skill.checkCondition(this, target, false))
{
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
//************************************* Check Player State *******************************************
// Abnormal effects(ex : Stun, Sleep...) are checked in L2Character useMagic()
// Check if the player use "Fake Death" skill
if(isAlikeDead() && !skill.isPotion() && skill.getSkillType() != L2Skill.SkillType.FAKE_DEATH)
{
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
if(isFishing() && sklType != SkillType.PUMPING && sklType != SkillType.REELING && sklType != SkillType.FISHING)
{
//Only fishing skills are available
sendPacket(new SystemMessage(SystemMessageId.ONLY_FISHING_SKILLS_NOW));
return;
}
//************************************* Check Skill Type *******************************************
// Check if this is offensive magic skill
if(skill.isOffensive())
{
Boolean peace = isInsidePeaceZone(this, target);
if(peace
&& (skill.getId() != 3261 // Like L2OFF you can use cupid bow skills on peace zone
&& skill.getId() != 3260
&& skill.getId() != 3262 && sklTargetType != SkillTargetType.TARGET_AURA)) // Like L2OFF people can use TARGET_AURE skills on peace zone
{
// If L2Character or target is in a peace zone, send a system message TARGET_IN_PEACEZONE a Server->Client packet ActionFailed
sendPacket(new SystemMessage(SystemMessageId.TARGET_IN_PEACEZONE));
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
if(isInOlympiadMode() && !isOlympiadStart() && sklTargetType != SkillTargetType.TARGET_AURA)
{
// if L2PcInstance is in Olympia and the match isn't already start, send a Server->Client packet ActionFailed
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
if(!(target instanceof L2MonsterInstance) && sklType == SkillType.CONFUSE_MOB_ONLY)
{
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
/*
// Check if the target is attackable
if(target instanceof L2PcInstance && !target.isAttackable() && !getAccessLevel().allowPeaceAttack() && (!(_inEventTvT && TvT.is_started()) || !(_inEventCTF && CTF.is_started()) || !(_inEventDM && DM.is_started()) || !(_inEventVIP && VIP._started)))
{
if(!isInFunEvent() || !((L2PcInstance)target).isInFunEvent())
{
// If target is not attackable, send a Server->Client packet ActionFailed
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
*/
// Check if a Forced ATTACK is in progress on non-attackable target
//if (!target.isAutoAttackable(this) && !forceUse && !(_inEventTvT && TvT._started) && !(_inEventDM && DM._started) && !(_inEventCTF && CTF._started) && !(_inEventVIP && VIP._started)
if (!target.isAutoAttackable(this) && (!forceUse && (skill.getId() != 3261 && skill.getId() != 3260 && skill.getId() != 3262)) && !(_inEventTvT && TvT.is_started()) && !(_inEventDM && DM.is_started()) && !(_inEventCTF && CTF.is_started()) && !(_inEventVIP && VIP._started)
&& sklTargetType != SkillTargetType.TARGET_AURA
&& sklTargetType != SkillTargetType.TARGET_CLAN
&& sklTargetType != SkillTargetType.TARGET_ALLY
&& sklTargetType != SkillTargetType.TARGET_PARTY
&& sklTargetType != SkillTargetType.TARGET_SELF
&& sklTargetType != SkillTargetType.TARGET_GROUND)
{
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Check if the target is in the skill cast range
if (dontMove)
{
// Calculate the distance between the L2PcInstance and the target
if (sklTargetType == SkillTargetType.TARGET_GROUND)
{
if (!isInsideRadius(getCurrentSkillWorldPosition().getX(), getCurrentSkillWorldPosition().getY(), getCurrentSkillWorldPosition().getZ(), (int) (skill.getCastRange() + getTemplate().getCollisionRadius()), false, false))
{
// Send a System Message to the caster
sendPacket(SystemMessageId.TARGET_TOO_FAR);
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
else if (skill.getCastRange() > 0 && !isInsideRadius(target, skill.getCastRange() + getTemplate().collisionRadius, false, false)) // Calculate the distance between the L2PcInstance and the target
{
// Send a System Message to the caster
sendPacket(new SystemMessage(SystemMessageId.TARGET_TOO_FAR));
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
else if (sklType == SkillType.SIGNET) // Check range for SIGNET skills
{
if (!isInsideRadius(getCurrentSkillWorldPosition().getX(), getCurrentSkillWorldPosition().getY(), getCurrentSkillWorldPosition().getZ(), (int) (skill.getCastRange() + getTemplate().getCollisionRadius()), false, false))
{
// Send a System Message to the caster
sendPacket(SystemMessageId.TARGET_TOO_FAR);
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
}
// Check if the skill is defensive
if(!skill.isOffensive())
{
// check if the target is a monster and if force attack is set.. if not then we don't want to cast.
if(target instanceof L2MonsterInstance && !forceUse && sklTargetType != SkillTargetType.TARGET_PET && sklTargetType != SkillTargetType.TARGET_AURA && sklTargetType != SkillTargetType.TARGET_CLAN && sklTargetType != SkillTargetType.TARGET_SELF && sklTargetType != SkillTargetType.TARGET_PARTY && sklTargetType != SkillTargetType.TARGET_ALLY && sklTargetType != SkillTargetType.TARGET_CORPSE_MOB && sklTargetType != SkillTargetType.TARGET_AREA_CORPSE_MOB && sklTargetType != SkillTargetType.TARGET_GROUND && sklType != SkillType.BEAST_FEED && sklType != SkillType.DELUXE_KEY_UNLOCK && sklType != SkillType.UNLOCK)
{
// send the action failed so that the skill doens't go off.
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
// Check if the skill is Spoil type and if the target isn't already spoiled
if(sklType == SkillType.SPOIL)
{
if(!(target instanceof L2MonsterInstance))
{
// Send a System Message to the L2PcInstance
sendPacket(new SystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
// Check if the skill is Sweep type and if conditions not apply
if(sklType == SkillType.SWEEP && target instanceof L2Attackable)
{
int spoilerId = ((L2Attackable) target).getIsSpoiledBy();
if(((L2Attackable) target).isDead())
{
if(!((L2Attackable) target).isSpoil())
{
// Send a System Message to the L2PcInstance
sendPacket(new SystemMessage(SystemMessageId.SWEEPER_FAILED_TARGET_NOT_SPOILED));
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
if(getObjectId() != spoilerId && !isInLooterParty(spoilerId))
{
// Send a System Message to the L2PcInstance
sendPacket(new SystemMessage(SystemMessageId.SWEEP_NOT_ALLOWED));
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
}
// Check if the skill is Drain Soul (Soul Crystals) and if the target is a MOB
if(sklType == SkillType.DRAIN_SOUL)
{
if(!(target instanceof L2MonsterInstance))
{
// Send a System Message to the L2PcInstance
sendPacket(new SystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
final Point3D worldPosition = getCurrentSkillWorldPosition();
if(sklTargetType == SkillTargetType.TARGET_GROUND && worldPosition == null)
{
_log.info("WorldPosition is null for skill: " + skill.getName() + ", player: " + getName() + ".");
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Check if this is a Pvp skill and target isn't a non-flagged/non-karma player
switch(sklTargetType)
{
case TARGET_PARTY:
case TARGET_ALLY: // For such skills, checkPvpSkill() is called from L2Skill.getTargetList()
case TARGET_CLAN: // For such skills, checkPvpSkill() is called from L2Skill.getTargetList()
case TARGET_AURA:
case TARGET_SELF:
case TARGET_GROUND:
break;
default:
//if pvp skill is not allowed for given target
if(!checkPvpSkill(target, skill) && !getAccessLevel().allowPeaceAttack() && (skill.getId() != 3261 && skill.getId() != 3260 && skill.getId() != 3262))
{
// Send a System Message to the L2PcInstance
sendPacket(new SystemMessage(SystemMessageId.TARGET_IS_INCORRECT));
// Send a Server->Client packet ActionFailed to the L2PcInstance
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
if(sklTargetType == SkillTargetType.TARGET_HOLY && !TakeCastle.checkIfOkToCastSealOfRule(this, false))
{
sendPacket(ActionFailed.STATIC_PACKET);
abortCast();
return;
}
if(sklType == SkillType.SIEGEFLAG && !SiegeFlag.checkIfOkToPlaceFlag(this, false))
{
sendPacket(ActionFailed.STATIC_PACKET);
abortCast();
return;
}
else if(sklType == SkillType.STRSIEGEASSAULT && !StrSiegeAssault.checkIfOkToUseStriderSiegeAssault(this, false))
{
sendPacket(ActionFailed.STATIC_PACKET);
abortCast();
return;
}
// TEMPFIX: Check client Z coordinate instead of server z to avoid exploit
// killing Zaken from others floor
if ((target instanceof L2GrandBossInstance) && ((L2GrandBossInstance) target).getNpcId() == 29022)
{
if (Math.abs(this.getClientZ() - target.getZ()) > 200)
{
sendPacket(new SystemMessage(SystemMessageId.CANT_SEE_TARGET));
getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
}
// GeoData Los Check here
if(skill.getCastRange() > 0 && !GeoData.getInstance().canSeeTarget(this, target))
{
sendPacket(new SystemMessage(SystemMessageId.CANT_SEE_TARGET));
sendPacket(ActionFailed.STATIC_PACKET);
return;
}
// Like L2OFF after a skill the player must stop the movement, also with toggle
stopMove(null);
// If all conditions are checked, create a new SkillDat object and set the player _currentSkill
setCurrentSkill(skill, forceUse, dontMove);
// Check if the active L2Skill can be casted (ex : not sleeping...), Check if the target is correct and Notify the AI with AI_INTENTION_CAST and target
super.useMagic(skill);
}
/**
* Checks if is in looter party.
* @param LooterId the looter id
* @return true, if is in looter party
*/
public boolean isInLooterParty(int LooterId)
{
L2PcInstance looter = L2World.getInstance().getPlayer(LooterId);
// if L2PcInstance is in a CommandChannel
if (isInParty() && getParty().isInCommandChannel() && looter != null)
return getParty().getCommandChannel().getMembers().contains(looter);
if (isInParty() && looter != null)
return getParty().getPartyMembers().contains(looter);
return false;
}
/*
public boolean checkPvpSkill(L2Object target, L2Skill skill)
{
if(target != null && (target instanceof L2PcInstance || target instanceof L2Summon))
{
L2PcInstance character;
if(target instanceof L2Summon)
{
if(((L2Summon) target).isInsideZone(ZONE_PVP))
{
return true;
}
character = ((L2Summon) target).getOwner();
}
else
{
character = (L2PcInstance) target;
}
if ((_inEventTvT && TvT.is_started()) || (_inEventDM && DM.is_started()) || (_inEventCTF && CTF.is_started()) || (_inEventVIP && VIP._started))
return true;
// check for PC->PC Pvp status
if(character != this && // target is not self and
!(isInDuel() && character.getDuelId() == getDuelId()) && // self is not in a duel and attacking opponent
!isInsideZone(ZONE_PVP) && // Pc is not in PvP zone
!character.isInsideZone(ZONE_PVP) // target is not in PvP zone
)
{
if(skill.isPvpSkill()) // pvp skill
{
if(getClan() != null && character.getClan() != null)
{
if(getClan().isAtWarWith(character.getClan().getClanId()) && character.getClan().isAtWarWith(getClan().getClanId()))
return true; // in clan war player can attack whites even with sleep etc.
}
if(character.getPvpFlag() == 0 && // target's pvp flag is not set and
character.getKarma() == 0 // target has no karma
)
return false;
}
else if(getCurrentSkill() != null && !getCurrentSkill().isCtrlPressed() && skill.isOffensive())
{
if(getClan() != null && character.getClan() != null)
{
if(getClan().isAtWarWith(character.getClan().getClanId()) && character.getClan().isAtWarWith(getClan().getClanId()))
return true; // in clan war player can attack whites even without ctrl
}
if(character.getPvpFlag() == 0 && // target's pvp flag is not set and
character.getKarma() == 0 // target has no karma
)
return false;
}
}
}
return true;
}
*/
/**
* Check if the requested casting is a Pc->Pc skill cast and if it's a valid pvp condition.
*
* @param target L2Object instance containing the target
* @param skill L2Skill instance with the skill being casted
* @return False if the skill is a pvpSkill and target is not a valid pvp target
*/
public boolean checkPvpSkill(L2Object target, L2Skill skill)
{
return checkPvpSkill(target, skill, false);
}
/**
* Check if the requested casting is a Pc->Pc skill cast and if it's a valid pvp condition.
* @param target L2Object instance containing the target
* @param skill L2Skill instance with the skill being casted
* @param srcIsSummon is L2Summon - caster?
* @return False if the skill is a pvpSkill and target is not a valid pvp target
*/
public boolean checkPvpSkill(L2Object target, L2Skill skill, boolean srcIsSummon)
{
if ((_inEventTvT && TvT.is_started()) || (_inEventDM && DM.is_started()) || (_inEventCTF && CTF.is_started()) || (_inEventVIP && VIP._started))
return true;
// check for PC->PC Pvp status
if (target instanceof L2Summon)
target = ((L2Summon) target).getOwner();
if (target != null && // target not null and
target != this && // target is not self and
target instanceof L2PcInstance && // target is L2PcInstance and
!(isInDuel() && ((L2PcInstance) target).getDuelId() == getDuelId()) && // self is not in a duel and attacking opponent
!isInsideZone(ZONE_PVP) && // Pc is not in PvP zone
!((L2PcInstance) target).isInsideZone(ZONE_PVP) && // target is not in PvP zone
!isInsideZone(ZONE_EVENT) &&
!((L2PcInstance) target).isInsideZone(ZONE_EVENT) &&
!((L2PcInstance) target).isinTownWar() &&
!isinTownWar() &&
!isInsideZone(ZONE_CHAOTIC) &&
!((L2PcInstance)target).isInsideZone(ZONE_CHAOTIC)) {
SkillDat skilldat = getCurrentSkill();
// SkillDat skilldatpet = getCurrentPetSkill();
if (skill.isPvpSkill()) // pvp skill
{
if (getClan() != null && ((L2PcInstance) target).getClan() != null)
{
if (getClan().isAtWarWith(((L2PcInstance) target).getClan().getClanId()) && ((L2PcInstance) target).getClan().isAtWarWith(getClan().getClanId()))
return true; // in clan war player can attack whites even with sleep etc.
}
if (((L2PcInstance) target).getPvpFlag() == 0 && // target's pvp flag is not set and
((L2PcInstance) target).getKarma() == 0 // target has no karma
)
return false;
}
else if ((skilldat != null && !skilldat.isCtrlPressed() && skill.isOffensive() && !srcIsSummon)
/* || (skilldatpet != null && !skilldatpet.isCtrlPressed() && skill.isOffensive() && srcIsSummon) */)
{
if (getClan() != null && ((L2PcInstance) target).getClan() != null)
{
if (getClan().isAtWarWith(((L2PcInstance) target).getClan().getClanId()) && ((L2PcInstance) target).getClan().isAtWarWith(getClan().getClanId()))
return true; // in clan war player can attack whites even without ctrl
}
if (((L2PcInstance) target).getPvpFlag() == 0 && // target's pvp flag is not set and
((L2PcInstance) target).getKarma() == 0 // target has no karma
)
return false;
}
}
return true;
}
/**
* Reduce Item quantity of the L2PcInstance Inventory and send it a Server->Client packet InventoryUpdate.<BR>
* <BR>
*
* @param itemConsumeId the item consume id
* @param itemCount the item count
*/
@Override
public void consumeItem(int itemConsumeId, int itemCount)
{
if(itemConsumeId != 0 && itemCount != 0)
{
destroyItemByItemId("Consume", itemConsumeId, itemCount, null, true);
}
}
/**
* Return True if the L2PcInstance is a Mage.<BR>
* <BR>
*
* @return true, if is mage class
*/
public boolean isMageClass()
{
return getClassId().isMage();
}
/**
* Checks if is mounted.
*
* @return true, if is mounted
*/
public boolean isMounted()
{
return _mountType > 0;
}
/**
* Set the type of Pet mounted (0 : none, 1 : Stridder, 2 : Wyvern) and send a Server->Client packet InventoryUpdate
* to the L2PcInstance.<BR>
* <BR>
*
* @return true, if successful
*/
public boolean checkLandingState()
{
// Check if char is in a no landing zone
if(isInsideZone(ZONE_NOLANDING))
return true;
else
// if this is a castle that is currently being sieged, and the rider is NOT a castle owner
// he cannot land.
// castle owner is the leader of the clan that owns the castle where the pc is
if(isInsideZone(ZONE_SIEGE) && !(getClan() != null && CastleManager.getInstance().getCastle(this) == CastleManager.getInstance().getCastleByOwner(getClan()) && this == getClan().getLeader().getPlayerInstance()))
return true;
return false;
}
// returns false if the change of mount type fails.
/**
* Sets the mount type.
*
* @param mountType the mount type
* @return true, if successful
*/
public boolean setMountType(int mountType)
{
if(checkLandingState() && mountType == 2)
return false;
switch(mountType)
{
case 0:
setIsFlying(false);
setIsRiding(false);
break; //Dismounted
case 1:
setIsRiding(true);
if(isNoble())
{
L2Skill striderAssaultSkill = SkillTable.getInstance().getInfo(325, 1);
addSkill(striderAssaultSkill, false); // not saved to DB
}
break;
case 2:
setIsFlying(true);
break; //Flying Wyvern
}
_mountType = mountType;
// Send a Server->Client packet InventoryUpdate to the L2PcInstance in order to update speed
UserInfo ui = new UserInfo(this);
sendPacket(ui);
ui = null;
return true;
}
/**
* Return the type of Pet mounted (0 : none, 1 : Stridder, 2 : Wyvern).<BR>
* <BR>
*
* @return the mount type
*/
public int getMountType()
{
return _mountType;
}
/**
* Send a Server->Client packet UserInfo to this L2PcInstance and CharInfo to all L2PcInstance in its _KnownPlayers.<BR>
* <BR>
* <B><U> Concept</U> :</B><BR>
* <BR>
* Others L2PcInstance in the detection area of the L2PcInstance are identified in <B>_knownPlayers</B>. In order to
* inform other players of this L2PcInstance state modifications, server just need to go through _knownPlayers to
* send Server->Client Packet<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>Send a Server->Client packet UserInfo to this L2PcInstance (Public and Private Data)</li> <li>Send a
* Server->Client packet CharInfo to all L2PcInstance in _KnownPlayers of the L2PcInstance (Public data only)</li><BR>
* <BR>
* <FONT COLOR=#FF0000><B> <U>Caution</U> : DON'T SEND UserInfo packet to other players instead of CharInfo packet.
* Indeed, UserInfo packet contains PRIVATE DATA as MaxHP, STR, DEX...</B></FONT><BR>
* <BR>
*/
@Override
public void updateAbnormalEffect()
{
broadcastUserInfo();
}
/**
* Disable the Inventory and create a new task to enable it after 1.5s.<BR>
* <BR>
*/
public void tempInvetoryDisable()
{
_inventoryDisable = true;
ThreadPoolManager.getInstance().scheduleGeneral(new InventoryEnable(), 1500);
}
/**
* Return True if the Inventory is disabled.<BR>
* <BR>
*
* @return true, if is invetory disabled
*/
public boolean isInvetoryDisabled()
{
return _inventoryDisable;
}
/**
* The Class InventoryEnable.
*/
class InventoryEnable implements Runnable
{
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
_inventoryDisable = false;
}
}
/**
* Gets the cubics.
* @return the cubics
*/
public Map<Integer, L2CubicInstance> getCubics()
{
synchronized (_cubics)
{
// clean cubics instances
Set<Integer> cubicsIds = _cubics.keySet();
for (Integer id : cubicsIds)
{
if (id == null || _cubics.get(id) == null)
try
{
_cubics.remove(id);
}
catch (NullPointerException e)
{
// FIXME: tried to remove a null key, to be found where this action has been performed (DEGUB)
}
}
return _cubics;
}
}
/**
* Add a L2CubicInstance to the L2PcInstance _cubics.<BR>
* <BR>
*
* @param id the id
* @param level the level
* @param matk the matk
* @param activationtime the activationtime
* @param activationchance the activationchance
* @param totalLifetime the total lifetime
* @param givenByOther the given by other
*/
/*public void addCubic(int id, int level, double d)
{
L2CubicInstance cubic = new L2CubicInstance(this, id, level,d);
_cubics.put(id, cubic);
cubic = null;
}*/
public void addCubic(int id, int level, double matk, int activationtime, int activationchance, int totalLifetime, boolean givenByOther)
{
if (Config.DEBUG)
_log.info("L2PcInstance(" + getName() + "): addCubic(" + id + "|" + level + "|" + matk + ")");
L2CubicInstance cubic = new L2CubicInstance(this, id, level, (int) matk, activationtime, activationchance, totalLifetime, givenByOther);
synchronized(_cubics){
_cubics.put(id, cubic);
}
}
/**
* Remove a L2CubicInstance from the L2PcInstance _cubics.<BR>
* <BR>
*
* @param id the id
*/
public void delCubic(int id)
{
synchronized(_cubics){
_cubics.remove(id);
}
}
/**
* Return the L2CubicInstance corresponding to the Identifier of the L2PcInstance _cubics.<BR>
* <BR>
*
* @param id the id
* @return the cubic
*/
public L2CubicInstance getCubic(int id)
{
synchronized(_cubics){
return _cubics.get(id);
}
}
public void unsummonAllCubics(){
// Unsummon Cubics
synchronized(_cubics){
if(_cubics.size() > 0)
{
for(L2CubicInstance cubic : _cubics.values())
{
cubic.stopAction();
cubic.cancelDisappear();
}
_cubics.clear();
}
}
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character#toString()
*/
@Override
public String toString()
{
return "player " + getName();
}
/**
* Return the modifier corresponding to the Enchant Effect of the Active Weapon (Min : 127).<BR>
* <BR>
*
* @return the enchant effect
*/
public int getEnchantEffect()
{
L2ItemInstance wpn = getActiveWeaponInstance();
if(wpn == null)
return 0;
return Math.min(127, wpn.getEnchantLevel());
}
/**
* Set the _lastFolkNpc of the L2PcInstance corresponding to the last Folk wich one the player talked.<BR>
* <BR>
*
* @param folkNpc the new last folk npc
*/
public void setLastFolkNPC(L2FolkInstance folkNpc)
{
_lastFolkNpc = folkNpc;
}
/**
* Return the _lastFolkNpc of the L2PcInstance corresponding to the last Folk wich one the player talked.<BR>
* <BR>
*
* @return the last folk npc
*/
public L2FolkInstance getLastFolkNPC()
{
return _lastFolkNpc;
}
/**
* Set the Silent Moving mode Flag.<BR>
* <BR>
* @param flag the new silent moving
*/
public void setSilentMoving(boolean flag)
{
if (flag)
_isSilentMoving++;
else
_isSilentMoving--;
}
/**
* Return True if the Silent Moving mode is active.<BR>
* <BR>
* @return true, if is silent moving
*/
public boolean isSilentMoving()
{
return _isSilentMoving > 0;
}
/**
* Return True if L2PcInstance is a participant in the Festival of Darkness.<BR>
* <BR>
*
* @return true, if is festival participant
*/
public boolean isFestivalParticipant()
{
return SevenSignsFestival.getInstance().isPlayerParticipant(this);
}
/**
* Adds the auto soul shot.
*
* @param itemId the item id
*/
public void addAutoSoulShot(int itemId)
{
_activeSoulShots.put(itemId, itemId);
}
/**
* Removes the auto soul shot.
*
* @param itemId the item id
*/
public void removeAutoSoulShot(int itemId)
{
_activeSoulShots.remove(itemId);
}
/**
* Gets the auto soul shot.
*
* @return the auto soul shot
*/
public Map<Integer, Integer> getAutoSoulShot()
{
return _activeSoulShots;
}
/**
* Recharge auto soul shot.
*
* @param physical the physical
* @param magic the magic
* @param summon the summon
*/
public void rechargeAutoSoulShot(boolean physical, boolean magic, boolean summon)
{
L2ItemInstance item;
IItemHandler handler;
if(_activeSoulShots == null || _activeSoulShots.size() == 0)
return;
for(int itemId : _activeSoulShots.values())
{
item = getInventory().getItemByItemId(itemId);
if(item != null)
{
if(magic)
{
if(!summon)
{
if(itemId == 2509 || itemId == 2510 || itemId == 2511 || itemId == 2512 || itemId == 2513 || itemId == 2514 || itemId == 3947 || itemId == 3948 || itemId == 3949 || itemId == 3950 || itemId == 3951 || itemId == 3952 || itemId == 5790)
{
handler = ItemHandler.getInstance().getItemHandler(itemId);
if(handler != null)
{
handler.useItem(this, item);
}
}
}
else
{
if(itemId == 6646 || itemId == 6647)
{
handler = ItemHandler.getInstance().getItemHandler(itemId);
if(handler != null)
{
handler.useItem(this, item);
}
}
}
}
if(physical)
{
if(!summon)
{
if(itemId == 1463 || itemId == 1464 || itemId == 1465 || itemId == 1466 || itemId == 1467 || itemId == 1835 || itemId == 5789 /*||
itemId == 6535 || itemId == 6536 || itemId == 6537 || itemId == 6538 || itemId == 6539 || itemId == 6540*/)
{
handler = ItemHandler.getInstance().getItemHandler(itemId);
if(handler != null)
{
handler.useItem(this, item);
}
}
}
else
{
if(itemId == 6645)
{
handler = ItemHandler.getInstance().getItemHandler(itemId);
if(handler != null)
{
handler.useItem(this, item);
}
}
}
}
}
else
{
removeAutoSoulShot(itemId);
}
}
item = null;
handler = null;
}
/** The _task warn user take break. */
private ScheduledFuture<?> _taskWarnUserTakeBreak;
/**
* The Class WarnUserTakeBreak.
*/
class WarnUserTakeBreak implements Runnable
{
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
if(isOnline() == 1)
{
SystemMessage msg = new SystemMessage(SystemMessageId.PLAYING_FOR_LONG_TIME);
L2PcInstance.this.sendPacket(msg);
msg = null;
}
else
{
stopWarnUserTakeBreak();
}
}
}
/** The _task bot checker. */
private ScheduledFuture<?> _taskBotChecker;
/** The _task kick bot. */
protected ScheduledFuture<?> _taskKickBot;
/**
* The Class botChecker.
*/
class botChecker implements Runnable
{
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
/* Start bot checker if player is in combat online without shop and in a zone not peacefull */
if(isOnline() == 1
&& isInCombat()
&& getPrivateStoreType() == 0
&& !isInsideZone(L2Character.ZONE_PEACE))
{
try
{
String text = HtmCache.getInstance().getHtm("data/html/custom/bot.htm");
String word = Config.QUESTION_LIST.get(Rnd.get(Config.QUESTION_LIST.size()));
String output;
_correctWord = Rnd.get(5)+1;
text = text.replace("%Time%", Integer.toString(Config.BOT_PROTECTOR_WAIT_ANSVER));
for(int i = 1; i <= 5; i++)
{
if(i != _correctWord)
{
output = RandomStringUtils.random(word.length(), word);
}else{
output = word;
}
text = text.replace("%Word"+i+"%", output);
if(i == _correctWord)
{
text = text.replace("%Word%", output);
}
}
L2PcInstance.this.sendPacket(new TutorialShowHtml(text));
if(_taskKickBot == null)
{
_stopKickBotTask = false;
_taskKickBot = ThreadPoolManager.getInstance().scheduleGeneral(new kickBot(), 10);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
else
{
stopBotChecker();
}
}
}
/**
* The Class kickBot.
*/
class kickBot implements Runnable
{
/*
* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@SuppressWarnings("synthetic-access")
@Override
public void run()
{
if (isOnline() == 1 && getPrivateStoreType() == 0 && !isGM())
{
for (int i = Config.BOT_PROTECTOR_WAIT_ANSVER; i >= 10; i -= 10)
{
if (_stopKickBotTask)
{
if (_taskKickBot != null)
{
_taskKickBot = null;
}
_stopKickBotTask = false;
return;
}
L2PcInstance.this.sendMessage("You have " + i + " seconds to choose the answer.");
try
{
Thread.sleep(10000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
if (_stopKickBotTask)
{
if (_taskKickBot != null)
{
_taskKickBot = null;
}
_stopKickBotTask = false;
return;
}
_log.warning("Player " + L2PcInstance.this.getName() + " kicked from game, no/wrong answer on ANTI BOT!");
L2PcInstance.this.closeNetConnection();
}
else
{
if (_taskKickBot != null)
{
_taskKickBot = null;
}
_stopKickBotTask = false;
}
}
}
/**
* The Class RentPetTask.
*/
class RentPetTask implements Runnable
{
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
stopRentPet();
}
}
/** The _taskforfish. */
public ScheduledFuture<?> _taskforfish;
/**
* The Class WaterTask.
*/
class WaterTask implements Runnable
{
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
double reduceHp = getMaxHp() / 100.0;
if(reduceHp < 1)
{
reduceHp = 1;
}
reduceCurrentHp(reduceHp, L2PcInstance.this, false);
//reduced hp, becouse not rest
SystemMessage sm = new SystemMessage(SystemMessageId.DROWN_DAMAGE_S1);
sm.addNumber((int) reduceHp);
sendPacket(sm);
sm = null;
}
}
/**
* The Class LookingForFishTask.
*/
class LookingForFishTask implements Runnable
{
/** The _is upper grade. */
boolean _isNoob, _isUpperGrade;
/** The _guts check time. */
int _fishType, _fishGutsCheck, _gutsCheckTime;
/** The _end task time. */
long _endTaskTime;
/**
* Instantiates a new looking for fish task.
*
* @param fishWaitTime the fish wait time
* @param fishGutsCheck the fish guts check
* @param fishType the fish type
* @param isNoob the is noob
* @param isUpperGrade the is upper grade
*/
protected LookingForFishTask(int fishWaitTime, int fishGutsCheck, int fishType, boolean isNoob, boolean isUpperGrade)
{
_fishGutsCheck = fishGutsCheck;
_endTaskTime = System.currentTimeMillis() + fishWaitTime + 10000;
_fishType = fishType;
_isNoob = isNoob;
_isUpperGrade = isUpperGrade;
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
if(System.currentTimeMillis() >= _endTaskTime)
{
EndFishing(false);
return;
}
if(_fishType == -1)
return;
int check = Rnd.get(1000);
if(_fishGutsCheck > check)
{
stopLookingForFishTask();
StartFishCombat(_isNoob, _isUpperGrade);
}
}
}
/**
* Gets the clan privileges.
*
* @return the clan privileges
*/
public int getClanPrivileges()
{
return _clanPrivileges;
}
/**
* Sets the clan privileges.
*
* @param n the new clan privileges
*/
public void setClanPrivileges(int n)
{
_clanPrivileges = n;
}
// baron etc
/**
* Sets the pledge class.
*
* @param classId the new pledge class
*/
public void setPledgeClass(int classId)
{
_pledgeClass = classId;
}
/**
* Gets the pledge class.
*
* @return the pledge class
*/
public int getPledgeClass()
{
return _pledgeClass;
}
/**
* Sets the pledge type.
*
* @param typeId the new pledge type
*/
public void setPledgeType(int typeId)
{
_pledgeType = typeId;
}
/**
* Gets the pledge type.
*
* @return the pledge type
*/
public int getPledgeType()
{
return _pledgeType;
}
/**
* Gets the apprentice.
*
* @return the apprentice
*/
public int getApprentice()
{
return _apprentice;
}
/**
* Sets the apprentice.
*
* @param apprentice_id the new apprentice
*/
public void setApprentice(int apprentice_id)
{
_apprentice = apprentice_id;
}
/**
* Gets the sponsor.
*
* @return the sponsor
*/
public int getSponsor()
{
return _sponsor;
}
/**
* Sets the sponsor.
*
* @param sponsor_id the new sponsor
*/
public void setSponsor(int sponsor_id)
{
_sponsor = sponsor_id;
}
/**
* Send message.
*
* @param message the message
*/
public void sendMessage(String message)
{
sendPacket(SystemMessage.sendString(message));
}
/** The _was invisible. */
private boolean _wasInvisible = false;
/**
* Enter observer mode.
*
* @param x
* the x
* @param y
* the y
* @param z
* the z
*/
public void enterObserverMode(int x, int y, int z) {
_obsX = getX();
_obsY = getY();
_obsZ = getZ();
// Unsummon pet while entering on Observer mode
if (getPet() != null)
getPet().unSummon(this);
// Unsummon cubics while entering on Observer mode
unsummonAllCubics();
_observerMode = true;
setTarget(null);
stopMove(null);
setIsParalyzed(true);
setIsInvul(true);
_wasInvisible = getAppearance().getInvisible();
getAppearance().setInvisible();
sendPacket(new ObservationMode(x, y, z));
getKnownList().removeAllKnownObjects(); // reinit knownlist
setXYZ(x, y, z);
teleToLocation(x, y, z, false);
broadcastUserInfo();
}
/**
* Enter olympiad observer mode.
*
* @param x
* the x
* @param y
* the y
* @param z
* the z
* @param id
* the id
*/
public void enterOlympiadObserverMode(int x, int y, int z, int id) {
// Unsummon pet while entering on Observer mode
if (getPet() != null)
getPet().unSummon(this);
// Unsummon cubics while entering on Observer mode
unsummonAllCubics();
if (getParty() != null)
getParty().removePartyMember(this);
_olympiadGameId = id;
if (isSitting())
standUp();
if (!_observerMode) {
_obsX = getX();
_obsY = getY();
_obsZ = getZ();
}
_observerMode = true;
setTarget(null);
setIsInvul(true);
_wasInvisible = getAppearance().getInvisible();
getAppearance().setInvisible();
teleToLocation(x, y, z, false);
sendPacket(new ExOlympiadMode(3));
broadcastUserInfo();
}
/**
* Leave observer mode.
*/
public void leaveObserverMode()
{
if(!_observerMode)
{
_log.warning("Player " + L2PcInstance.this.getName() + " request leave observer mode when he not use it!");
Util.handleIllegalPlayerAction(L2PcInstance.this, "Warning!! Character " + L2PcInstance.this.getName() + " tried to cheat in observer mode.", Config.DEFAULT_PUNISH);
}
setTarget(null);
setXYZ(_obsX, _obsY, _obsZ);
setIsParalyzed(false);
if(_wasInvisible){
getAppearance().setInvisible();
}else
getAppearance().setVisible();
setIsInvul(false);
if(getAI() != null)
{
getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
}
teleToLocation(_obsX, _obsY, _obsZ, false);
_observerMode = false;
sendPacket(new ObservationReturn(this));
if(!_wasInvisible)
broadcastUserInfo();
}
/**
* Leave olympiad observer mode.
*/
public void leaveOlympiadObserverMode()
{
setTarget(null);
sendPacket(new ExOlympiadMode(0));
teleToLocation(_obsX, _obsY, _obsZ, true);
getAppearance().setVisible();
setIsInvul(false);
if(getAI() != null)
{
getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
}
Olympiad.getInstance();
Olympiad.removeSpectator(_olympiadGameId, this);
_olympiadGameId = -1;
_observerMode = false;
if(!_wasInvisible)
broadcastUserInfo();
}
/**
* Update name title color.
*/
public void updateNameTitleColor()
{
/** Updates title and name color of a donator **/
if(Config.DONATOR_NAME_COLOR_ENABLED && isDonator())
{
getAppearance().setNameColor(Config.DONATOR_NAME_COLOR);
getAppearance().setTitleColor(Config.DONATOR_TITLE_COLOR);
}
}
/**
* Update gm name title color.
*/
public void updateGmNameTitleColor()// KidZor: needs to be finished when Acces levels system is complite
{
//if this is a GM but has disabled his gM status, so we clear name / title
if(isGM() && !hasGmStatusActive())
{
getAppearance().setNameColor(0xFFFFFF);
getAppearance().setTitleColor(0xFFFF77);
}
// this is a GM but has GM status enabled, so we must set proper values
else if(isGM() && hasGmStatusActive())
{
// Nick Updates
if(getAccessLevel().useNameColor())
{
// this is a normal GM
if(isNormalGm())
{
getAppearance().setNameColor(getAccessLevel().getNameColor());
}
else if(isAdministrator())
{
getAppearance().setNameColor(Config.MASTERACCESS_NAME_COLOR);
}
}
else
{
getAppearance().setNameColor(0xFFFFFF);
}
// Title Updates
if(getAccessLevel().useTitleColor())
{
// this is a normal GM
if(isNormalGm())
{
getAppearance().setTitleColor(getAccessLevel().getTitleColor());
}
else if(isAdministrator())
{
getAppearance().setTitleColor(Config.MASTERACCESS_TITLE_COLOR);
}
}
else
{
getAppearance().setTitleColor(0xFFFF77);
}
}
}
/**
* Sets the olympiad side.
*
* @param i the new olympiad side
*/
public void setOlympiadSide(int i)
{
_olympiadSide = i;
}
/**
* Gets the olympiad side.
*
* @return the olympiad side
*/
public int getOlympiadSide()
{
return _olympiadSide;
}
/**
* Sets the olympiad game id.
*
* @param id the new olympiad game id
*/
public void setOlympiadGameId(int id)
{
_olympiadGameId = id;
}
/**
* Gets the olympiad game id.
*
* @return the olympiad game id
*/
public int getOlympiadGameId()
{
return _olympiadGameId;
}
/**
* Gets the obs x.
*
* @return the obs x
*/
public int getObsX()
{
return _obsX;
}
/**
* Gets the obs y.
*
* @return the obs y
*/
public int getObsY()
{
return _obsY;
}
/**
* Gets the obs z.
*
* @return the obs z
*/
public int getObsZ()
{
return _obsZ;
}
/**
* In observer mode.
*
* @return true, if successful
*/
public boolean inObserverMode()
{
return _observerMode;
}
/**
* Gets the tele mode.
*
* @return the tele mode
*/
public int getTeleMode()
{
return _telemode;
}
/**
* Sets the tele mode.
*
* @param mode the new tele mode
*/
public void setTeleMode(int mode)
{
_telemode = mode;
}
/**
* Sets the loto.
*
* @param i the i
* @param val the val
*/
public void setLoto(int i, int val)
{
_loto[i] = val;
}
/**
* Gets the loto.
*
* @param i the i
* @return the loto
*/
public int getLoto(int i)
{
return _loto[i];
}
/**
* Sets the race.
*
* @param i the i
* @param val the val
*/
public void setRace(int i, int val)
{
_race[i] = val;
}
/**
* Gets the race.
*
* @param i the i
* @return the race
*/
public int getRace(int i)
{
return _race[i];
}
/*
public void setChatBanned(boolean isBanned)
{
_chatBanned = isBanned;
if(isChatBanned())
{
sendMessage("You have been chat banned by a server admin.");
}
else
{
sendMessage("Your chat ban has been lifted.");
if(_chatUnbanTask != null)
{
_chatUnbanTask.cancel(false);
}
_chatUnbanTask = null;
}
sendPacket(new EtcStatusUpdate(this));
}
public boolean isChatBanned()
{
return _chatBanned;
}
public void setChatUnbanTask(ScheduledFuture<?> task)
{
_chatUnbanTask = task;
}
public ScheduledFuture<?> getChatUnbanTask()
{
return _chatUnbanTask;
}
*/
/**
* Send a Server->Client packet StatusUpdate to the L2PcInstance.<BR><BR>
*/
@Override
public void sendPacket(L2GameServerPacket packet)
{
if (_client != null)
{
_client.sendPacket(packet);
}
}
/**
* Send SystemMessage packet.<BR><BR>
* @param id
*/
public void sendPacket(SystemMessageId id)
{
sendPacket(SystemMessage.getSystemMessage(id));
}
/**
* Gets the message refusal.
*
* @return the message refusal
*/
public boolean getMessageRefusal()
{
return _messageRefusal;
}
/**
* Sets the message refusal.
*
* @param mode the new message refusal
*/
public void setMessageRefusal(boolean mode)
{
_messageRefusal = mode;
sendPacket(new EtcStatusUpdate(this));
}
/**
* Sets the diet mode.
*
* @param mode the new diet mode
*/
public void setDietMode(boolean mode)
{
_dietMode = mode;
}
/**
* Gets the diet mode.
*
* @return the diet mode
*/
public boolean getDietMode()
{
return _dietMode;
}
/**
* Sets the exchange refusal.
*
* @param mode the new exchange refusal
*/
public void setExchangeRefusal(boolean mode)
{
_exchangeRefusal = mode;
}
/**
* Gets the exchange refusal.
*
* @return the exchange refusal
*/
public boolean getExchangeRefusal()
{
return _exchangeRefusal;
}
/**
* Gets the block list.
*
* @return the block list
*/
public BlockList getBlockList()
{
return _blockList;
}
/**
* Sets the hero aura.
*
* @param heroAura the new hero aura
*/
public void setHeroAura (boolean heroAura)
{
isPVPHero = heroAura;
return;
}
/**
* Gets the checks if is pvp hero.
*
* @return the checks if is pvp hero
*/
public boolean getIsPVPHero()
{
return isPVPHero;
}
/**
* Gets the count.
*
* @return the count
*/
public int getCount()
{
String HERO_COUNT = "SELECT count FROM heroes WHERE char_name=?";
int _count = 0;
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement(HERO_COUNT);
statement.setString(1, getName());
ResultSet rset = statement.executeQuery();
while(rset.next())
{
_count = rset.getInt("count");
}
rset.close();
statement.close();
statement = null;
rset = null;
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
CloseUtil.close(con);
con = null;
}
if(_count != 0)
return _count;
return 0;
}
/**
* Reload pvp hero aura.
*/
public void reloadPVPHeroAura()
{
sendPacket(new UserInfo(this));
}
/**
* Sets the checks if is hero.
*
* @param hero the new checks if is hero
*/
/*
public void setIsHero(boolean hero)
{
if(hero && _baseClass == _activeClass)
{
for(L2Skill s : HeroSkillTable.getHeroSkills())
{
addSkill(s, false); //Dont Save Hero skills to database
}
}
else if(getCount() >= Config.HERO_COUNT && hero && Config.ALLOW_HERO_SUBSKILL)
{
for(L2Skill s : HeroSkillTable.getHeroSkills())
{
addSkill(s, false); //Dont Save Hero skills to database
}
}
else
{
for(L2Skill s : HeroSkillTable.getHeroSkills())
{
super.removeSkill(s); //Just Remove skills from nonHero characters
}
}
_hero = hero;
sendSkillList();
}
*/
/**
* Sets the donator.
*
* @param value the new donator
*/
public void setDonator(boolean value)
{
_donator = value;
}
/**
* Checks if is donator.
*
* @return true, if is donator
*/
public boolean isDonator()
{
return _donator;
}
/**
* Checks if is away.
*
* @return true, if is away
*/
public boolean isAway()
{
return _isAway;
}
/**
* Sets the checks if is away.
*
* @param state the new checks if is away
*/
public void setIsAway(boolean state)
{
_isAway = state;
}
/**
* Sets the checks if is in olympiad mode.
*
* @param b the new checks if is in olympiad mode
*/
public void setIsInOlympiadMode(boolean b)
{
_inOlympiadMode = b;
}
/**
* Sets the checks if is olympiad start.
*
* @param b the new checks if is olympiad start
*/
public void setIsOlympiadStart(boolean b)
{
_OlympiadStart = b;
}
/**
* Checks if is olympiad start.
*
* @return true, if is olympiad start
*/
public boolean isOlympiadStart()
{
return _OlympiadStart;
}
/**
* Sets the olympiad position.
*
* @param pos the new olympiad position
*/
public void setOlympiadPosition(int[] pos)
{
_OlympiadPosition = pos;
}
/**
* Gets the olympiad position.
*
* @return the olympiad position
*/
public int[] getOlympiadPosition()
{
return _OlympiadPosition;
}
/**
* Checks if is hero.
*
* @return true, if is hero
*/
public boolean isHero()
{
return _hero;
}
/**
* Checks if is in olympiad mode.
*
* @return true, if is in olympiad mode
*/
public boolean isInOlympiadMode()
{
return _inOlympiadMode;
}
/**
* Checks if is in duel.
*
* @return true, if is in duel
*/
public boolean isInDuel()
{
return _isInDuel;
}
/**
* Gets the duel id.
*
* @return the duel id
*/
public int getDuelId()
{
return _duelId;
}
/**
* Sets the duel state.
*
* @param mode the new duel state
*/
public void setDuelState(int mode)
{
_duelState = mode;
}
/**
* Gets the duel state.
*
* @return the duel state
*/
public int getDuelState()
{
return _duelState;
}
/**
* Sets the coupon.
*
* @param coupon the new coupon
*/
public void setCoupon(int coupon)
{
if(coupon >= 0 && coupon <= 3)
{
_hasCoupon = coupon;
}
}
/**
* Adds the coupon.
*
* @param coupon the coupon
*/
public void addCoupon(int coupon)
{
if(coupon == 1 || coupon == 2 && !getCoupon(coupon - 1))
{
_hasCoupon += coupon;
}
}
/**
* Gets the coupon.
*
* @param coupon the coupon
* @return the coupon
*/
public boolean getCoupon(int coupon)
{
return (_hasCoupon == 1 || _hasCoupon == 3) && coupon == 0 || (_hasCoupon == 2 || _hasCoupon == 3) && coupon == 1;
}
/**
* Sets up the duel state using a non 0 duelId.
*
* @param duelId 0=not in a duel
*/
public void setIsInDuel(int duelId)
{
if(duelId > 0)
{
_isInDuel = true;
_duelState = Duel.DUELSTATE_DUELLING;
_duelId = duelId;
}
else
{
if(_duelState == Duel.DUELSTATE_DEAD)
{
enableAllSkills();
getStatus().startHpMpRegeneration();
}
_isInDuel = false;
_duelState = Duel.DUELSTATE_NODUEL;
_duelId = 0;
}
}
/**
* This returns a SystemMessage stating why the player is not available for duelling.
*
* @return S1_CANNOT_DUEL... message
*/
public SystemMessage getNoDuelReason()
{
SystemMessage sm = new SystemMessage(_noDuelReason);
sm.addString(getName());
_noDuelReason = SystemMessageId.THERE_IS_NO_OPPONENT_TO_RECEIVE_YOUR_CHALLENGE_FOR_A_DUEL;
return sm;
}
/**
* Checks if this player might join / start a duel. To get the reason use getNoDuelReason() after calling this
* function.
*
* @return true if the player might join/start a duel.
*/
public boolean canDuel()
{
if(isInCombat() || isInJail())
{
_noDuelReason = SystemMessageId.S1_CANNOT_DUEL_BECAUSE_S1_IS_CURRENTLY_ENGAGED_IN_BATTLE;
return false;
}
if(isDead() || isAlikeDead() || getCurrentHp() < getMaxHp() / 2 || getCurrentMp() < getMaxMp() / 2)
{
_noDuelReason = SystemMessageId.S1_CANNOT_DUEL_BECAUSE_S1S_HP_OR_MP_IS_BELOW_50_PERCENT;
return false;
}
if(isInDuel())
{
_noDuelReason = SystemMessageId.S1_CANNOT_DUEL_BECAUSE_S1_IS_ALREADY_ENGAGED_IN_A_DUEL;
return false;
}
if(isInOlympiadMode())
{
_noDuelReason = SystemMessageId.S1_CANNOT_DUEL_BECAUSE_S1_IS_PARTICIPATING_IN_THE_OLYMPIAD;
return false;
}
if(isCursedWeaponEquiped())
{
_noDuelReason = SystemMessageId.S1_CANNOT_DUEL_BECAUSE_S1_IS_IN_A_CHAOTIC_STATE;
return false;
}
if(getPrivateStoreType() != STORE_PRIVATE_NONE)
{
_noDuelReason = SystemMessageId.S1_CANNOT_DUEL_BECAUSE_S1_IS_CURRENTLY_ENGAGED_IN_A_PRIVATE_STORE_OR_MANUFACTURE;
return false;
}
if(isMounted() || isInBoat())
{
_noDuelReason = SystemMessageId.S1_CANNOT_DUEL_BECAUSE_S1_IS_CURRENTLY_RIDING_A_BOAT_WYVERN_OR_STRIDER;
return false;
}
if(isFishing())
{
_noDuelReason = SystemMessageId.S1_CANNOT_DUEL_BECAUSE_S1_IS_CURRENTLY_FISHING;
return false;
}
if(isInsideZone(ZONE_PVP) || isInsideZone(ZONE_PEACE) || isInsideZone(ZONE_SIEGE) || isInsideZone(ZONE_EVENT))
{
_noDuelReason = SystemMessageId.S1_CANNOT_MAKE_A_CHALLANGE_TO_A_DUEL_BECAUSE_S1_IS_CURRENTLY_IN_A_DUEL_PROHIBITED_AREA;
return false;
}
return true;
}
/**
* Checks if is noble.
*
* @return true, if is noble
*/
public boolean isNoble()
{
return _noble;
}
/**
* Sets the noble.
*
* @param val the new noble
*/
public void setNoble(boolean val)
{
if(val)
{
for(L2Skill s : NobleSkillTable.getInstance().GetNobleSkills())
{
addSkill(s, false); //Dont Save Noble skills to Sql
}
}
else
{
for(L2Skill s : NobleSkillTable.getInstance().GetNobleSkills())
{
super.removeSkill(s); //Just Remove skills without deleting from Sql
}
}
_noble = val;
sendSkillList();
}
public String getHWid()
{
if (getClient() == null)
return _hwid;
_hwid = getClient().getHWid();
return _hwid;
}
public String getLastHwId()
{
return _hwid;
}
/**
* Adds the clan leader skills.
*
* @param val the val
*/
public void addClanLeaderSkills(boolean val)
{
if(val)
{
SiegeManager.getInstance().addSiegeSkills(this);
/*
for(L2Skill s : ClanLeaderSkillTable.getInstance().GetClanLeaderSkills())
{
addSkill(s, false); //Dont Save Noble skills to Sql
}
*/
}
else
{
SiegeManager.getInstance().removeSiegeSkills(this);
/*
for(L2Skill s : ClanLeaderSkillTable.getInstance().GetClanLeaderSkills())
{
super.removeSkill(s); //Just Remove skills without deleting from Sql
}
*/
}
sendSkillList();
}
/**
* Sets the lvl joined academy.
*
* @param lvl the new lvl joined academy
*/
public void setLvlJoinedAcademy(int lvl)
{
_lvlJoinedAcademy = lvl;
}
/**
* Gets the lvl joined academy.
*
* @return the lvl joined academy
*/
public int getLvlJoinedAcademy()
{
return _lvlJoinedAcademy;
}
/**
* Checks if is academy member.
*
* @return true, if is academy member
*/
public boolean isAcademyMember()
{
return _lvlJoinedAcademy > 0;
}
/**
* Sets the team.
*
* @param team the new team
*/
public void setTeam(int team)
{
_team = team;
}
/**
* Gets the team.
*
* @return the team
*/
public int getTeam()
{
return _team;
}
/**
* Sets the wants peace.
*
* @param wantsPeace the new wants peace
*/
public void setWantsPeace(int wantsPeace)
{
_wantsPeace = wantsPeace;
}
/**
* Gets the wants peace.
*
* @return the wants peace
*/
public int getWantsPeace()
{
return _wantsPeace;
}
/**
* Checks if is fishing.
*
* @return true, if is fishing
*/
public boolean isFishing()
{
return _fishing;
}
/**
* Sets the fishing.
*
* @param fishing the new fishing
*/
public void setFishing(boolean fishing)
{
_fishing = fishing;
}
/**
* Sets the alliance with varka ketra.
*
* @param sideAndLvlOfAlliance the new alliance with varka ketra
*/
public void setAllianceWithVarkaKetra(int sideAndLvlOfAlliance)
{
// [-5,-1] varka, 0 neutral, [1,5] ketra
_alliedVarkaKetra = sideAndLvlOfAlliance;
}
/**
* Gets the alliance with varka ketra.
*
* @return the alliance with varka ketra
*/
public int getAllianceWithVarkaKetra()
{
return _alliedVarkaKetra;
}
/**
* Checks if is allied with varka.
*
* @return true, if is allied with varka
*/
public boolean isAlliedWithVarka()
{
return _alliedVarkaKetra < 0;
}
/**
* Checks if is allied with ketra.
*
* @return true, if is allied with ketra
*/
public boolean isAlliedWithKetra()
{
return _alliedVarkaKetra > 0;
}
/**
* Send skill list.
*/
public void sendSkillList()
{
sendSkillList(this);
}
/**
* Send skill list.
*
* @param player the player
*/
public void sendSkillList(L2PcInstance player)
{
SkillList sl = new SkillList();
if(player != null)
{
for(L2Skill s : player.getAllSkills())
{
if(s == null)
{
continue;
}
if(s.getId() > 9000)
{
continue; // Fake skills to change base stats
}
if(s.bestowed())
{
continue;
}
if(s.isChance())
{
sl.addSkill(s.getId(), s.getLevel(), s.isChance());
}
else
{
sl.addSkill(s.getId(), s.getLevel(), s.isPassive());
}
}
}
sendPacket(sl);
sl = null;
}
/**
* 1. Add the specified class ID as a subclass (up to the maximum number of <b>three</b>) for this character.<BR>
* 2. This method no longer changes the active _classIndex of the player. This is only done by the calling of
* setActiveClass() method as that should be the only way to do so.
*
* @param classId the class id
* @param classIndex the class index
* @return boolean subclassAdded
*/
public synchronized boolean addSubClass(int classId, int classIndex)
{
// Reload skills from armors / jewels / weapons
getInventory().reloadEquippedItems();
// Remove Item RHAND
if(Config.REMOVE_WEAPON_SUBCLASS)
{
L2ItemInstance rhand = getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
if (rhand != null)
{
L2ItemInstance[] unequipped = getInventory().unEquipItemInBodySlotAndRecord(rhand.getItem().getBodyPart());
InventoryUpdate iu = new InventoryUpdate();
for (L2ItemInstance element : unequipped)
iu.addModifiedItem(element);
sendPacket(iu);
}
}
// Remove Item CHEST
if(Config.REMOVE_CHEST_SUBCLASS)
{
L2ItemInstance chest = getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST);
if (chest != null)
{
L2ItemInstance[] unequipped = getInventory().unEquipItemInBodySlotAndRecord(chest.getItem().getBodyPart());
InventoryUpdate iu = new InventoryUpdate();
for (L2ItemInstance element : unequipped)
iu.addModifiedItem(element);
sendPacket(iu);
}
}
// Remove Item LEG
if(Config.REMOVE_LEG_SUBCLASS)
{
L2ItemInstance legs = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LEGS);
if (legs != null)
{
L2ItemInstance[] unequipped = getInventory().unEquipItemInBodySlotAndRecord(legs.getItem().getBodyPart());
InventoryUpdate iu = new InventoryUpdate();
for (L2ItemInstance element : unequipped)
iu.addModifiedItem(element);
sendPacket(iu);
}
}
if(getTotalSubClasses() == Config.ALLOWED_SUBCLASS || classIndex == 0)
return false;
if(getSubClasses().containsKey(classIndex))
return false;
// Note: Never change _classIndex in any method other than setActiveClass().
SubClass newClass = new SubClass();
newClass.setClassId(classId);
newClass.setClassIndex(classIndex);
boolean output = false;
Connection con = null;
try
{
// Store the basic info about this new sub-class.
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement(ADD_CHAR_SUBCLASS);
statement.setInt(1, getObjectId());
statement.setInt(2, newClass.getClassId());
statement.setLong(3, newClass.getExp());
statement.setInt(4, newClass.getSp());
statement.setInt(5, newClass.getLevel());
statement.setInt(6, newClass.getClassIndex()); // <-- Added
statement.execute();
statement.close();
statement = null;
output=true;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("WARNING: Could not add character sub class for " + getName() + ": " + e);
}
finally
{
CloseUtil.close(con);
con = null;
}
if(output){
// Commit after database INSERT incase exception is thrown.
getSubClasses().put(newClass.getClassIndex(), newClass);
if(Config.DEBUG)
{
_log.info(getName() + " added class ID " + classId + " as a sub class at index " + classIndex + ".");
}
ClassId subTemplate = ClassId.values()[classId];
Collection<L2SkillLearn> skillTree = SkillTreeTable.getInstance().getAllowedSkills(subTemplate);
subTemplate = null;
if(skillTree == null)
return true;
Map<Integer, L2Skill> prevSkillList = new FastMap<Integer, L2Skill>();
for(L2SkillLearn skillInfo : skillTree)
{
if(skillInfo.getMinLevel() <= 40)
{
final L2Skill prevSkill = prevSkillList.get(skillInfo.getId());
final L2Skill newSkill = SkillTable.getInstance().getInfo(skillInfo.getId(), skillInfo.getLevel());
if(newSkill== null || prevSkill != null && prevSkill.getLevel() > newSkill.getLevel())
{
continue;
}
prevSkillList.put(newSkill.getId(), newSkill);
storeSkill(newSkill, prevSkill, classIndex);
}
}
skillTree = null;
prevSkillList = null;
if(Config.DEBUG)
{
_log.info(getName() + " was given " + getAllSkills().length + " skills for their new sub class.");
}
}
return output;
}
/**
* 1. Completely erase all existance of the subClass linked to the classIndex.<BR>
* 2. Send over the newClassId to addSubClass()to create a new instance on this classIndex.<BR>
* 3. Upon Exception, revert the player to their BaseClass to avoid further problems.<BR>
*
* @param classIndex the class index
* @param newClassId the new class id
* @return boolean subclassAdded
*/
public boolean modifySubClass(int classIndex, int newClassId)
{
int oldClassId = getSubClasses().get(classIndex).getClassId();
if(Config.DEBUG)
{
_log.info(getName() + " has requested to modify sub class index " + classIndex + " from class ID " + oldClassId + " to " + newClassId + ".");
}
boolean output = false;
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement;
// Remove all henna info stored for this sub-class.
statement = con.prepareStatement(DELETE_CHAR_HENNAS);
statement.setInt(1, getObjectId());
statement.setInt(2, classIndex);
statement.execute();
statement.close();
// Remove all shortcuts info stored for this sub-class.
statement = con.prepareStatement(DELETE_CHAR_SHORTCUTS);
statement.setInt(1, getObjectId());
statement.setInt(2, classIndex);
statement.execute();
statement.close();
// Remove all effects info stored for this sub-class.
statement = con.prepareStatement(DELETE_SKILL_SAVE);
statement.setInt(1, getObjectId());
statement.setInt(2, classIndex);
statement.execute();
statement.close();
// Remove all skill info stored for this sub-class.
statement = con.prepareStatement(DELETE_CHAR_SKILLS);
statement.setInt(1, getObjectId());
statement.setInt(2, classIndex);
statement.execute();
statement.close();
// Remove all basic info stored about this sub-class.
statement = con.prepareStatement(DELETE_CHAR_SUBCLASS);
statement.setInt(1, getObjectId());
statement.setInt(2, classIndex);
statement.execute();
statement.close();
statement = null;
output = true;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("Could not modify sub class for " + getName() + " to class index " + classIndex + ": " + e);
}
finally
{
CloseUtil.close(con);
con = null;
}
getSubClasses().remove(classIndex);
if(output){
return addSubClass(newClassId, classIndex);
}
return false;
}
/**
* Checks if is sub class active.
*
* @return true, if is sub class active
*/
public boolean isSubClassActive()
{
return _classIndex > 0;
}
/**
* Gets the sub classes.
*
* @return the sub classes
*/
public Map<Integer, SubClass> getSubClasses()
{
if(_subClasses == null)
{
_subClasses = new FastMap<Integer, SubClass>();
}
return _subClasses;
}
/**
* Gets the total sub classes.
*
* @return the total sub classes
*/
public int getTotalSubClasses()
{
return getSubClasses().size();
}
/**
* Gets the base class.
*
* @return the base class
*/
public int getBaseClass()
{
return _baseClass;
}
/**
* Gets the active class.
*
* @return the active class
*/
public synchronized int getActiveClass()
{
return _activeClass;
}
/**
* Gets the class index.
*
* @return the class index
*/
public int getClassIndex()
{
return _classIndex;
}
/**
* Sets the class template.
*
* @param classId the new class template
*/
private synchronized void setClassTemplate(int classId)
{
_activeClass = classId;
L2PcTemplate t = CharTemplateTable.getInstance().getTemplate(classId);
if(t == null)
{
_log.severe("Missing template for classId: " + classId);
throw new Error();
}
// Set the template of the L2PcInstance
setTemplate(t);
t = null;
}
/**
* Changes the character's class based on the given class index. <BR>
* <BR>
* An index of zero specifies the character's original (base) class, while indexes 1-3 specifies the character's
* sub-classes respectively.
*
* @param classIndex the class index
* @return true, if successful
*/
public synchronized boolean setActiveClass(int classIndex)
{
if(isInCombat() || this.getAI().getIntention() == CtrlIntention.AI_INTENTION_ATTACK){
sendMessage("Impossible switch class if in combat");
sendPacket( ActionFailed.STATIC_PACKET );
return false;
}
// Delete a force buff upon class change.
//thank l2j-arhid
if(_forceBuff != null)
{
abortCast();
}
/**
* 1. Call store() before modifying _classIndex to avoid skill effects rollover. 2. Register the correct
* _classId against applied 'classIndex'.
*/
store();
if(classIndex == 0)
{
setClassTemplate(getBaseClass());
}
else
{
try
{
setClassTemplate(getSubClasses().get(classIndex).getClassId());
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.info("Could not switch " + getName() + "'s sub class to class index " + classIndex + ": " + e);
return false;
}
}
_classIndex = classIndex;
if(isInParty())
{
getParty().recalculatePartyLevel();
}
/*
* Update the character's change in class status.
*
* 1. Remove any active cubics from the player.
* 2. Renovate the characters table in the database with the new class info, storing also buff/effect data.
* 3. Remove all existing skills.
* 4. Restore all the learned skills for the current class from the database.
* 5. Restore effect/buff data for the new class.
* 6. Restore henna data for the class, applying the new stat modifiers while removing existing ones.
* 7. Reset HP/MP/CP stats and send Server->Client character status packet to reflect changes.
* 8. Restore shortcut data related to this class.
* 9. Resend a class change animation effect to broadcast to all nearby players.
* 10.Unsummon any active servitor from the player.
*/
if(getPet() != null && getPet() instanceof L2SummonInstance)
{
getPet().unSummon(this);
}
unsummonAllCubics();
for(L2Character character : getKnownList().getKnownCharacters())
{
if(character.getForceBuff() != null && character.getForceBuff().getTarget() == this)
{
character.abortCast();
}
}
synchronized (getAllSkills()){
for(L2Skill oldSkill : getAllSkills())
{
super.removeSkill(oldSkill);
}
}
// Yesod: Rebind CursedWeapon passive.
if(isCursedWeaponEquiped())
{
CursedWeaponsManager.getInstance().givePassive(_cursedWeaponEquipedId);
}
stopAllEffects();
if(isSubClassActive())
{
_dwarvenRecipeBook.clear();
_commonRecipeBook.clear();
}
else
{
restoreRecipeBook();
}
// Restore any Death Penalty Buff
restoreDeathPenaltyBuffLevel();
restoreSkills();
regiveTemporarySkills();
rewardSkills();
restoreEffects(Config.ALT_RESTORE_EFFECTS_ON_SUBCLASS_CHANGE);
// Reload skills from armors / jewels / weapons
getInventory().reloadEquippedItems();
// Remove Item RHAND
if(Config.REMOVE_WEAPON_SUBCLASS)
{
L2ItemInstance rhand = getInventory().getPaperdollItem(Inventory.PAPERDOLL_RHAND);
if (rhand != null)
{
L2ItemInstance[] unequipped = getInventory().unEquipItemInBodySlotAndRecord(rhand.getItem().getBodyPart());
InventoryUpdate iu = new InventoryUpdate();
for (L2ItemInstance element : unequipped)
iu.addModifiedItem(element);
sendPacket(iu);
}
}
// Remove Item CHEST
if(Config.REMOVE_CHEST_SUBCLASS)
{
L2ItemInstance chest = getInventory().getPaperdollItem(Inventory.PAPERDOLL_CHEST);
if (chest != null)
{
L2ItemInstance[] unequipped = getInventory().unEquipItemInBodySlotAndRecord(chest.getItem().getBodyPart());
InventoryUpdate iu = new InventoryUpdate();
for (L2ItemInstance element : unequipped)
iu.addModifiedItem(element);
sendPacket(iu);
}
}
// Remove Item LEG
if(Config.REMOVE_LEG_SUBCLASS)
{
L2ItemInstance legs = getInventory().getPaperdollItem(Inventory.PAPERDOLL_LEGS);
if (legs != null)
{
L2ItemInstance[] unequipped = getInventory().unEquipItemInBodySlotAndRecord(legs.getItem().getBodyPart());
InventoryUpdate iu = new InventoryUpdate();
for (L2ItemInstance element : unequipped)
iu.addModifiedItem(element);
sendPacket(iu);
}
}
checkAllowedSkills();
sendPacket(new EtcStatusUpdate(this));
//if player has quest 422: Repent Your Sins, remove it
QuestState st = getQuestState("422_RepentYourSins");
if(st != null)
{
st.exitQuest(true);
st = null;
}
for(int i = 0; i < 3; i++)
{
_henna[i] = null;
}
restoreHenna();
sendPacket(new HennaInfo(this));
if(getCurrentHp() > getMaxHp())
{
setCurrentHp(getMaxHp());
}
if(getCurrentMp() > getMaxMp())
{
setCurrentMp(getMaxMp());
}
if(getCurrentCp() > getMaxCp())
{
setCurrentCp(getMaxCp());
}
// Refresh player infos and update new status
broadcastUserInfo();
refreshOverloaded();
refreshExpertisePenalty();
refreshMasteryPenality();
refreshMasteryWeapPenality();
sendPacket(new UserInfo(this));
sendPacket(new ItemList(this, false));
getInventory().refreshWeight();
// Clear resurrect xp calculation
setExpBeforeDeath(0);
_macroses.restore();
_macroses.sendUpdate();
_shortCuts.restore();
sendPacket(new ShortCutInit(this));
// Rebirth Caller - if player has any skills, they will be granted them.
if(Config.REBIRTH_ENABLE)
L2Rebirth.getInstance().grantRebirthSkills(this);
broadcastPacket(new SocialAction(getObjectId(), 15));
sendPacket(new SkillCoolTime(this));
if (getClan() != null)
getClan().broadcastToOnlineMembers(new PledgeShowMemberListUpdate(this));
//decayMe();
//spawnMe(getX(), getY(), getZ());
return true;
}
/**
* Broadcast class icon.
*/
public void broadcastClassIcon()
{
// Update class icon in party and clan
if (isInParty())
getParty().broadcastToPartyMembers(new PartySmallWindowUpdate(this));
if (getClan() != null)
getClan().broadcastToOnlineMembers(new PledgeShowMemberListUpdate(this));
}
/**
* Stop warn user take break.
*/
public void stopWarnUserTakeBreak()
{
if(_taskWarnUserTakeBreak != null)
{
_taskWarnUserTakeBreak.cancel(true);
_taskWarnUserTakeBreak = null;
}
}
/**
* Start warn user take break.
*/
public void startWarnUserTakeBreak()
{
if(_taskWarnUserTakeBreak == null)
{
_taskWarnUserTakeBreak = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new WarnUserTakeBreak(), 7200000, 7200000);
}
}
/**
* Start bot checker.
*/
public void startBotChecker()
{
if(_taskBotChecker == null)
{
if(Config.QUESTION_LIST.size() != 0){
_taskBotChecker = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new botChecker(), Config.BOT_PROTECTOR_FIRST_CHECK * 60000, Config.BOT_PROTECTOR_NEXT_CHECK * 60000);
}else{
_log.warning("ATTENTION: Bot Checker is bad configured because config/questionwords.txt has 0 words of 6 to 15 keys");
}
}
}
/**
* Stop bot checker.
*/
public void stopBotChecker()
{
if(_taskBotChecker != null)
{
_taskBotChecker.cancel(true);
_taskBotChecker = null;
}
}
/**
* Check answer.
*
* @param id the id
*/
public void checkAnswer(int id)
{
if(id - 100000 == _correctWord)
{
_stopKickBotTask = true;
}
else
{
closeNetConnection();
}
}
/**
* Stop rent pet.
*/
public void stopRentPet()
{
if(_taskRentPet != null)
{
// if the rent of a wyvern expires while over a flying zone, tp to down before unmounting
if(checkLandingState() && getMountType() == 2)
{
teleToLocation(MapRegionTable.TeleportWhereType.Town);
}
if(setMountType(0)) // this should always be true now, since we teleported already
{
_taskRentPet.cancel(true);
Ride dismount = new Ride(getObjectId(), Ride.ACTION_DISMOUNT, 0);
sendPacket(dismount);
broadcastPacket(dismount);
dismount = null;
_taskRentPet = null;
}
}
}
/**
* Start rent pet.
*
* @param seconds the seconds
*/
public void startRentPet(int seconds)
{
if(_taskRentPet == null)
{
_taskRentPet = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new RentPetTask(), seconds * 1000L, seconds * 1000L);
}
}
/**
* Checks if is rented pet.
*
* @return true, if is rented pet
*/
public boolean isRentedPet()
{
if(_taskRentPet != null)
return true;
return false;
}
/**
* Stop water task.
*/
public void stopWaterTask()
{
if(_taskWater != null)
{
_taskWater.cancel(false);
_taskWater = null;
sendPacket(new SetupGauge(2, 0));
// for catacombs...
broadcastUserInfo();
}
}
/**
* Start water task.
*/
public void startWaterTask()
{
broadcastUserInfo();
if(!isDead() && _taskWater == null)
{
int timeinwater = 86000;
sendPacket(new SetupGauge(2, timeinwater));
_taskWater = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new WaterTask(), timeinwater, 1000);
}
}
/**
* Checks if is in water.
*
* @return true, if is in water
*/
public boolean isInWater()
{
if(_taskWater != null)
return true;
return false;
}
/**
* Check water state.
*/
public void checkWaterState()
{
//checking if char is over base level of water (sea, rivers)
if(getZ() > -3750)
{
stopWaterTask();
return;
}
if(isInsideZone(ZONE_WATER))
{
startWaterTask();
}
else
{
stopWaterTask();
return;
}
}
/**
* On player enter.
*/
public void onPlayerEnter()
{
startWarnUserTakeBreak();
if(Config.BOT_PROTECTOR)
{
startBotChecker();
}
if(SevenSigns.getInstance().isSealValidationPeriod() || SevenSigns.getInstance().isCompResultsPeriod())
{
if(!isGM() && isIn7sDungeon() && SevenSigns.getInstance().getPlayerCabal(this) != SevenSigns.getInstance().getCabalHighestScore())
{
teleToLocation(MapRegionTable.TeleportWhereType.Town);
setIsIn7sDungeon(false);
sendMessage("You have been teleported to the nearest town due to the beginning of the Seal Validation period.");
}
}
else
{
if(!isGM() && isIn7sDungeon() && SevenSigns.getInstance().getPlayerCabal(this) == SevenSigns.CABAL_NULL)
{
teleToLocation(MapRegionTable.TeleportWhereType.Town);
setIsIn7sDungeon(false);
sendMessage("You have been teleported to the nearest town because you have not signed for any cabal.");
}
}
// jail task
updatePunishState();
if(_isInvul)
{
sendMessage("Entering world in Invulnerable mode.");
}
if(getAppearance().getInvisible())
{
sendMessage("Entering world in Invisible mode.");
}
if(getMessageRefusal())
{
sendMessage("Entering world in Message Refusal mode.");
}
StatusChecker.checkStatuses(this);
revalidateZone(true);
notifyFriends(false);
// Fix against exploit on anti-target on login
decayMe();
spawnMe();
broadcastUserInfo();
}
/**
* Gets the last access.
*
* @return the last access
*/
public long getLastAccess()
{
return _lastAccess;
}
/**
* Check recom.
*
* @param recsHave the recs have
* @param recsLeft the recs left
*/
private void checkRecom(int recsHave, int recsLeft)
{
Calendar check = Calendar.getInstance();
check.setTimeInMillis(_lastRecomUpdate);
check.add(Calendar.DAY_OF_MONTH, 1);
Calendar min = Calendar.getInstance();
_recomHave = recsHave;
_recomLeft = recsLeft;
if(getStat().getLevel() < 10 || check.after(min))
return;
restartRecom();
}
/**
* Restart recom.
*/
public void restartRecom()
{
if(Config.ALT_RECOMMEND)
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement(DELETE_CHAR_RECOMS);
statement.setInt(1, getObjectId());
statement.execute();
statement.close();
statement = null;
_recomChars.clear();
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("could not clear char recommendations: " + e);
}
finally
{
CloseUtil.close(con);
con = null;
}
}
if(getStat().getLevel() < 20)
{
_recomLeft = 3;
_recomHave--;
}
else if(getStat().getLevel() < 40)
{
_recomLeft = 6;
_recomHave -= 2;
}
else
{
_recomLeft = 9;
_recomHave -= 3;
}
if(_recomHave < 0)
{
_recomHave = 0;
}
// If we have to update last update time, but it's now before 13, we should set it to yesterday
Calendar update = Calendar.getInstance();
if(update.get(Calendar.HOUR_OF_DAY) < 13)
{
update.add(Calendar.DAY_OF_MONTH, -1);
}
update.set(Calendar.HOUR_OF_DAY, 13);
_lastRecomUpdate = update.getTimeInMillis();
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character#doRevive()
*/
@Override
public void doRevive()
{
super.doRevive();
updateEffectIcons();
sendPacket(new EtcStatusUpdate(this));
_reviveRequested = 0;
_revivePower = 0;
if(isInParty() && getParty().isInDimensionalRift())
{
if(!DimensionalRiftManager.getInstance().checkIfInPeaceZone(getX(), getY(), getZ()))
{
getParty().getDimensionalRift().memberRessurected(this);
}
}
if((_inEventTvT && TvT.is_started() && Config.TVT_REVIVE_RECOVERY) || (_inEventCTF && CTF.is_started() && Config.CTF_REVIVE_RECOVERY) || (_inEventDM && DM.is_started() && Config.DM_REVIVE_RECOVERY))
{
getStatus().setCurrentHp(getMaxHp());
getStatus().setCurrentMp(getMaxMp());
getStatus().setCurrentCp(getMaxCp());
}
if (_inEventRaid && Raid._started)
{
getStatus().setCurrentHp(getMaxHp());
getStatus().setCurrentMp(getMaxMp());
getStatus().setCurrentCp(getMaxCp());
}
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character#doRevive(double)
*/
@Override
public void doRevive(double revivePower)
{
// Restore the player's lost experience,
// depending on the % return of the skill used (based on its power).
restoreExp(revivePower);
doRevive();
}
/**
* Revive request.
*
* @param Reviver the reviver
* @param skill the skill
* @param Pet the pet
*/
public void reviveRequest(L2PcInstance Reviver, L2Skill skill, boolean Pet)
{
if(_reviveRequested == 1)
{
if(_revivePet == Pet)
{
Reviver.sendPacket(new SystemMessage(SystemMessageId.RES_HAS_ALREADY_BEEN_PROPOSED)); // Resurrection is already been proposed.
}
else
{
if(Pet)
{
Reviver.sendPacket(new SystemMessage(SystemMessageId.PET_CANNOT_RES)); // A pet cannot be resurrected while it's owner is in the process of resurrecting.
}
else
{
Reviver.sendPacket(new SystemMessage(SystemMessageId.MASTER_CANNOT_RES)); // While a pet is attempting to resurrect, it cannot help in resurrecting its master.
}
}
return;
}
if(Pet && getPet() != null && getPet().isDead() || !Pet && isDead())
{
_reviveRequested = 1;
if(isPhoenixBlessed())
{
_revivePower = 100;
}
else if(skill != null)
{
_revivePower = Formulas.getInstance().calculateSkillResurrectRestorePercent(skill.getPower(), Reviver);
}
else
{
_revivePower = 0;
}
_revivePet = Pet;
ConfirmDlg dlg = new ConfirmDlg(SystemMessageId.RESSURECTION_REQUEST.getId());
dlg.addString(Reviver.getName());
sendPacket(dlg);
dlg = null;
}
}
/**
* Revive answer.
*
* @param answer the answer
*/
public void reviveAnswer(int answer)
{
if(_reviveRequested != 1 || !isDead() && !_revivePet || _revivePet && getPet() != null && !getPet().isDead())
return;
//If character refuse a PhoenixBlessed autoress, cancel all buffs he had
if(answer == 0 && isPhoenixBlessed())
{
stopPhoenixBlessing(null);
stopAllEffects();
}
if(answer == 1)
{
if(!_revivePet)
{
if(_revivePower != 0)
{
doRevive(_revivePower);
}
else
{
doRevive();
}
}
else if(getPet() != null)
{
if(_revivePower != 0)
{
getPet().doRevive(_revivePower);
}
else
{
getPet().doRevive();
}
}
}
_reviveRequested = 0;
_revivePower = 0;
}
/**
* Checks if is revive requested.
*
* @return true, if is revive requested
*/
public boolean isReviveRequested()
{
return _reviveRequested == 1;
}
/**
* Checks if is reviving pet.
*
* @return true, if is reviving pet
*/
public boolean isRevivingPet()
{
return _revivePet;
}
/**
* Removes the reviving.
*/
public void removeReviving()
{
_reviveRequested = 0;
_revivePower = 0;
}
/**
* On action request.
*/
public void onActionRequest()
{
if (isSpawnProtected())
sendMessage("The effect of Spawn Protection has been removed.");
else if (isTeleportProtected())
sendMessage("The effect of Teleport Spawn Protection has been removed.");
if (Config.PLAYER_SPAWN_PROTECTION > 0)
setProtection(false);
if (Config.PLAYER_TELEPORT_PROTECTION > 0)
setTeleportProtection(false);
}
/**
* Sets the expertise index.
*
* @param expertiseIndex The expertiseIndex to set.
*/
public void setExpertiseIndex(int expertiseIndex)
{
_expertiseIndex = expertiseIndex;
}
/**
* Gets the expertise index.
*
* @return Returns the expertiseIndex.
*/
public int getExpertiseIndex()
{
return _expertiseIndex;
}
/*
* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character#onTeleported()
*/
@Override
public final void onTeleported()
{
super.onTeleported();
// Force a revalidation
revalidateZone(true);
if ((Config.PLAYER_TELEPORT_PROTECTION > 0) && !isInOlympiadMode())
{
setTeleportProtection(true);
sendMessage("The effects of Teleport Spawn Protection flow through you.");
}
if (Config.ALLOW_WATER)
{
checkWaterState();
}
// Modify the position of the tamed beast if necessary (normal pets are handled by super...though
// L2PcInstance is the only class that actually has pets!!! )
if (getTrainedBeast() != null)
{
getTrainedBeast().getAI().stopFollow();
getTrainedBeast().teleToLocation(getPosition().getX() + Rnd.get(-100, 100), getPosition().getY() + Rnd.get(-100, 100), getPosition().getZ(), false);
getTrainedBeast().getAI().startFollow(this);
}
// To be sure update also the pvp flag / war tag status
if (!inObserverMode())
broadcastUserInfo();
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character#updatePosition(int)
*/
@Override
public final boolean updatePosition(int gameTicks)
{
// Disables custom movement for L2PCInstance when Old Synchronization is selected
if(Config.COORD_SYNCHRONIZE == -1)
return super.updatePosition(gameTicks);
// Get movement data
MoveData m = _move;
if(_move == null)
return true;
if(!isVisible())
{
_move = null;
return true;
}
// Check if the position has alreday be calculated
if(m._moveTimestamp == 0)
{
m._moveTimestamp = m._moveStartTime;
}
// Check if the position has alreday be calculated
if(m._moveTimestamp == gameTicks)
return false;
double dx = m._xDestination - getX();
double dy = m._yDestination - getY();
double dz = m._zDestination - getZ();
int distPassed = (int) getStat().getMoveSpeed() * (gameTicks - m._moveTimestamp) / GameTimeController.TICKS_PER_SECOND;
double distFraction = distPassed / Math.sqrt(dx * dx + dy * dy + dz * dz);
// if (Config.DEVELOPER) System.out.println("Move Ticks:" + (gameTicks - m._moveTimestamp) + ", distPassed:" + distPassed + ", distFraction:" + distFraction);
if(distFraction > 1)
{
// Set the position of the L2Character to the destination
super.setXYZ(m._xDestination, m._yDestination, m._zDestination);
}
else
{
// Set the position of the L2Character to estimated after parcial move
super.setXYZ(getX() + (int) (dx * distFraction + 0.5), getY() + (int) (dy * distFraction + 0.5), getZ() + (int) (dz * distFraction));
}
// Set the timer of last position update to now
m._moveTimestamp = gameTicks;
revalidateZone(false);
return distFraction > 1;
}
/**
* Sets the last client position.
*
* @param x the x
* @param y the y
* @param z the z
*/
public void setLastClientPosition(int x, int y, int z)
{
_lastClientPosition.setXYZ(x, y, z);
}
/**
* Sets the last client position.
*
* @param loc the new last client position
*/
public void setLastClientPosition(Location loc) {
_lastClientPosition = loc;
}
/**
* Check last client position.
*
* @param x the x
* @param y the y
* @param z the z
* @return true, if successful
*/
public boolean checkLastClientPosition(int x, int y, int z)
{
return _lastClientPosition.equals(x, y, z);
}
/**
* Gets the last client distance.
*
* @param x the x
* @param y the y
* @param z the z
* @return the last client distance
*/
public int getLastClientDistance(int x, int y, int z)
{
double dx = x - _lastClientPosition.getX();
double dy = y - _lastClientPosition.getY();
double dz = z - _lastClientPosition.getZ();
return (int) Math.sqrt(dx * dx + dy * dy + dz * dz);
}
/**
* Sets the last server position.
*
* @param x the x
* @param y the y
* @param z the z
*/
public void setLastServerPosition(int x, int y, int z)
{
_lastServerPosition.setXYZ(x, y, z);
}
/**
* Sets the last server position.
*
* @param loc the new last server position
*/
public void setLastServerPosition(Location loc) {
_lastServerPosition = loc;
}
/**
* Check last server position.
*
* @param x the x
* @param y the y
* @param z the z
* @return true, if successful
*/
public boolean checkLastServerPosition(int x, int y, int z)
{
return _lastServerPosition.equals(x, y, z);
}
/**
* Gets the last server distance.
*
* @param x the x
* @param y the y
* @param z the z
* @return the last server distance
*/
public int getLastServerDistance(int x, int y, int z)
{
double dx = x - _lastServerPosition.getX();
double dy = y - _lastServerPosition.getY();
double dz = z - _lastServerPosition.getZ();
return (int) Math.sqrt(dx * dx + dy * dy + dz * dz);
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character#addExpAndSp(long, int)
*/
@Override
public void addExpAndSp(long addToExp, int addToSp)
{
getStat().addExpAndSp(addToExp, addToSp);
}
/**
* Removes the exp and sp.
*
* @param removeExp the remove exp
* @param removeSp the remove sp
*/
public void removeExpAndSp(long removeExp, int removeSp)
{
getStat().removeExpAndSp(removeExp, removeSp);
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character#reduceCurrentHp(double, com.l2jfrozen.gameserver.model.L2Character)
*/
@Override
public void reduceCurrentHp(double i, L2Character attacker)
{
getStatus().reduceHp(i, attacker);
// notify the tamed beast of attacks
if(getTrainedBeast() != null)
{
getTrainedBeast().onOwnerGotAttacked(attacker);
}
}
/*
* Function for skill summon friend or Gate Chant.
*/
/**
* Request Teleport *.
*
* @param requester the requester
* @param skill the skill
* @return true, if successful
*/
public boolean teleportRequest(L2PcInstance requester, L2Skill skill)
{
if (_summonRequest.getTarget() != null && requester != null)
return false;
_summonRequest.setTarget(requester, skill);
return true;
}
/**
* Action teleport *.
*
* @param answer the answer
* @param requesterId the requester id
*/
public void teleportAnswer(int answer, int requesterId)
{
if (_summonRequest.getTarget() == null)
return;
if (answer == 1 && _summonRequest.getTarget().getObjectId() == requesterId)
{
teleToTarget(this, _summonRequest.getTarget(), _summonRequest.getSkill());
}
_summonRequest.setTarget(null, null);
}
/**
* Tele to target.
*
* @param targetChar the target char
* @param summonerChar the summoner char
* @param summonSkill the summon skill
*/
public static void teleToTarget(L2PcInstance targetChar, L2PcInstance summonerChar, L2Skill summonSkill)
{
if (targetChar == null || summonerChar == null || summonSkill == null)
return;
if (!checkSummonerStatus(summonerChar))
return;
if (!checkSummonTargetStatus(targetChar, summonerChar))
return;
int itemConsumeId = summonSkill.getTargetConsumeId();
int itemConsumeCount = summonSkill.getTargetConsume();
if (itemConsumeId != 0 && itemConsumeCount != 0)
{
//Delete by rocknow
if (targetChar.getInventory().getInventoryItemCount(itemConsumeId, 0) < itemConsumeCount)
{
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_REQUIRED_FOR_SUMMONING);
sm.addItemName(summonSkill.getTargetConsumeId());
targetChar.sendPacket(sm);
return;
}
targetChar.getInventory().destroyItemByItemId("Consume", itemConsumeId, itemConsumeCount, summonerChar, targetChar);
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_DISAPPEARED);
sm.addItemName(summonSkill.getTargetConsumeId());
targetChar.sendPacket(sm);
}
targetChar.teleToLocation(summonerChar.getX(), summonerChar.getY(), summonerChar.getZ(), true);
}
/**
* Check summoner status.
*
* @param summonerChar the summoner char
* @return true, if successful
*/
public static boolean checkSummonerStatus(L2PcInstance summonerChar)
{
if (summonerChar == null)
return false;
if (summonerChar.isInOlympiadMode())
{
summonerChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.THIS_ITEM_IS_NOT_AVAILABLE_FOR_THE_OLYMPIAD_EVENT));
return false;
}
if (summonerChar.inObserverMode())
{
return false;
}
if (summonerChar._inEventRaid)
{
summonerChar.sendMessage("You cannot summon your friend due to event restrictions.");
return false;
}
if (summonerChar.isInsideZone(L2Character.ZONE_NOSUMMONFRIEND) || summonerChar.isFlying() || summonerChar.isMounted())
{
summonerChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING));
return false;
}
return true;
}
/**
* Check summon target status.
*
* @param target the target
* @param summonerChar the summoner char
* @return true, if successful
*/
public static boolean checkSummonTargetStatus(L2Object target, L2PcInstance summonerChar)
{
if (target == null || !(target instanceof L2PcInstance))
return false;
L2PcInstance targetChar = (L2PcInstance) target;
if (targetChar.isAlikeDead())
{
return false;
}
if (targetChar.isInStoreMode())
{
return false;
}
if (targetChar.isRooted() || targetChar.isInCombat())
{
return false;
}
if (targetChar.isInOlympiadMode())
{
summonerChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CANNOT_SUMMON_PLAYERS_WHO_ARE_IN_OLYMPIAD));
return false;
}
if (targetChar._inEventRaid)
{
targetChar.sendMessage("You cannot be summoned due to event restriction.");
return false;
}
if (targetChar.isFestivalParticipant() || targetChar.isFlying())
{
summonerChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING));
return false;
}
if (targetChar.inObserverMode())
{
return false;
}
if (targetChar.isInCombat())
{
summonerChar.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOUR_TARGET_IS_IN_AN_AREA_WHICH_BLOCKS_SUMMONING));
return false;
}
if (targetChar.isInsideZone(L2Character.ZONE_NOSUMMONFRIEND))
{
return false;
}
return true;
}
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character#reduceCurrentHp(double, com.l2jfrozen.gameserver.model.L2Character, boolean)
*/
@Override
public void reduceCurrentHp(double value, L2Character attacker, boolean awake)
{
getStatus().reduceHp(value, attacker, awake);
// notify the tamed beast of attacks
if(getTrainedBeast() != null)
{
getTrainedBeast().onOwnerGotAttacked(attacker);
}
}
public void broadcastSnoop(int type, String name, String _text, CreatureSay cs)
{
if (_snoopListener.size() > 0)
{
Snoop sn = new Snoop(this, type, name, _text);
for (L2PcInstance pci : _snoopListener)
{
if (pci != null)
{
pci.sendPacket(cs);
pci.sendPacket(sn);
}
}
}
}
public void addSnooper(L2PcInstance pci)
{
if (!_snoopListener.contains(pci))
{
_snoopListener.add(pci);
}
}
public void removeSnooper(L2PcInstance pci)
{
_snoopListener.remove(pci);
}
public void addSnooped(L2PcInstance pci)
{
if (!_snoopedPlayer.contains(pci))
_snoopedPlayer.add(pci);
}
public void removeSnooped(L2PcInstance pci)
{
_snoopedPlayer.remove(pci);
}
/**
* Adds the bypass.
*
* @param bypass the bypass
*/
public synchronized void addBypass(String bypass)
{
if(bypass == null)
return;
_validBypass.add(bypass);
//_log.warning("[BypassAdd]"+getName()+" '"+bypass+"'");
}
/**
* Adds the bypass2.
*
* @param bypass the bypass
*/
public synchronized void addBypass2(String bypass)
{
if(bypass == null)
return;
_validBypass2.add(bypass);
//_log.warning("[BypassAdd]"+getName()+" '"+bypass+"'");
}
/**
* Validate bypass.
*
* @param cmd the cmd
* @return true, if successful
*/
public synchronized boolean validateBypass(String cmd)
{
if(!Config.BYPASS_VALIDATION)
return true;
for(String bp : _validBypass)
{
if(bp == null)
{
continue;
}
//_log.warning("[BypassValidation]"+getName()+" '"+bp+"'");
if(bp.equals(cmd))
return true;
}
for(String bp : _validBypass2)
{
if(bp == null)
{
continue;
}
//_log.warning("[BypassValidation]"+getName()+" '"+bp+"'");
if(cmd.startsWith(bp))
return true;
}
if(cmd.startsWith("npc_") && cmd.endsWith("_SevenSigns 7"))
return true;
//L2PcInstance player = getClient().getActiveChar();
// We decided to put a kick because when a player is doing quest with a BOT he sends invalid bypass.
//Util.handleIllegalPlayerAction(player,"[L2PcInstance] player [" + player.getName() + "] sent invalid bypass '" + cmd + "'", Config.DEFAULT_PUNISH);
return false;
}
/**
* Validate item manipulation by item id.
*
* @param itemId the item id
* @param action the action
* @return true, if successful
*/
public boolean validateItemManipulationByItemId(int itemId, String action)
{
L2ItemInstance item = getInventory().getItemByItemId(itemId);
if(item == null || item.getOwnerId() != getObjectId())
{
_log.finest(getObjectId() + ": player tried to " + action + " item he is not owner of");
return false;
}
if(getActiveEnchantItem() != null && getActiveEnchantItem().getItemId() == itemId)
{
_log.finest(getObjectId() + ":player tried to " + action + " an enchant scroll he was using");
return false;
}
if(CursedWeaponsManager.getInstance().isCursed(itemId))
// can not trade a cursed weapon
return false;
if(item.isWear())
// cannot drop/trade wear-items
return false;
item = null;
return true;
}
/**
* Validate item manipulation.
*
* @param objectId the object id
* @param action the action
* @return true, if successful
*/
public boolean validateItemManipulation(int objectId, String action)
{
L2ItemInstance item = getInventory().getItemByObjectId(objectId);
if(item == null || item.getOwnerId() != getObjectId())
{
_log.finest(getObjectId() + ": player tried to " + action + " item he is not owner of");
return false;
}
// Pet is summoned and not the item that summoned the pet AND not the buggle from strider you're mounting
if(getPet() != null && getPet().getControlItemId() == objectId || getMountObjectID() == objectId)
{
if(Config.DEBUG)
{
_log.finest(getObjectId() + ": player tried to " + action + " item controling pet");
}
return false;
}
if(getActiveEnchantItem() != null && getActiveEnchantItem().getObjectId() == objectId)
{
if(Config.DEBUG)
{
_log.finest(getObjectId() + ":player tried to " + action + " an enchant scroll he was using");
}
return false;
}
if(CursedWeaponsManager.getInstance().isCursed(item.getItemId()))
// can not trade a cursed weapon
return false;
if(item.isWear())
// cannot drop/trade wear-items
return false;
item = null;
return true;
}
/**
* Clear bypass.
*/
public synchronized void clearBypass()
{
_validBypass.clear();
_validBypass2.clear();
}
/**
* Validate link.
*
* @param cmd the cmd
* @return true, if successful
*/
public synchronized boolean validateLink(String cmd)
{
if(!Config.BYPASS_VALIDATION)
return true;
for(String bp : _validLink)
{
if(bp == null)
continue;
if(bp.equals(cmd))
return true;
}
_log.warning("[L2PcInstance] player ["+getName()+"] sent invalid link '"+cmd+"', ban this player!");
return false;
}
/**
* Clear links.
*/
public synchronized void clearLinks()
{
_validLink.clear();
}
/**
* Adds the link.
*
* @param link the link
*/
public synchronized void addLink(String link)
{
if(link == null) return;
_validLink.add(link);
}
/**
* Checks if is in boat.
*
* @return Returns the inBoat.
*/
public boolean isInBoat()
{
return _inBoat;
}
/**
* Sets the in boat.
*
* @param inBoat The inBoat to set.
*/
public void setInBoat(boolean inBoat)
{
_inBoat = inBoat;
}
/**
* Gets the boat.
*
* @return the boat
*/
public L2BoatInstance getBoat()
{
return _boat;
}
/**
* Sets the boat.
*
* @param boat the new boat
*/
public void setBoat(L2BoatInstance boat)
{
_boat = boat;
}
/**
* Sets the in crystallize.
*
* @param inCrystallize the new in crystallize
*/
public void setInCrystallize(boolean inCrystallize)
{
_inCrystallize = inCrystallize;
}
/**
* Checks if is in crystallize.
*
* @return true, if is in crystallize
*/
public boolean isInCrystallize()
{
return _inCrystallize;
}
/**
* Gets the in boat position.
*
* @return the in boat position
*/
public Point3D getInBoatPosition()
{
return _inBoatPosition;
}
/**
* Sets the in boat position.
*
* @param pt the new in boat position
*/
public void setInBoatPosition(Point3D pt)
{
_inBoatPosition = pt;
}
/**
* Manage the delete task of a L2PcInstance (Leave Party, Unsummon pet, Save its inventory in the database, Remove
* it from the world...).<BR>
* <BR>
* <B><U> Actions</U> :</B><BR>
* <BR>
* <li>If the L2PcInstance is in observer mode, set its position to its position before entering in observer mode</li>
* <li>Set the online Flag to True or False and update the characters table of the database with online status and
* lastAccess</li> <li>Stop the HP/MP/CP Regeneration task</li> <li>Cancel Crafting, Attak or Cast</li> <li>Remove
* the L2PcInstance from the world</li> <li>Stop Party and Unsummon Pet</li> <li>Update database with items in its
* inventory and remove them from the world</li> <li>Remove all L2Object from _knownObjects and _knownPlayer of the
* L2Character then cancel Attak or Cast and notify AI</li> <li>Close the connection with the client</li><BR>
* <BR>
*/
public synchronized void deleteMe()
{
// Check if the L2PcInstance is in observer mode to set its position to its position before entering in observer mode
if(inObserverMode())
{
setXYZ(_obsX, _obsY, _obsZ);
}
if(isTeleporting())
{
try
{
wait(2000);
}
catch(InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
onTeleported();
}
Castle castle = null;
if(getClan() != null)
{
castle = CastleManager.getInstance().getCastleByOwner(getClan());
if(castle != null)
{
castle.destroyClanGate();
}
}
// Set the online Flag to True or False and update the characters table of the database with online status and lastAccess (called when login and logout)
try
{
setOnlineStatus(false);
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}
// Stop the HP/MP/CP Regeneration task (scheduled tasks)
try
{
stopAllTimers();
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}
// Stop crafting, if in progress
try
{
RecipeController.getInstance().requestMakeItemAbort(this);
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}
// Cancel Attak or Cast
try
{
abortAttack();
abortCast();
setTarget(null);
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}
PartyMatchWaitingList.getInstance().removePlayer(this);
if (_partyroom != 0)
{
PartyMatchRoom room = PartyMatchRoomList.getInstance().getRoom(_partyroom);
if (room != null)
room.deleteMember(this);
}
// Remove from world regions zones
if(getWorldRegion() != null)
{
getWorldRegion().removeFromZones(this);
}
try
{
if(_forceBuff != null)
{
abortCast();
}
for(L2Character character : getKnownList().getKnownCharacters())
if(character.getForceBuff() != null && character.getForceBuff().getTarget() == this)
{
character.abortCast();
}
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}
// Remove the L2PcInstance from the world
if(isVisible())
{
try
{
decayMe();
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}
}
// If a Party is in progress, leave it
if(isInParty())
{
try
{
leaveParty();
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}
}
// If the L2PcInstance has Pet, unsummon it
if(getPet() != null)
{
try
{
getPet().unSummon(this);
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}// returns pet to control item
}
if(getClanId() != 0 && getClan() != null)
{
// set the status for pledge member list to OFFLINE
try
{
L2ClanMember clanMember = getClan().getClanMember(getName());
if(clanMember != null)
{
clanMember.setPlayerInstance(null);
}
clanMember = null;
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}
}
if(getActiveRequester() != null)
{
// deals with sudden exit in the middle of transaction
setActiveRequester(null);
}
if(getOlympiadGameId() != -1)
{
Olympiad.getInstance().removeDisconnectedCompetitor(this);
}
if (LastManStanding.isActive())
{
if(this.isInLMS())
{
LastManStanding.joined--;
switch(LastManStanding.joined)
{
case 2:
{
for (L2PcInstance player : LastManStanding.players)
player.sendMessage("There are only two players left! Now its 1 versus 1");
break;
}
case 1:
{
for(L2PcInstance p : L2World.getInstance().getAllPlayers())
{
if (p.isInsideZone(L2Character.ZONE_EVENT))
{
LastManStanding.winner = p;
for (L2PcInstance player : LastManStanding.players)
player.sendMessage(LastManStanding.winner + " is the winner of the event.");
LastManStanding.endAndReward();
break;
}
}
}
}
}
}
// If the L2PcInstance is a GM, remove it from the GM List
if(isGM())
{
try
{
GmListTable.getInstance().deleteGm(this);
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}
}
// Update database with items in its inventory and remove them from the world
try
{
getInventory().deleteMe();
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}
// Update database with items in its warehouse and remove them from the world
try
{
clearWarehouse();
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}
if(Config.WAREHOUSE_CACHE)
{
WarehouseCacheManager.getInstance().remCacheTask(this);
}
// Update database with items in its freight and remove them from the world
try
{
getFreight().deleteMe();
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}
// Remove all L2Object from _knownObjects and _knownPlayer of the L2Character then cancel Attak or Cast and notify AI
try
{
getKnownList().removeAllKnownObjects();
}
catch(Throwable t)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
t.printStackTrace();
_log.log(Level.SEVERE, "deleteMe()", t);
}
// Close the connection with the client
closeNetConnection();
// remove from flood protector
//FloodProtector.getInstance().removePlayer(getObjectId());
if(getClanId() > 0)
{
getClan().broadcastToOtherOnlineMembers(new PledgeShowMemberListUpdate(this), this);
//ClanTable.getInstance().getClan(getClanId()).broadcastToOnlineMembers(new PledgeShowMemberListAdd(this));
}
for(L2PcInstance player : _snoopedPlayer)
{
player.removeSnooper(this);
}
for(L2PcInstance player : _snoopListener)
{
player.removeSnooped(this);
}
if(_chanceSkills != null)
{
_chanceSkills.setOwner(null);
_chanceSkills = null;
}
notifyFriends(true);
// Remove L2Object object from _allObjects of L2World
L2World.getInstance().removeObject(this);
L2World.getInstance().removeFromAllPlayers(this); // force remove in case of crash during teleport
}
/** ShortBuff clearing Task */
private ScheduledFuture<?> _shortBuffTask = null;
private class ShortBuffTask implements Runnable
{
private L2PcInstance _player = null;
public ShortBuffTask(L2PcInstance activeChar)
{
_player = activeChar;
}
@Override
public void run()
{
if (_player == null)
return;
_player.sendPacket(new ShortBuffStatusUpdate(0, 0, 0));
}
}
/**
* @param magicId
* @param level
* @param time
*/
public void shortBuffStatusUpdate(int magicId, int level, int time)
{
if (_shortBuffTask != null)
{
_shortBuffTask.cancel(false);
_shortBuffTask = null;
}
_shortBuffTask = ThreadPoolManager.getInstance().scheduleGeneral(new ShortBuffTask(this), 15000);
sendPacket(new ShortBuffStatusUpdate(magicId, level, time));
}
/** list of character friends. */
private List<String> _friendList = new FastList<String>();
/**
* Gets the friend list.
*
* @return the friend list
*/
public List<String> getFriendList()
{
return _friendList;
}
/**
* Restore friend list.
*/
public void restoreFriendList()
{
_friendList.clear();
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement;
statement = con.prepareStatement("SELECT friend_name,not_blocked FROM character_friends WHERE char_id=?");
statement.setInt(1, getObjectId());
ResultSet rset = statement.executeQuery();
while(rset.next())
{
String friendName = rset.getString("friend_name");
if (friendName.equals(getName()))
continue;
Integer blockedType = rset.getInt("not_blocked");
if(blockedType == 1){
_friendList.add(friendName);
}else{
_blockList.getBlockList().add(friendName);
}
}
rset.close();
statement.close();
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("could not restore friend data:" + e);
}
finally
{
CloseUtil.close(con);
con = null;
}
}
/**
* Notify friends.
*
* @param closing the closing
*/
private void notifyFriends(boolean closing)
{
for(String friendName : _friendList)
{
L2PcInstance friend = L2World.getInstance().getPlayer(friendName);
if(friend != null) //friend logged in.
{
friend.sendPacket(new FriendList(friend));
}
}
}
/*
private void notifyFriends2(L2PcInstance cha)
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement;
statement = con.prepareStatement("SELECT friend_name FROM character_friends WHERE char_id=?");
statement.setInt(1, cha.getObjectId());
ResultSet rset = statement.executeQuery();
while(rset.next())
{
String friendName = rset.getString("friend_name");
L2PcInstance friend = L2World.getInstance().getPlayer(friendName);
if(friend != null) //friend logged in.
{
friend.sendPacket(new FriendList(friend));
friend.sendMessage("Friend: " + cha.getName() + " has logged off.");
}
}
rset.close();
statement.close();
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("could not restore friend data:" + e);
}
finally
{
CloseUtil.close(con);
con = null;
}
}
*/
/** The _fish. */
private FishData _fish;
/* startFishing() was stripped of any pre-fishing related checks, namely the fishing zone check.
* Also worthy of note is the fact the code to find the hook landing position was also striped. The
* stripped code was moved into fishing.java. In my opinion it makes more sense for it to be there
* since all other skill related checks were also there. Last but not least, moving the zone check
* there, fixed a bug where baits would always be consumed no matter if fishing actualy took place.
* startFishing() now takes up 3 arguments, wich are acurately described as being the hook landing
* coordinates.
*/
/**
* Start fishing.
*
* @param _x the _x
* @param _y the _y
* @param _z the _z
*/
public void startFishing(int _x, int _y, int _z)
{
stopMove(null);
setIsImobilised(true);
_fishing = true;
_fishx = _x;
_fishy = _y;
_fishz = _z;
broadcastUserInfo();
//Starts fishing
int lvl = GetRandomFishLvl();
int group = GetRandomGroup();
int type = GetRandomFishType(group);
List<FishData> fishs = FishTable.getInstance().getfish(lvl, type, group);
if(fishs == null || fishs.size() == 0)
{
sendMessage("Error - Fishes are not definied");
EndFishing(false);
return;
}
int check = Rnd.get(fishs.size());
// Use a copy constructor else the fish data may be over-written below
_fish = new FishData(fishs.get(check));
fishs.clear();
fishs = null;
sendPacket(new SystemMessage(SystemMessageId.CAST_LINE_AND_START_FISHING));
ExFishingStart efs = null;
if(!GameTimeController.getInstance().isNowNight() && _lure.isNightLure())
{
_fish.setType(-1);
}
//sendMessage("Hook x,y: " + _x + "," + _y + " - Water Z, Player Z:" + _z + ", " + getZ()); //debug line, uncoment to show coordinates used in fishing.
efs = new ExFishingStart(this, _fish.getType(), _x, _y, _z, _lure.isNightLure());
broadcastPacket(efs);
efs = null;
StartLookingForFishTask();
}
/**
* Stop looking for fish task.
*/
public void stopLookingForFishTask()
{
if(_taskforfish != null)
{
_taskforfish.cancel(false);
_taskforfish = null;
}
}
/**
* Start looking for fish task.
*/
public void StartLookingForFishTask()
{
if(!isDead() && _taskforfish == null)
{
int checkDelay = 0;
boolean isNoob = false;
boolean isUpperGrade = false;
if(_lure != null)
{
int lureid = _lure.getItemId();
isNoob = _fish.getGroup() == 0;
isUpperGrade = _fish.getGroup() == 2;
if(lureid == 6519 || lureid == 6522 || lureid == 6525 || lureid == 8505 || lureid == 8508 || lureid == 8511)
{
checkDelay = Math.round((float) (_fish.getGutsCheckTime() * 1.33));
}
else if(lureid == 6520 || lureid == 6523 || lureid == 6526 || lureid >= 8505 && lureid <= 8513 || lureid >= 7610 && lureid <= 7613 || lureid >= 7807 && lureid <= 7809 || lureid >= 8484 && lureid <= 8486)
{
checkDelay = Math.round((float) (_fish.getGutsCheckTime() * 1.00));
}
else if(lureid == 6521 || lureid == 6524 || lureid == 6527 || lureid == 8507 || lureid == 8510 || lureid == 8513)
{
checkDelay = Math.round((float) (_fish.getGutsCheckTime() * 0.66));
}
}
_taskforfish = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new LookingForFishTask(_fish.getWaitTime(), _fish.getFishGuts(), _fish.getType(), isNoob, isUpperGrade), 10000, checkDelay);
}
}
/**
* Gets the random group.
*
* @return the int
*/
private int GetRandomGroup()
{
switch(_lure.getItemId())
{
case 7807: //green for beginners
case 7808: //purple for beginners
case 7809: //yellow for beginners
case 8486: //prize-winning for beginners
return 0;
case 8485: //prize-winning luminous
case 8506: //green luminous
case 8509: //purple luminous
case 8512: //yellow luminous
return 2;
default:
return 1;
}
}
/**
* Gets the random fish type.
*
* @param group the group
* @return the int
*/
private int GetRandomFishType(int group)
{
int check = Rnd.get(100);
int type = 1;
switch(group)
{
case 0: //fish for novices
switch(_lure.getItemId())
{
case 7807: //green lure, preferred by fast-moving (nimble) fish (type 5)
if(check <= 54)
{
type = 5;
}
else if(check <= 77)
{
type = 4;
}
else
{
type = 6;
}
break;
case 7808: //purple lure, preferred by fat fish (type 4)
if(check <= 54)
{
type = 4;
}
else if(check <= 77)
{
type = 6;
}
else
{
type = 5;
}
break;
case 7809: //yellow lure, preferred by ugly fish (type 6)
if(check <= 54)
{
type = 6;
}
else if(check <= 77)
{
type = 5;
}
else
{
type = 4;
}
break;
case 8486: //prize-winning fishing lure for beginners
if(check <= 33)
{
type = 4;
}
else if(check <= 66)
{
type = 5;
}
else
{
type = 6;
}
break;
}
break;
case 1: //normal fish
switch(_lure.getItemId())
{
case 7610:
case 7611:
case 7612:
case 7613:
type = 3;
break;
case 6519: //all theese lures (green) are prefered by fast-moving (nimble) fish (type 1)
case 8505:
case 6520:
case 6521:
case 8507:
if(check <= 54)
{
type = 1;
}
else if(check <= 74)
{
type = 0;
}
else if(check <= 94)
{
type = 2;
}
else
{
type = 3;
}
break;
case 6522: //all theese lures (purple) are prefered by fat fish (type 0)
case 8508:
case 6523:
case 6524:
case 8510:
if(check <= 54)
{
type = 0;
}
else if(check <= 74)
{
type = 1;
}
else if(check <= 94)
{
type = 2;
}
else
{
type = 3;
}
break;
case 6525: //all theese lures (yellow) are prefered by ugly fish (type 2)
case 8511:
case 6526:
case 6527:
case 8513:
if(check <= 55)
{
type = 2;
}
else if(check <= 74)
{
type = 1;
}
else if(check <= 94)
{
type = 0;
}
else
{
type = 3;
}
break;
case 8484: //prize-winning fishing lure
if(check <= 33)
{
type = 0;
}
else if(check <= 66)
{
type = 1;
}
else
{
type = 2;
}
break;
}
break;
case 2: //upper grade fish, luminous lure
switch(_lure.getItemId())
{
case 8506: //green lure, preferred by fast-moving (nimble) fish (type 8)
if(check <= 54)
{
type = 8;
}
else if(check <= 77)
{
type = 7;
}
else
{
type = 9;
}
break;
case 8509: //purple lure, preferred by fat fish (type 7)
if(check <= 54)
{
type = 7;
}
else if(check <= 77)
{
type = 9;
}
else
{
type = 8;
}
break;
case 8512: //yellow lure, preferred by ugly fish (type 9)
if(check <= 54)
{
type = 9;
}
else if(check <= 77)
{
type = 8;
}
else
{
type = 7;
}
break;
case 8485: //prize-winning fishing lure
if(check <= 33)
{
type = 7;
}
else if(check <= 66)
{
type = 8;
}
else
{
type = 9;
}
break;
}
}
return type;
}
/**
* Gets the random fish lvl.
*
* @return the int
*/
private int GetRandomFishLvl()
{
L2Effect[] effects = getAllEffects();
int skilllvl = getSkillLevel(1315);
for(L2Effect e : effects)
{
if(e.getSkill().getId() == 2274)
{
skilllvl = (int) e.getSkill().getPower(this);
}
}
if(skilllvl <= 0)
return 1;
int randomlvl;
int check = Rnd.get(100);
if(check <= 50)
{
randomlvl = skilllvl;
}
else if(check <= 85)
{
randomlvl = skilllvl - 1;
if(randomlvl <= 0)
{
randomlvl = 1;
}
}
else
{
randomlvl = skilllvl + 1;
if(randomlvl > 27)
{
randomlvl = 27;
}
}
effects = null;
return randomlvl;
}
/**
* Start fish combat.
*
* @param isNoob the is noob
* @param isUpperGrade the is upper grade
*/
public void StartFishCombat(boolean isNoob, boolean isUpperGrade)
{
_fishCombat = new L2Fishing(this, _fish, isNoob, isUpperGrade);
}
/**
* End fishing.
*
* @param win the win
*/
public void EndFishing(boolean win)
{
ExFishingEnd efe = new ExFishingEnd(win, this);
broadcastPacket(efe);
efe = null;
_fishing = false;
_fishx = 0;
_fishy = 0;
_fishz = 0;
broadcastUserInfo();
if(_fishCombat == null)
{
sendPacket(new SystemMessage(SystemMessageId.BAIT_LOST_FISH_GOT_AWAY));
}
_fishCombat = null;
_lure = null;
//Ends fishing
sendPacket(new SystemMessage(SystemMessageId.REEL_LINE_AND_STOP_FISHING));
setIsImobilised(false);
stopLookingForFishTask();
}
/**
* Gets the fish combat.
*
* @return the l2 fishing
*/
public L2Fishing GetFishCombat()
{
return _fishCombat;
}
/**
* Gets the fishx.
*
* @return the int
*/
public int GetFishx()
{
return _fishx;
}
/**
* Gets the fishy.
*
* @return the int
*/
public int GetFishy()
{
return _fishy;
}
/**
* Gets the fishz.
*
* @return the int
*/
public int GetFishz()
{
return _fishz;
}
public void SetPartyFind(int find)
{
_party_find = find;
}
public int GetPartyFind()
{
return _party_find;
}
/**
* Sets the lure.
*
* @param lure the lure
*/
public void SetLure(L2ItemInstance lure)
{
_lure = lure;
}
/**
* Gets the lure.
*
* @return the l2 item instance
*/
public L2ItemInstance GetLure()
{
return _lure;
}
/**
* Gets the inventory limit.
*
* @return the int
*/
public int getInventoryLimit()
{
int ivlim;
if(isGM())
{
ivlim = Config.INVENTORY_MAXIMUM_GM;
}
else if(getRace() == Race.dwarf)
{
ivlim = Config.INVENTORY_MAXIMUM_DWARF;
}
else
{
ivlim = Config.INVENTORY_MAXIMUM_NO_DWARF;
}
ivlim += (int) getStat().calcStat(Stats.INV_LIM, 0, null, null);
return ivlim;
}
/**
* Gets the ware house limit.
*
* @return the int
*/
public int GetWareHouseLimit()
{
int whlim;
if(getRace() == Race.dwarf)
{
whlim = Config.WAREHOUSE_SLOTS_DWARF;
}
else
{
whlim = Config.WAREHOUSE_SLOTS_NO_DWARF;
}
whlim += (int) getStat().calcStat(Stats.WH_LIM, 0, null, null);
return whlim;
}
/**
* Gets the private sell store limit.
*
* @return the int
*/
public int GetPrivateSellStoreLimit()
{
int pslim;
if(getRace() == Race.dwarf)
{
pslim = Config.MAX_PVTSTORE_SLOTS_DWARF;
}
else
{
pslim = Config.MAX_PVTSTORE_SLOTS_OTHER;
}
pslim += (int) getStat().calcStat(Stats.P_SELL_LIM, 0, null, null);
return pslim;
}
/**
* Gets the private buy store limit.
*
* @return the int
*/
public int GetPrivateBuyStoreLimit()
{
int pblim;
if(getRace() == Race.dwarf)
{
pblim = Config.MAX_PVTSTORE_SLOTS_DWARF;
}
else
{
pblim = Config.MAX_PVTSTORE_SLOTS_OTHER;
}
pblim += (int) getStat().calcStat(Stats.P_BUY_LIM, 0, null, null);
return pblim;
}
/**
* Gets the freight limit.
*
* @return the int
*/
public int GetFreightLimit()
{
return Config.FREIGHT_SLOTS + (int) getStat().calcStat(Stats.FREIGHT_LIM, 0, null, null);
}
/**
* Gets the dwarf recipe limit.
*
* @return the int
*/
public int GetDwarfRecipeLimit()
{
int recdlim = Config.DWARF_RECIPE_LIMIT;
recdlim += (int) getStat().calcStat(Stats.REC_D_LIM, 0, null, null);
return recdlim;
}
/**
* Gets the common recipe limit.
*
* @return the int
*/
public int GetCommonRecipeLimit()
{
int recclim = Config.COMMON_RECIPE_LIMIT;
recclim += (int) getStat().calcStat(Stats.REC_C_LIM, 0, null, null);
return recclim;
}
/**
* Sets the mount object id.
*
* @param newID the new mount object id
*/
public void setMountObjectID(int newID)
{
_mountObjectID = newID;
}
/**
* Gets the mount object id.
*
* @return the mount object id
*/
public int getMountObjectID()
{
return _mountObjectID;
}
/** The _lure. */
private L2ItemInstance _lure = null;
/**
* Get the current skill in use or return null.<BR>
* <BR>
*
* @return the current skill
*/
public SkillDat getCurrentSkill()
{
return _currentSkill;
}
/**
* Create a new SkillDat object and set the player _currentSkill.<BR>
* <BR>
*
* @param currentSkill the current skill
* @param ctrlPressed the ctrl pressed
* @param shiftPressed the shift pressed
*/
public void setCurrentSkill(L2Skill currentSkill, boolean ctrlPressed, boolean shiftPressed)
{
if(currentSkill == null)
{
if(Config.DEBUG)
{
_log.info("Setting current skill: NULL for " + getName() + ".");
}
_currentSkill = null;
return;
}
if(Config.DEBUG)
{
_log.info("Setting current skill: " + currentSkill.getName() + " (ID: " + currentSkill.getId() + ") for " + getName() + ".");
}
_currentSkill = new SkillDat(currentSkill, ctrlPressed, shiftPressed);
}
/**
* Gets the queued skill.
*
* @return the queued skill
*/
public SkillDat getQueuedSkill()
{
return _queuedSkill;
}
/**
* Create a new SkillDat object and queue it in the player _queuedSkill.<BR>
* <BR>
*
* @param queuedSkill the queued skill
* @param ctrlPressed the ctrl pressed
* @param shiftPressed the shift pressed
*/
public void setQueuedSkill(L2Skill queuedSkill, boolean ctrlPressed, boolean shiftPressed)
{
if(queuedSkill == null)
{
if(Config.DEBUG)
{
_log.info("Setting queued skill: NULL for " + getName() + ".");
}
_queuedSkill = null;
return;
}
if(Config.DEBUG)
{
_log.info("Setting queued skill: " + queuedSkill.getName() + " (ID: " + queuedSkill.getId() + ") for " + getName() + ".");
}
_queuedSkill = new SkillDat(queuedSkill, ctrlPressed, shiftPressed);
}
/**
* Gets the power grade.
*
* @return the power grade
*/
public int getPowerGrade()
{
return _powerGrade;
}
/**
* Sets the power grade.
*
* @param power the new power grade
*/
public void setPowerGrade(int power)
{
_powerGrade = power;
}
/**
* Checks if is cursed weapon equiped.
*
* @return true, if is cursed weapon equiped
*/
public boolean isCursedWeaponEquiped()
{
return _cursedWeaponEquipedId != 0;
}
/**
* Sets the cursed weapon equiped id.
*
* @param value the new cursed weapon equiped id
*/
public void setCursedWeaponEquipedId(int value)
{
_cursedWeaponEquipedId = value;
}
/**
* Gets the cursed weapon equiped id.
*
* @return the cursed weapon equiped id
*/
public int getCursedWeaponEquipedId()
{
return _cursedWeaponEquipedId;
}
/** The _charm of courage. */
private boolean _charmOfCourage = false;
/**
* Gets the charm of courage.
*
* @return the charm of courage
*/
public boolean getCharmOfCourage()
{
return _charmOfCourage;
}
/**
* Sets the charm of courage.
*
* @param val the new charm of courage
*/
public void setCharmOfCourage(boolean val)
{
_charmOfCourage = val;
sendPacket(new EtcStatusUpdate(this));
}
/**
* Gets the death penalty buff level.
*
* @return the death penalty buff level
*/
public int getDeathPenaltyBuffLevel()
{
return _deathPenaltyBuffLevel;
}
/**
* Sets the death penalty buff level.
*
* @param level the new death penalty buff level
*/
public void setDeathPenaltyBuffLevel(int level)
{
_deathPenaltyBuffLevel = level;
}
/**
* Calculate death penalty buff level.
*
* @param killer the killer
*/
public void calculateDeathPenaltyBuffLevel(L2Character killer)
{
if(Rnd.get(100) <= Config.DEATH_PENALTY_CHANCE && !(killer instanceof L2PcInstance) && !isGM() && !(getCharmOfLuck() && (killer instanceof L2GrandBossInstance || killer instanceof L2RaidBossInstance)) && !(isInsideZone(L2Character.ZONE_PVP) || isInsideZone(L2Character.ZONE_SIEGE) || isInsideZone(L2Character.ZONE_EVENT)
|| !(isInsideZone(L2Character.ZONE_CHAOTIC) || killer.isRaid())))
{
increaseDeathPenaltyBuffLevel();
}
}
/**
* Increase death penalty buff level.
*/
public void increaseDeathPenaltyBuffLevel()
{
if(getDeathPenaltyBuffLevel() >= 15) //maximum level reached
return;
if(getDeathPenaltyBuffLevel() != 0)
{
L2Skill skill = SkillTable.getInstance().getInfo(5076, getDeathPenaltyBuffLevel());
if(skill != null)
{
removeSkill(skill, true);
skill = null;
}
}
_deathPenaltyBuffLevel++;
addSkill(SkillTable.getInstance().getInfo(5076, getDeathPenaltyBuffLevel()), false);
sendPacket(new EtcStatusUpdate(this));
SystemMessage sm = new SystemMessage(SystemMessageId.DEATH_PENALTY_LEVEL_S1_ADDED);
sm.addNumber(getDeathPenaltyBuffLevel());
sendPacket(sm);
sm = null;
sendSkillList();
}
/**
* Reduce death penalty buff level.
*/
public void reduceDeathPenaltyBuffLevel()
{
if(getDeathPenaltyBuffLevel() <= 0)
return;
L2Skill skill = SkillTable.getInstance().getInfo(5076, getDeathPenaltyBuffLevel());
if(skill != null)
{
removeSkill(skill, true);
skill = null;
sendSkillList();
}
_deathPenaltyBuffLevel--;
if(getDeathPenaltyBuffLevel() > 0)
{
addSkill(SkillTable.getInstance().getInfo(5076, getDeathPenaltyBuffLevel()), false);
sendPacket(new EtcStatusUpdate(this));
SystemMessage sm = new SystemMessage(SystemMessageId.DEATH_PENALTY_LEVEL_S1_ADDED);
sm.addNumber(getDeathPenaltyBuffLevel());
sendPacket(sm);
sm = null;
sendSkillList();
}
else
{
sendPacket(new EtcStatusUpdate(this));
sendPacket(new SystemMessage(SystemMessageId.DEATH_PENALTY_LIFTED));
}
}
/**
* restore all Custom Data hero/noble/donator.
*/
public void restoreCustomStatus()
{
if(Config.DEVELOPER)
{
_log.info("Restoring character status "+getName()+" from database...");
}
int hero = 0;
int noble = 0;
int donator = 0;
long hero_end = 0;
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection(false);
PreparedStatement statement = con.prepareStatement(STATUS_DATA_GET);
statement.setInt(1, getObjectId());
ResultSet rset = statement.executeQuery();
while(rset.next())
{
hero = rset.getInt("hero");
noble = rset.getInt("noble");
donator = rset.getInt("donator");
hero_end = rset.getLong("hero_end_date");
}
rset.close();
statement.close();
statement = null;
rset = null;
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("Error: could not restore char custom data info: " + e);
}
finally
{
CloseUtil.close(con);
}
if(hero > 0 && (hero_end == 0 || hero_end > System.currentTimeMillis()))
{
setHero(true);
}else{
//delete wings of destiny
destroyItem("HeroEnd", 6842, 1, null, false);
}
if(noble > 0)
{
setNoble(true);
}
if(donator > 0)
{
setDonator(true);
}
}
/**
* Restore death penalty buff level.
*/
public void restoreDeathPenaltyBuffLevel()
{
L2Skill skill = SkillTable.getInstance().getInfo(5076, getDeathPenaltyBuffLevel());
if(skill != null)
{
removeSkill(skill, true);
skill = null;
}
if(getDeathPenaltyBuffLevel() > 0)
{
addSkill(SkillTable.getInstance().getInfo(5076, getDeathPenaltyBuffLevel()), false);
SystemMessage sm = new SystemMessage(SystemMessageId.DEATH_PENALTY_LEVEL_S1_ADDED);
sm.addNumber(getDeathPenaltyBuffLevel());
sendPacket(sm);
sm = null;
}
sendPacket(new EtcStatusUpdate(this));
}
/** The Reuse time stamps. */
private FastMap<Integer, TimeStamp> ReuseTimeStamps = new FastMap<Integer, TimeStamp>().shared();
/**
* Simple class containing all neccessary information to maintain valid timestamps and reuse for skills upon relog.
* Filter this carefully as it becomes redundant to store reuse for small delays.
*
* @author Yesod
public class TimeStamp
{
private int skill;
private long reuse;
private Date stamp;
public TimeStamp(int _skill, long _reuse)
{
skill = _skill;
reuse = _reuse;
stamp = new Date(new Date().getTime() + reuse);
}
public int getSkill()
{
return skill;
}
public long getReuse()
{
return reuse;
}
public boolean hasNotPassed()
{
Date d = new Date();
if(d.before(stamp))
{
reuse -= d.getTime() - (stamp.getTime() - reuse);
return true;
}
return false;
}
}
*/
public static class TimeStamp
{
public long getStamp()
{
return stamp;
}
public int getSkill()
{
return skill;
}
public long getReuse()
{
return reuse;
}
public long getRemaining()
{
return Math.max(stamp - System.currentTimeMillis(), 0L);
}
protected boolean hasNotPassed()
{
return System.currentTimeMillis() < stamp;
}
private int skill;
private long reuse;
private long stamp;
protected TimeStamp(int _skill, long _reuse)
{
skill = _skill;
reuse = _reuse;
stamp = System.currentTimeMillis() + reuse;
}
protected TimeStamp(int _skill, long _reuse, long _systime)
{
skill = _skill;
reuse = _reuse;
stamp = _systime;
}
}
/**
* Index according to skill id the current timestamp of use.
*
* @param s the s
* @param r the r
*/
@Override
public void addTimeStamp(int s, int r)
{
ReuseTimeStamps.put(s, new TimeStamp(s, r));
}
/**
* Index according to skill this TimeStamp instance for restoration purposes only.
*
* @param T the t
*/
private void addTimeStamp(TimeStamp T)
{
ReuseTimeStamps.put(T.getSkill(), T);
}
/**
* Index according to skill id the current timestamp of use.
*
* @param s the s
*/
@Override
public void removeTimeStamp(int s)
{
ReuseTimeStamps.remove(s);
}
public Collection<TimeStamp> getReuseTimeStamps()
{
return ReuseTimeStamps.values();
}
public void resetSkillTime(boolean ssl)
{
L2Skill arr$[] = getAllSkills();
int len$ = arr$.length;
for(int i$ = 0; i$ < len$; i$++)
{
L2Skill skill = arr$[i$];
if(skill != null && skill.isActive() && skill.getId() != 1324)
enableSkill(skill.getId());
}
if(ssl)
sendSkillList();
sendPacket(new SkillCoolTime(this));
}
/*
public boolean isInDangerArea()
{
return isInDangerArea;
}
public void enterDangerArea()
{
L2Skill skill = SkillTable.getInstance().getInfo(4268, 1);
if(skill != null)
{
removeSkill(skill, true);
skill = null;
}
addSkill(skill, false);
isInDangerArea = true;
sendPacket(new EtcStatusUpdate(this));
SystemMessage sm = new SystemMessage(SystemMessageId.S1_S2);
sm.addString("You have entered a danger area");
sendPacket(sm);
sm = null;
}
public void exitDangerArea()
{
L2Skill skill = SkillTable.getInstance().getInfo(4268, 1);
if(skill != null)
{
removeSkill(skill, true);
skill = null;
}
isInDangerArea = false;
sendPacket(new EtcStatusUpdate(this));
SystemMessage sm = new SystemMessage(SystemMessageId.S1_S2);
sm.addString("You have left a danger area");
sendPacket(sm);
sm = null;
}
*/
/* (non-Javadoc)
* @see com.l2jfrozen.gameserver.model.L2Character#sendDamageMessage(com.l2jfrozen.gameserver.model.L2Character, int, boolean, boolean, boolean)
*/
@Override
public final void sendDamageMessage(L2Character target, int damage, boolean mcrit, boolean pcrit, boolean miss)
{
// Check if hit is missed
if(miss)
{
sendPacket(new SystemMessage(SystemMessageId.MISSED_TARGET));
return;
}
// Check if hit is critical
if(pcrit)
{
sendPacket(new SystemMessage(SystemMessageId.CRITICAL_HIT));
}
if(mcrit)
{
sendPacket(new SystemMessage(SystemMessageId.CRITICAL_HIT_MAGIC));
}
if (isInOlympiadMode() && target instanceof L2PcInstance &&
((L2PcInstance) target).isInOlympiadMode() && ((L2PcInstance) target).getOlympiadGameId() == getOlympiadGameId())
{
Olympiad.getInstance().notifyCompetitorDamage(this, damage, getOlympiadGameId());
}
SystemMessage sm = new SystemMessage(SystemMessageId.YOU_DID_S1_DMG);
sm.addNumber(damage);
sendPacket(sm);
sm = null;
}
/**
* Update title.
*/
public void updateTitle()
{
setTitle(Config.PVP_TITLE_PREFIX + getPvpKills() + Config.PK_TITLE_PREFIX + getPkKills() + " ");
}
/**
* Return true if last request is expired.
*
* @return true, if is request expired
*/
public boolean isRequestExpired()
{
return !(_requestExpireTime > GameTimeController.getGameTicks());
}
/** The _gm status. */
boolean _gmStatus = true; //true by default sincce this is used by GMS
// private Object _BanChatTask;
// private long _banchat_timer;
/**
* Sets the gm status active.
*
* @param state the new gm status active
*/
public void setGmStatusActive(boolean state)
{
_gmStatus = state;
}
/**
* Checks for gm status active.
*
* @return true, if successful
*/
public boolean hasGmStatusActive()
{
return _gmStatus;
}
/*
//////////////////////////////////////////////////////////////////
//START CHAT BAN SYSTEM
//////////////////////////////////////////////////////////////////
public void setChatBanTimer(long time)
{
_chatBanTimer = time;
}
private void updateChatBanState()
{
if(_chatBanTimer > 0L)
{
_chatBanned = true;
_chatBanTask = ThreadPoolManager.getInstance().scheduleGeneral(new ChatBanTask(this), _chatBanTimer);
sendPacket(new EtcStatusUpdate(this));
}
}
public void stopChatBanTask(boolean save)
{
if(_chatBanTask != null)
{
if(save)
{
long delay = _chatBanTask.getDelay(TimeUnit.MILLISECONDS);
if(delay < 0L)
{
delay = 0L;
}
setChatBanTimer(delay);
}
_chatBanTask.cancel(false);
_chatBanned = false;
_chatBanTask = null;
sendPacket(new EtcStatusUpdate(this));
}
}
public void setChatBanned(boolean state, long delayInSec)
{
_chatBanned = state;
_chatBanTimer = 0L;
stopChatBanTask(false);
if(_chatBanned && delayInSec > 0)
{
_chatBanTimer = delayInSec;
_chatBanTask = ThreadPoolManager.getInstance().scheduleGeneral(new ChatBanTask(this), _chatBanTimer);
sendMessage("\u0412\u0430\u0448 \u0447\u0430\u0442 \u0437\u0430\u0431\u0430\u043D\u0435\u043D \u043D\u0430 " + _chatBanTimer / 60 / 1000 + " \u043C\u0438\u043D\u0443\u0442.");
sendPacket(new EtcStatusUpdate(this));
}
storeCharBase();
}
public long getChatBanTimer()
{
if(_chatBanned && _chatBanTask!=null)
{
long delay = _chatBanTask.getDelay(TimeUnit.MILLISECONDS);
if(delay >= 0L)
{
_chatBanTimer = delay;
}
}
return _chatBanTimer;
}
private class ChatBanTask implements Runnable
{
L2PcInstance _player;
//protected long _startedAt;
protected ChatBanTask(L2PcInstance player)
{
_player = player;
//_startedAt = System.currentTimeMillis();
}
public void run()
{
_player.setChatBanned(false, 0);
}
}
*/
//////////////////////////////////////////////////////////////////
//END CHAT BAN SYSTEM
//////////////////////////////////////////////////////////////////
/** The _saymode. */
public L2Object _saymode = null;
/**
* Gets the say mode.
*
* @return the say mode
*/
public L2Object getSayMode()
{
return _saymode;
}
/**
* Sets the say mode.
*
* @param say the new say mode
*/
public void setSayMode(L2Object say)
{
_saymode = say;
}
/**
* Save event stats.
*/
public void saveEventStats()
{
_originalNameColor = getAppearance().getNameColor();
_originalKarma = getKarma();
_eventKills = 0;
}
/**
* Restore event stats.
*/
public void restoreEventStats()
{
getAppearance().setNameColor(_originalNameColor);
setKarma(_originalKarma);
_eventKills = 0;
}
/**
* Gets the current skill world position.
*
* @return the current skill world position
*/
public Point3D getCurrentSkillWorldPosition()
{
return _currentSkillWorldPosition;
}
/**
* Sets the current skill world position.
*
* @param worldPosition the new current skill world position
*/
public void setCurrentSkillWorldPosition(final Point3D worldPosition)
{
_currentSkillWorldPosition = worldPosition;
}
////////////////////////////////////////////////
/**
* Checks if is cursed weapon equipped.
*
* @return true, if is cursed weapon equipped
*/
public boolean isCursedWeaponEquipped()
{
return _cursedWeaponEquipedId != 0;
}
// public void setCombatFlagEquipped(boolean value)
// {
// _combatFlagEquippedId = value;
// }
/**
* Dismount.
*
* @return true, if successful
*/
public boolean dismount()
{
if(setMountType(0))
{
if(isFlying())
{
removeSkill(SkillTable.getInstance().getInfo(4289, 1));
}
Ride dismount = new Ride(getObjectId(), Ride.ACTION_DISMOUNT, 0);
broadcastPacket(dismount);
dismount = null;
setMountObjectID(0);
// Notify self and others about speed change
broadcastUserInfo();
return true;
}
return false;
}
/**
* Gets the pc bang score.
*
* @return the pc bang score
*/
public int getPcBangScore()
{
return pcBangPoint;
}
/**
* Reduce pc bang score.
*
* @param to the to
*/
public void reducePcBangScore(int to)
{
pcBangPoint -= to;
updatePcBangWnd(to, false, false);
}
/**
* Adds the pc bang score.
*
* @param to the to
*/
public void addPcBangScore(int to)
{
pcBangPoint += to;
}
/**
* Update pc bang wnd.
*
* @param score the score
* @param add the add
* @param duble the duble
*/
public void updatePcBangWnd(int score, boolean add, boolean duble)
{
ExPCCafePointInfo wnd = new ExPCCafePointInfo(this, score, add, 24, duble);
sendPacket(wnd);
}
/**
* Show pc bang window.
*/
public void showPcBangWindow()
{
ExPCCafePointInfo wnd = new ExPCCafePointInfo(this, 0, false, 24, false);
sendPacket(wnd);
}
/**
* Checks if is offline.
*
* @return true, if is offline
*/
public boolean isOffline()
{
return _isOffline;
}
/**
* Sets the offline.
*
* @param set the new offline
*/
public void setOffline(boolean set)
{
_isOffline = set;
}
/**
* Checks if is trade disabled.
*
* @return true, if is trade disabled
*/
public boolean isTradeDisabled()
{
return _isTradeOff || isCastingNow();
}
/**
* Sets the trade disabled.
*
* @param set the new trade disabled
*/
public void setTradeDisabled(boolean set)
{
_isTradeOff = set;
}
/**
* Show teleport html.
*/
public void showTeleportHtml()
{
TextBuilder text = new TextBuilder();
text.append("<html>");
text.append("<body>");
text.append("<title></title>");
text.append("<center>");
text.append("<img src=\"L2UI_CH3.herotower_deco\" width=256 height=32>");
text.append("<br><br>");
text.append("<table width=\"85%\"><tr><td>Your party leader, "+getParty().getLeader().getName()+", requested a group teleport to raidboss. You have 30 seconds from this popup to teleport, or the teleport windows will close</td></tr></table><br>");
text.append("<a action=\"bypass -h rbAnswear\">Port with my party</a><br>");
text.append("<a action=\"bypass -h rbAnswearDenied\">Don't port</a><br1>");
text.append("<center><img src=\"L2UI.SquareGray\" width=\"280\" height=\"1\">");
text.append("<font color=\"999999\">Gates of Fire</font></center>");
text.append("</body>");
text.append("</html>");
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setHtml(text.toString());
sendPacket(html);
}
/** The Dropzor. */
String Dropzor = "Coin of Luck";
/**
* Show raidboss info level40.
*/
public void showRaidbossInfoLevel40()
{
TextBuilder text = new TextBuilder();
text.append("<html>");
text.append("<body>");
text.append("<title>Raidboss Level (40-45)</title>");
text.append("<center>");
text.append("<img src=\"L2UI_CH3.herotower_deco\" width=256 height=32>");
text.append("</center>");
text.append("<br><br>");
text.append("<table width=\"85%\"><tr><td>Drop: "+Dropzor+"</td></tr></table>");
text.append("Leto Chief Talkin (40)<br1>");
text.append("Water Spirit Lian (40) <br1>");
text.append("Shaman King Selu (40) <br1>");
text.append("Gwindorr (40) <br1>");
text.append("Icarus Sample 1 (40) <br1>");
text.append("Fafurion's Page Sika (40) <br1>");
text.append("Nakondas (40) <br1>");
text.append("Road Scavenger Leader (40)<br1>");
text.append("Wizard of Storm Teruk (40) <br1>");
text.append("Water Couatle Ateka (40)<br1>");
text.append("Crazy Mechanic Golem (43) <br1>");
text.append("Earth Protector Panathen (43) <br1>");
text.append("Thief Kelbar (44) <br1>");
text.append("Timak Orc Chief Ranger (44) <br1>");
text.append("Rotten Tree Repiro (44) <br1>");
text.append("Dread Avenger Kraven (44) <br1>");
text.append("Biconne of Blue Sky (45)<br1>");
text.append("Evil Spirit Cyrion (45) <br1>");
text.append("Iron Giant Totem (45) <br1>");
text.append("Timak Orc Gosmos (45) <br1>");
text.append("Shacram (45) <br1>");
text.append("Fafurion's Henchman Istary (45) <br1>");
text.append("<center><img src=\"L2UI.SquareGray\" width=\"280\" height=\"1\">");
text.append("<font color=\"999999\">Gates of Fire</font></center>");
text.append("</body>");
text.append("</html>");
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setHtml(text.toString());
sendPacket(html);
}
/**
* Show raidboss info level45.
*/
public void showRaidbossInfoLevel45()
{
TextBuilder text = new TextBuilder();
text.append("<html>");
text.append("<body>");
text.append("<title>Raidboss Level (45-50)</title>");
text.append("<center>");
text.append("<img src=\"L2UI_CH3.herotower_deco\" width=256 height=32>");
text.append("</center>");
text.append("<br><br>");
text.append("<table width=\"85%\"><tr><td>Drop: "+Dropzor+"</td></tr></table>");
text.append("Necrosentinel Royal Guard (47) <br1>");
text.append("Barion (47) <br1>");
text.append("Orfen's Handmaiden (48) <br1>");
text.append("King Tarlk (48) <br1>");
text.append("Katu Van Leader Atui (49) <br1>");
text.append("Mirror of Oblivion (49) <br1>");
text.append("Karte (49) <br1>");
text.append("Ghost of Peasant Leader (50) <br1>");
text.append("Cursed Clara (50) <br1>");
text.append("Carnage Lord Gato (50) <br1>");
text.append("Fafurion's Henchman Istary (45) <br1>");
text.append("<center><img src=\"L2UI.SquareGray\" width=\"280\" height=\"1\">");
text.append("<font color=\"999999\">Gates of Fire</font></center>");
text.append("</body>");
text.append("</html>");
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setHtml(text.toString());
sendPacket(html);
}
/**
* Show raidboss info level50.
*/
public void showRaidbossInfoLevel50()
{
TextBuilder text = new TextBuilder();
text.append("<html>");
text.append("<body>");
text.append("<title>Raidboss Level (50-55)</title>");
text.append("<center>");
text.append("<img src=\"L2UI_CH3.herotower_deco\" width=256 height=32>");
text.append("</center>");
text.append("<br><br>");
text.append("<table width=\"85%\"><tr><td>Drop: "+Dropzor+"</td></tr></table>");
text.append("Verfa (51) <br1>");
text.append("Deadman Ereve (51) <br1>");
text.append("Captain of Red Flag Shaka (52) <br1>");
text.append("Grave Robber Kim (52) <br1>");
text.append("Paniel the Unicorn (54) <br1>");
text.append("Bandit Leader Barda (55) <br1>");
text.append("Eva's Spirit Niniel (55) <br1>");
text.append("Beleth's Seer Sephia (55) <br1>");
text.append("Pagan Watcher Cerberon (55) <br1>");
text.append("Shaman King Selu (55) <br1>");
text.append("Black Lily (55) <br1>");
text.append("Ghost Knight Kabed (55) <br1>");
text.append("Sorcerer Isirr (55) <br1>");
text.append("Furious Thieles (55) <br1>");
text.append("Enchanted Forest Watcher Ruell (55) <br1>");
text.append("<center><img src=\"L2UI.SquareGray\" width=\"280\" height=\"1\">");
text.append("<font color=\"999999\">Gates of Fire</font></center>");
text.append("</body>");
text.append("</html>");
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setHtml(text.toString());
sendPacket(html);
}
/**
* Show raidboss info level55.
*/
public void showRaidbossInfoLevel55()
{
TextBuilder text = new TextBuilder();
text.append("<html>");
text.append("<body>");
text.append("<title>Raidboss Level (55-60)</title>");
text.append("<center>");
text.append("<img src=\"L2UI_CH3.herotower_deco\" width=256 height=32>");
text.append("</center>");
text.append("<br><br>");
text.append("<table width=\"85%\"><tr><td>Drop: "+Dropzor+"</td></tr></table>");
text.append("Fairy Queen Timiniel (56) <br1>");
text.append("Harit Guardian Garangky (56) <br1>");
text.append("Refugee Hopeful Leo (56) <br1>");
text.append("Timak Seer Ragoth (57) <br1>");
text.append("Soulless Wild Boar (59) <br1>");
text.append("Abyss Brukunt (59) <br1>");
text.append("Giant Marpanak (60) <br1>");
text.append("Ghost of the Well Lidia (60) <br1>");
text.append("Guardian of the Statue of Giant Karum (60) <br1>");
text.append("The 3rd Underwater Guardian (60) <br1>");
text.append("Taik High Prefect Arak (60) <br1>");
text.append("Ancient Weird Drake (60) <br1>");
text.append("Lord Ishka (60) <br1>");
text.append("<center><img src=\"L2UI.SquareGray\" width=\"280\" height=\"1\">");
text.append("<font color=\"999999\">Gates of Fire</font></center>");
text.append("</body>");
text.append("</html>");
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setHtml(text.toString());
sendPacket(html);
}
/**
* Show raidboss info level60.
*/
public void showRaidbossInfoLevel60()
{
TextBuilder text = new TextBuilder();
text.append("<html>");
text.append("<body>");
text.append("<title>Raidboss Level (60-65)</title>");
text.append("<center>");
text.append("<img src=\"L2UI_CH3.herotower_deco\" width=256 height=32>");
text.append("</center>");
text.append("<br><br>");
text.append("<table width=\"85%\"><tr><td>Drop: "+Dropzor+"</td></tr></table>");
text.append("Roaring Lord Kastor (62) <br1>");
text.append("Gorgolos (64) <br1>");
text.append("Hekaton Prime (65) <br1>");
text.append("Gargoyle Lord Tiphon (65) <br1>");
text.append("Fierce Tiger King Angel (65) <br1>");
text.append("Enmity Ghost Ramdal (65) <br1>");
text.append("Rahha (65) <br1>");
text.append("Shilen's Priest Hisilrome (65) <br1>");
text.append("<center><img src=\"L2UI.SquareGray\" width=\"280\" height=\"1\">");
text.append("<font color=\"999999\">Gates of Fire</font></center>");
text.append("</body>");
text.append("</html>");
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setHtml(text.toString());
sendPacket(html);
}
/**
* Show raidboss info level65.
*/
public void showRaidbossInfoLevel65()
{
TextBuilder text = new TextBuilder();
text.append("<html>");
text.append("<body>");
text.append("<title>Raidboss Level (65-70)</title>");
text.append("<br><br>");
text.append("<center>");
text.append("<table width=\"85%\"><tr><td>Drop: "+Dropzor+"</td></tr></table>");
text.append("</center>");
text.append("Demon's Agent Falston (66) <br1>");
text.append("Last Titan utenus (66) <br1>");
text.append("Kernon's Faithful Servant Kelone (67) <br1>");
text.append("Spirit of Andras, the Betrayer (69) <br1>");
text.append("Bloody Priest Rudelto (69) <br1>");
text.append("Shilen's Messenger Cabrio (70) <br1>");
text.append("Anakim's Nemesis Zakaron (70) <br1>");
text.append("Flame of Splendor Barakiel (70) <br1>");
text.append("Roaring Skylancer (70) <br1>");
text.append("Beast Lord Behemoth (70) <br1>");
text.append("Palibati Queen Themis (70) <br1>");
text.append("Fafurion''s Herald Lokness (70) <br1>");
text.append("Meanas Anor (70) <br1>");
text.append("Korim (70) <br1>");
text.append("<center><img src=\"L2UI.SquareGray\" width=\"280\" height=\"1\">");
text.append("<font color=\"999999\">Gates of Fire</font></center>");
text.append("</body>");
text.append("</html>");
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setHtml(text.toString());
sendPacket(html);
}
/**
* Show raidboss info level70.
*/
public void showRaidbossInfoLevel70()
{
TextBuilder text = new TextBuilder();
text.append("<html>");
text.append("<body>");
text.append("<title>Raidboss Level (70-75)</title>");
text.append("<center>");
text.append("<img src=\"L2UI_CH3.herotower_deco\" width=256 height=32>");
text.append("</center>");
text.append("<br><br>");
text.append("<table width=\"85%\"><tr><td>Drop: "+Dropzor+"</td></tr></table>");
text.append("Immortal Savior Mardil (71) <br1>");
text.append("Vanor Chief Kandra (72) <br1>");
text.append("Water Dragon Seer Sheshark (72) <br1>");
text.append("Doom Blade Tanatos (72) <br1>");
text.append("Death Lord Hallate (73) <br1>");
text.append("Plague Golem (73) <br1>");
text.append("Icicle Emperor Bumbalump (74) <br1>");
text.append("Antharas Priest Cloe (74) <br1>");
text.append("Krokian Padisha Sobekk (74) <br1>");
text.append("<center><img src=\"L2UI.SquareGray\" width=\"280\" height=\"1\">");
text.append("<font color=\"999999\">Gates of Fire</font></center>");
text.append("</body>");
text.append("</html>");
NpcHtmlMessage html = new NpcHtmlMessage(1);
html.setHtml(text.toString());
sendPacket(html);
}
/** The isintwtown. */
private boolean isintwtown = false;
/**
* Checks if is inside tw town.
*
* @return true, if is inside tw town
*/
public boolean isInsideTWTown()
{
if(isintwtown)
return true;
return false;
}
/**
* Sets the inside tw town.
*
* @param b the new inside tw town
*/
public void setInsideTWTown(boolean b)
{
isintwtown = true;
}
/**
* check if local player can make multibox and also refresh local boxes instances number.
*
* @return true, if successful
*/
public boolean checkMultiBox(){
boolean output = true;
int boxes_number = 0; //this one
List<String> active_boxes = new ArrayList<String>();
if(getClient()!=null && getClient().getConnection()!=null && !getClient().getConnection().isClosed() && getClient().getConnection().getInetAddress()!=null ){
String thisip = getClient().getConnection().getInetAddress().getHostAddress();
final Collection<L2PcInstance> allPlayers = L2World.getInstance().getAllPlayers();
for(L2PcInstance player : allPlayers)
{
if(player != null)
{
if(!player.isOffline() && player.getClient()!=null && player.getClient().getConnection()!=null && !player.getClient().getConnection().isClosed() && player.getClient().getConnection().getInetAddress()!=null && !player.getName().equals(this.getName())){
String ip = player.getClient().getConnection().getInetAddress().getHostAddress();
if(thisip.equals(ip) && this != player)
{
if(!Config.ALLOW_DUALBOX){
output=false;
break;
}
if(boxes_number+1>Config.ALLOWED_BOXES){ //actual count+actual player one
output = false;
break;
}
boxes_number++;
active_boxes.add(player.getName());
}
}
}
}
}
if(output){
_active_boxes = boxes_number+1; //current number of boxes+this one
if(!active_boxes.contains(this.getName())){
active_boxes.add(this.getName());
this.active_boxes_characters = active_boxes;
}
refreshOtherBoxes();
}
/*
System.out.println("Player "+getName()+" has this boxes");
for(String name:active_boxes_characters){
System.out.println("*** "+name+" ***");
}
*/
return output;
}
/**
* increase active boxes number for local player and other boxer for same ip.
*/
public void refreshOtherBoxes(){
if(getClient()!=null && getClient().getConnection()!=null && !getClient().getConnection().isClosed() && getClient().getConnection().getInetAddress()!=null ){
String thisip = getClient().getConnection().getInetAddress().getHostAddress();
final Collection<L2PcInstance> allPlayers = L2World.getInstance().getAllPlayers();
L2PcInstance[] players = allPlayers.toArray(new L2PcInstance[allPlayers.size()]);
for(L2PcInstance player : players)
{
if(player != null && !player.isOffline())
{
if(player.getClient()!=null && player.getClient().getConnection()!=null && !player.getClient().getConnection().isClosed() && !player.getName().equals(this.getName())){
String ip = player.getClient().getConnection().getInetAddress().getHostAddress();
if(thisip.equals(ip) && this != player)
{
player._active_boxes = _active_boxes;
player.active_boxes_characters = active_boxes_characters;
/*
System.out.println("Player "+player.getName()+" has this boxes");
for(String name:player.active_boxes_characters){
System.out.println("*** "+name+" ***");
}
*/
}
}
}
}
}
}
/**
* descrease active boxes number for local player and other boxer for same ip.
*/
public void decreaseBoxes(){
_active_boxes=_active_boxes-1;
active_boxes_characters.remove(this.getName());
refreshOtherBoxes();
/*
if(getClient()!=null && !getClient().getConnection().isClosed()){
String thisip = getClient().getConnection().getSocketChannel().socket().getInetAddress().getHostAddress();
Collection<L2PcInstance> allPlayers = L2World.getInstance().getAllPlayers();
L2PcInstance[] players = allPlayers.toArray(new L2PcInstance[allPlayers.size()]);
for(L2PcInstance player : players)
{
if(player != null)
{
if(player.getClient()!=null && !player.getClient().getConnection().isClosed()){
String ip = player.getClient().getConnection().getSocketChannel().socket().getInetAddress().getHostAddress();
if(thisip.equals(ip) && this != player && player != null)
{
player._active_boxes = _active_boxes;
player.active_boxes_characters = active_boxes_characters;
System.out.println("Player "+player.getName()+" has this boxes");
for(String name:player.active_boxes_characters){
System.out.println("*** "+name+" ***");
}
}
}
}
}
}
*/
/*
System.out.println("Player "+getName()+" has this boxes");
for(String name:active_boxes_characters){
System.out.println("*** "+name+" ***");
}
*/
}
/**
* Aio System Start.
*
* @return true, if is aio
*/
public boolean isAio()
{
return _isAio;
}
/**
* Sets the aio.
*
* @param val the new aio
*/
public void setAio(boolean val)
{
_isAio = val;
}
/**
* Reward aio skills.
*/
public void rewardAioSkills()
{
L2Skill skill;
for(Integer skillid : Config.AIO_SKILLS.keySet())
{
int skilllvl = Config.AIO_SKILLS.get(skillid);
skill = SkillTable.getInstance().getInfo(skillid,skilllvl);
if(skill != null)
{
addSkill(skill, true);
}
}
sendMessage("GM give to you Aio's skills");
}
/**
* Lost aio skills.
*/
public void lostAioSkills()
{
L2Skill skill;
for(Integer skillid : Config.AIO_SKILLS.keySet())
{
int skilllvl = Config.AIO_SKILLS.get(skillid);
skill = SkillTable.getInstance().getInfo(skillid,skilllvl);
removeSkill(skill);
}
}
/**
* Sets the aio end time.
*
* @param val the new aio end time
*/
public void setAioEndTime(long val)
{
_aio_endTime = val;
}
/**
* Sets the end time.
*
* @param process the process
* @param val the val
*/
public void setEndTime(String process, int val)
{
if (val > 0)
{
long end_day;
Calendar calendar = Calendar.getInstance();
if (val >= 30)
{
while(val >= 30)
{
if(calendar.get(Calendar.MONTH)== 11)
calendar.roll(Calendar.YEAR, true);
calendar.roll(Calendar.MONTH, true);
val -= 30;
}
}
if (val < 30 && val > 0)
{
while(val > 0)
{
if(calendar.get(Calendar.DATE)== 28 && calendar.get(Calendar.MONTH) == 1)
calendar.roll(Calendar.MONTH, true);
if(calendar.get(Calendar.DATE)== 30)
{
if(calendar.get(Calendar.MONTH) == 11)
calendar.roll(Calendar.YEAR, true);
calendar.roll(Calendar.MONTH, true);
}
calendar.roll(Calendar.DATE, true);
val--;
}
}
end_day = calendar.getTimeInMillis();
if(process.equals("aio"))
_aio_endTime = end_day;
else
{
System.out.println("process "+ process + "no Known while try set end date");
return;
}
Date dt = new Date(end_day);
System.out.println(""+process +" end time for player " + getName() + " is " + dt);
}
else
{
if(process.equals("aio"))
_aio_endTime = 0;
else
{
System.out.println("process "+ process + "no Known while try set end date");
return;
}
}
}
/**
* Gets the aio end time.
*
* @return the aio end time
*/
public long getAioEndTime()
{
return _aio_endTime;
}
/**
* Gets the offline start time.
*
* @return the offline start time
*/
public long getOfflineStartTime()
{
return _offlineShopStart;
}
/**
* Sets the offline start time.
*
* @param time the new offline start time
*/
public void setOfflineStartTime(long time)
{
_offlineShopStart = time;
}
// during fall validations will be disabled for 10 ms.
/** The Constant FALLING_VALIDATION_DELAY. */
private static final int FALLING_VALIDATION_DELAY = 10000;
/** The _falling timestamp. */
private long _fallingTimestamp = 0;
/**
* Return true if character falling now
* On the start of fall return false for correct coord sync !.
*
* @param z the z
* @return true, if is falling
*/
public final boolean isFalling(int z)
{
if (isDead()
|| isFlying()
|| isInvul()
|| isInFunEvent()
|| isInsideZone(ZONE_WATER))
return false;
if (System.currentTimeMillis() < _fallingTimestamp)
return true;
final int deltaZ = getZ() - z;
if (deltaZ <= getBaseTemplate().getFallHeight())
return false;
final int damage = (int)Formulas.calcFallDam(this, deltaZ);
if (damage > 0)
{
reduceCurrentHp(Math.min(damage, getCurrentHp() - 1), null, false);
sendPacket(new SystemMessage(SystemMessageId.FALL_DAMAGE_S1).addNumber(damage));
}
setFalling();
return false;
}
/**
* Set falling timestamp.
*/
public final void setFalling()
{
_fallingTimestamp = System.currentTimeMillis() + FALLING_VALIDATION_DELAY;
}
/** Previous coordinate sent to party in ValidatePosition *. */
private Point3D _lastPartyPosition = new Point3D(0, 0, 0);
/**
* Sets the last party position.
*
* @param x the x
* @param y the y
* @param z the z
*/
public void setLastPartyPosition(int x, int y, int z)
{
_lastPartyPosition.setXYZ(x,y,z);
}
/**
* Gets the last party position distance.
*
* @param x the x
* @param y the y
* @param z the z
* @return the last party position distance
*/
public int getLastPartyPositionDistance(int x, int y, int z)
{
double dx = (x - _lastPartyPosition.getX());
double dy = (y - _lastPartyPosition.getY());
double dz = (z - _lastPartyPosition.getZ());
return (int)Math.sqrt(dx*dx + dy*dy + dz*dz);
}
/**
* Checks if is awaying.
*
* @return the _awaying
*/
public boolean isAwaying()
{
return _awaying;
}
/**
* Sets the _awaying.
*
* @param _awaying the _awaying to set
*/
public void set_awaying(boolean _awaying)
{
this._awaying = _awaying;
}
/**
* Checks if is locked.
*
* @return true, if is locked
*/
public boolean isLocked()
{
return _isLocked;
}
/**
* Sets the locked.
*
* @param a the new locked
*/
public void setLocked(boolean a)
{
_isLocked = a;
}
/**
* Checks if is stored.
*
* @return true, if is stored
*/
public boolean isStored()
{
return _isStored;
}
/**
* Sets the stored.
*
* @param a the new stored
*/
public void setStored(boolean a)
{
_isStored = a;
}
/** The _punish level. */
private PunishLevel _punishLevel = PunishLevel.NONE;
/** The _punish timer. */
private long _punishTimer = 0;
/** The _punish task. */
private ScheduledFuture<?> _punishTask;
/**
* The Enum PunishLevel.
*/
public enum PunishLevel
{
/** The NONE. */
NONE(0, ""),
/** The CHAT. */
CHAT(1, "chat banned"),
/** The JAIL. */
JAIL(2, "jailed"),
/** The CHAR. */
CHAR(3, "banned"),
/** The ACC. */
ACC(4, "banned");
/** The pun value. */
private final int punValue;
/** The pun string. */
private final String punString;
/**
* Instantiates a new punish level.
*
* @param value the value
* @param string the string
*/
PunishLevel(int value, String string)
{
punValue = value;
punString = string;
}
/**
* Value.
*
* @return the int
*/
public int value()
{
return punValue;
}
/**
* String.
*
* @return the string
*/
public String string()
{
return punString;
}
}
// open/close gates
@SuppressWarnings("synthetic-access")
private GatesRequest _gatesRequest = new GatesRequest();
private static class GatesRequest
{
private L2DoorInstance _target = null;
public void setTarget(L2DoorInstance door)
{
_target = door;
}
public L2DoorInstance getDoor()
{
return _target;
}
}
public void gatesRequest(L2DoorInstance door)
{
_gatesRequest.setTarget(door);
}
public void gatesAnswer(int answer, int type)
{
if (_gatesRequest.getDoor() == null)
return;
if (answer == 1 && getTarget() == _gatesRequest.getDoor() && type == 1)
_gatesRequest.getDoor().openMe();
else if (answer == 1 && getTarget() == _gatesRequest.getDoor() && type == 0)
_gatesRequest.getDoor().closeMe();
_gatesRequest.setTarget(null);
}
/**
* returns punishment level of player.
*
* @return the punish level
*/
public PunishLevel getPunishLevel()
{
return _punishLevel;
}
/**
* Checks if is in jail.
*
* @return True if player is jailed
*/
public boolean isInJail()
{
return _punishLevel == PunishLevel.JAIL;
}
/**
* Checks if is chat banned.
*
* @return True if player is chat banned
*/
public boolean isChatBanned()
{
return _punishLevel == PunishLevel.CHAT;
}
/**
* Sets the punish level.
*
* @param state the new punish level
*/
public void setPunishLevel(int state)
{
switch (state){
case 0 :
{
_punishLevel = PunishLevel.NONE;
break;
}
case 1 :
{
_punishLevel = PunishLevel.CHAT;
break;
}
case 2 :
{
_punishLevel = PunishLevel.JAIL;
break;
}
case 3 :
{
_punishLevel = PunishLevel.CHAR;
break;
}
case 4 :
{
_punishLevel = PunishLevel.ACC;
break;
}
}
}
/**
* Sets the punish level.
*
* @param state the state
* @param delayInMinutes the delay in minutes
*/
public void setPunishLevel(PunishLevel state, int delayInMinutes)
{
long delayInMilliseconds = delayInMinutes * 60000L;
setPunishLevel(state, delayInMilliseconds);
}
/**
* Sets punish level for player based on delay.
*
* @param state the state
* @param delayInMilliseconds 0 - Indefinite
*/
public void setPunishLevel(PunishLevel state, long delayInMilliseconds)
{
switch (state)
{
case NONE: // Remove Punishments
{
switch (_punishLevel)
{
case CHAT:
{
_punishLevel = state;
stopPunishTask(true);
sendPacket(new EtcStatusUpdate(this));
sendMessage("Your Chat ban has been lifted");
break;
}
case JAIL:
{
_punishLevel = state;
// Open a Html message to inform the player
NpcHtmlMessage htmlMsg = new NpcHtmlMessage(0);
String jailInfos = HtmCache.getInstance().getHtm("data/html/jail_out.htm");
if (jailInfos != null)
htmlMsg.setHtml(jailInfos);
else
htmlMsg.setHtml("<html><body>You are free for now, respect server rules!</body></html>");
sendPacket(htmlMsg);
stopPunishTask(true);
teleToLocation(17836, 170178, -3507, true); // Floran
break;
}
}
break;
}
case CHAT: // Chat Ban
{
// not allow player to escape jail using chat ban
if (_punishLevel == PunishLevel.JAIL)
break;
_punishLevel = state;
_punishTimer = 0;
sendPacket(new EtcStatusUpdate(this));
// Remove the task if any
stopPunishTask(false);
if (delayInMilliseconds > 0)
{
_punishTimer = delayInMilliseconds;
// start the countdown
int minutes = (int) (delayInMilliseconds/60000);
_punishTask = ThreadPoolManager.getInstance().scheduleGeneral(new PunishTask(this), _punishTimer);
sendMessage("You are chat banned for "+minutes+" minutes.");
}
else
sendMessage("You have been chat banned");
break;
}
case JAIL: // Jail Player
{
_punishLevel = state;
_punishTimer = 0;
// Remove the task if any
stopPunishTask(false);
if (delayInMilliseconds > 0)
{
_punishTimer = delayInMilliseconds; // Delay in milliseconds
// start the countdown
_punishTask = ThreadPoolManager.getInstance().scheduleGeneral(new PunishTask(this), _punishTimer);
sendMessage("You are in jail for "+delayInMilliseconds/60000+" minutes.");
}
if(_inEventCTF){
CTF.onDisconnect(this);
}else if(_inEventDM){
DM.onDisconnect(this);
}else if(_inEventTvT){
TvT.onDisconnect(this);
}else if(_inEventVIP){
VIP.onDisconnect(this);
}
if (Olympiad.getInstance().isRegisteredInComp(this))
Olympiad.getInstance().removeDisconnectedCompetitor(this);
{
if(this.isInLMS())
{
LastManStanding.joined--;
switch(LastManStanding.joined)
{
case 2:
{
for (L2PcInstance player : LastManStanding.players)
player.sendMessage("There are only two players left! Now its 1 versus 1");
break;
}
case 1:
{
for(L2PcInstance p : L2World.getInstance().getAllPlayers())
{
if (p.isInsideZone(L2Character.ZONE_EVENT))
{
LastManStanding.winner = p;
for (L2PcInstance player : LastManStanding.players)
player.sendMessage(LastManStanding.winner + " is the winner of the event.");
LastManStanding.endAndReward();
break;
}
}
}
}
}
}
// Open a Html message to inform the player
NpcHtmlMessage htmlMsg = new NpcHtmlMessage(0);
String jailInfos = HtmCache.getInstance().getHtm("data/html/jail_in.htm");
if (jailInfos != null)
htmlMsg.setHtml(jailInfos);
else
htmlMsg.setHtml("<html><body>You have been put in jail by an admin.</body></html>");
sendPacket(htmlMsg);
setInstanceId(0);
setIsIn7sDungeon(false);
teleToLocation(-114356, -249645, -2984, false); // Jail
break;
}
case CHAR: // Ban Character
{
setAccessLevel(-100);
logout();
break;
}
case ACC: // Ban Account
{
setAccountAccesslevel(-100);
logout();
break;
}
default:
{
_punishLevel = state;
break;
}
}
// store in database
storeCharBase();
}
public void setInArenaEvent(boolean val)
{
inArenaEvent = val;
}
public boolean isInArenaEvent()
{
return inArenaEvent;
}
private int arenaDefeats;
private int arenaWins;
public void increaseArenaDefeats()
{
arenaDefeats++;
}
public void increaseArenaWins()
{
arenaWins++;
}
private void setArenaDefeats(int val)
{
arenaDefeats = val;
}
private void setArenaWins(int val)
{
arenaWins = val;
}
/**
* Gets the punish timer.
*
* @return the punish timer
*/
public long getPunishTimer()
{
return _punishTimer;
}
/**
* Sets the punish timer.
*
* @param time the new punish timer
*/
public void setPunishTimer(long time)
{
_punishTimer = time;
}
/**
* Update punish state.
*/
private void updatePunishState()
{
if (getPunishLevel() != PunishLevel.NONE)
{
// If punish timer exists, restart punishtask.
if (_punishTimer > 0)
{
_punishTask = ThreadPoolManager.getInstance().scheduleGeneral(new PunishTask(this), _punishTimer);
sendMessage("You are still " + getPunishLevel().string() + " for " + (_punishTimer / 60000) + " minutes.");
}
if (getPunishLevel() == PunishLevel.JAIL)
{
// If player escaped, put him back in jail
if (!isInsideZone(ZONE_JAIL))
teleToLocation(-114356,-249645,-2984, true);
}
}
}
/**
* Stop punish task.
*
* @param save the save
*/
public void stopPunishTask(boolean save)
{
if (_punishTask != null)
{
if (save)
{
long delay = _punishTask.getDelay(TimeUnit.MILLISECONDS);
if (delay < 0)
delay = 0;
setPunishTimer(delay);
}
_punishTask.cancel(false);
ThreadPoolManager.getInstance().removeGeneral((Runnable)_punishTask);
_punishTask = null;
}
}
/**
* The Class PunishTask.
*/
private class PunishTask implements Runnable
{
/** The _player. */
L2PcInstance _player;
// protected long _startedAt;
/**
* Instantiates a new punish task.
*
* @param player the player
*/
protected PunishTask(L2PcInstance player)
{
_player = player;
// _startedAt = System.currentTimeMillis();
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
_player.setPunishLevel(PunishLevel.NONE, 0);
}
}
/**
* Gets the flood protectors.
*
* @return the flood protectors
*/
public FloodProtectors getFloodProtectors()
{
return getClient().getFloodProtectors();
}
/**
* Test if player inventory is under 80% capaity.
*
* @return true, if is inventory under80
*/
public boolean isInventoryUnder80()
{
if (getInventory().getSize() <= (getInventoryLimit() * 0.8))
{
return true;
}
return false;
}
// Multisell
/** The _current multi sell id. */
private int _currentMultiSellId = -1;
/**
* Gets the multi sell id.
*
* @return the multi sell id
*/
public final int getMultiSellId()
{
return _currentMultiSellId;
}
/**
* Sets the multi sell id.
*
* @param listid the new multi sell id
*/
public final void setMultiSellId(int listid)
{
_currentMultiSellId = listid;
}
/**
* Checks if is party waiting.
*
* @return true, if is party waiting
*/
public boolean isPartyWaiting()
{
return PartyMatchWaitingList.getInstance().getPlayers().contains(this);
}
// these values are only stored temporarily
/** The _partyroom. */
private int _partyroom = 0;
/**
* Sets the party room.
*
* @param id the new party room
*/
public void setPartyRoom(int id)
{
_partyroom = id;
}
/**
* Gets the party room.
*
* @return the party room
*/
public int getPartyRoom()
{
return _partyroom;
}
/**
* Checks if is in party match room.
*
* @return true, if is in party match room
*/
public boolean isInPartyMatchRoom()
{
return _partyroom > 0;
}
/**
* Checks if is item equipped by item id.
*
* @param item_id the item_id
* @return true, if is item equipped by item id
*/
public boolean isItemEquippedByItemId(int item_id)
{
if(_inventory == null)
return false;
if(_inventory.getAllItemsByItemId(item_id) == null
|| _inventory.getAllItemsByItemId(item_id).length == 0)
return false;
return _inventory.checkIfEquipped(item_id);
}
/**
* Gets the _instance login time.
*
* @return the _instanceLoginTime
*/
public long get_instanceLoginTime()
{
return _instanceLoginTime;
}
/**
* Sets the sex db.
*
* @param player the player
* @param mode the mode
*/
public static void setSexDB(L2PcInstance player, int mode)
{
Connection con;
if(player == null)
return;
con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("UPDATE characters SET sex=? WHERE obj_Id=?");
statement.setInt(1, player.getAppearance().getSex() ? 1 : 0);
statement.setInt(2, player.getObjectId());
statement.execute();
statement.close();
}
catch(Exception e)
{
if(Config.ENABLE_ALL_EXCEPTIONS)
e.printStackTrace();
_log.warning("SetSex: Could not store data:" + e);
}
finally
{
CloseUtil.close(con);
}
}
public boolean checkTeleportOverTime(){
if(!isTeleporting())
return false;
if(System.currentTimeMillis() - _lastTeleportAction > Config.CHECK_TELEPORT_ZOMBIE_DELAY_TIME){
_log.warning("Player "+getName()+" has been in teleport more then "+Config.CHECK_TELEPORT_ZOMBIE_DELAY_TIME/1000+" seconds.. --> Kicking it");
return true;
}
return false;
}
@Override
public void setIsTeleporting(boolean value)
{
super.setIsTeleporting(value);
if(value){
_lastTeleportAction = System.currentTimeMillis();
}
}
@Override
public L2PcInstance getActingPlayer()
{
return this;
}
public void sendBlockList()
{
sendMessage("======<Ignore List>======");
int i=1;
Iterator<String> blockListIt = getBlockList().getBlockList().iterator();
while(blockListIt.hasNext())
{
String playerId = blockListIt.next();
sendMessage((new StringBuilder()).append(i++).append(". ").append(playerId).toString());
}
sendMessage("========================");
}
public long getLastAttackPacket()
{
return _lastAttackPacket;
}
public void setLastAttackPacket()
{
_lastAttackPacket = System.currentTimeMillis();
}
public void checkItemRestriction()
{
for (int i = 0; i < Inventory.PAPERDOLL_TOTALSLOTS; i++)
{
L2ItemInstance equippedItem = getInventory().getPaperdollItem(i);
if (equippedItem != null && !equippedItem.checkOlympCondition())
{
if (equippedItem.isAugmented())
equippedItem.getAugmentation().removeBoni(this);
L2ItemInstance[] items = getInventory().unEquipItemInSlotAndRecord(i);
if (equippedItem.isWear())
continue;
SystemMessage sm = null;
if (equippedItem.getEnchantLevel() > 0)
{
sm = new SystemMessage(SystemMessageId.EQUIPMENT_S1_S2_REMOVED);
sm.addNumber(equippedItem.getEnchantLevel());
sm.addItemName(equippedItem.getItemId());
}
else
{
sm = new SystemMessage(SystemMessageId.S1_DISARMED);
sm.addItemName(equippedItem.getItemId());
}
sendPacket(sm);
InventoryUpdate iu = new InventoryUpdate();
iu.addItems(Arrays.asList(items));
sendPacket(iu);
broadcastUserInfo();
}
}
}
public void enterOlympiadObserverMode(int x, int y, int z, int id, boolean storeCoords)
{
if (getPet() != null)
getPet().unSummon(this);
unsummonAllCubics();
_olympiadGameId = id;
if (isSitting())
standUp();
if (storeCoords)
{
_obsX = getX();
_obsY = getY();
_obsZ = getZ();
}
setTarget(null);
setIsInvul(true);
getAppearance().setInvisible();
//sendPacket(new GMHide(1));
teleToLocation(x, y, z, true);
sendPacket(new ExOlympiadMode(3));
_observerMode = true;
broadcastUserInfo();
}
public void leaveOlympiadObserverMode(boolean olymp)
{
setTarget(null);
sendPacket(new ExOlympiadMode(0));
teleToLocation(_obsX, _obsY, _obsZ, true);
if (!AdminCommandAccessRights.getInstance().hasAccess("admin_invis", getAccessLevel()))
getAppearance().setVisible();
if (!AdminCommandAccessRights.getInstance().hasAccess("admin_invul", getAccessLevel()))
setIsInvul(false);
if (getAI() != null)
{
getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
}
if (!olymp)
Olympiad.removeSpectator(_olympiadGameId, this);
_olympiadGameId = -1;
_observerMode = false;
broadcastUserInfo();
}
public void setHero(boolean hero)
{
_hero = hero;
if (_hero && _baseClass == _activeClass)
{
giveHeroSkills();
}
else if(getCount() >= Config.HERO_COUNT && _hero && Config.ALLOW_HERO_SUBSKILL){
giveHeroSkills();
}
else
{
removeHeroSkills();
}
}
public void giveHeroSkills()
{
for (L2Skill s : HeroSkillTable.getHeroSkills())
{
addSkill(s, false); //Dont Save Hero skills to database
}
sendSkillList();
}
public void removeHeroSkills()
{
for (L2Skill s : HeroSkillTable.getHeroSkills())
{
super.removeSkill(s); //Just Remove skills from nonHero characters
}
sendSkillList();
}
/**
* Get the current pet skill in use or return null.<br><br>
* @return
*
*/
public SkillDat getCurrentPetSkill()
{
return _currentPetSkill;
}
/**
* Create a new SkillDat object and set the player _currentPetSkill.<br><br>
* @param currentSkill
* @param ctrlPressed
* @param shiftPressed
*
*/
public void setCurrentPetSkill(L2Skill currentSkill, boolean ctrlPressed, boolean shiftPressed)
{
if (currentSkill == null)
{
if (Config.DEBUG)
_log.info("Setting current pet skill: NULL for " + getName() + ".");
_currentPetSkill = null;
return;
}
if (Config.DEBUG)
_log.info("Setting current Pet skill: " + currentSkill.getName() + " (ID: " + currentSkill.getId() + ") for " + getName() + ".");
_currentPetSkill = new SkillDat(currentSkill, ctrlPressed, shiftPressed);
}
public void setKamalokaStatus(boolean value)
{
_kamaStatus = value;
}
public void setKamalokaStatusEnd(long end)
{
_kamaStatus_endTime = end;
}
public long getKamalokaStatusEnd()
{
return _kamaStatus_endTime;
}
public boolean isKamalokaStatus()
{
return _kamaStatus;
}
public void setKamaloka2Status(boolean value)
{
_kama2Status = value;
}
public void setKamaloka2StatusEnd(long end)
{
_kama2Status_endTime = end;
}
public long getKamaloka2StatusEnd()
{
return _kama2Status_endTime;
}
public boolean isKamaloka2Status()
{
return _kama2Status;
}
public void setKamaloka3Status(boolean value)
{
_kama3Status = value;
}
public void setKamaloka3StatusEnd(long end)
{
_kama3Status_endTime = end;
}
public long getKamaloka3StatusEnd()
{
return _kama3Status_endTime;
}
public boolean isKamaloka3Status()
{
return _kama3Status;
}
private void pvpSkillsSystem()
{
L2PcInstance activeChar = L2PcInstance.this.getClient().getActiveChar();
if (activeChar.getPvpKills() == 500)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(323, 1), true); // Adena to True Gold
activeChar.sendMessage("You have received Adena to True Gold skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 1000)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(3156, 1), true); // Firework (Recovers 500 CP)
activeChar.sendMessage("You have received Firework skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 1500)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(3157, 1), true); // Large Firework
activeChar.sendMessage("You have received Large Firework skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 3000)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(7045, 1), true); // Blessed Body
activeChar.sendMessage("You have received Blessed Body skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 3500)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(60, 1), true); // Fake Death
activeChar.sendMessage("You have received Fake Death skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 4000)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(7041, 1), true); // Focus
activeChar.sendMessage("You have received Focus skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 5000)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(7049, 1), true); // Decrease Weight
activeChar.sendMessage("You have received Decrease Weight skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 7000)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(7042, 1), true); // Death Whisper
activeChar.sendMessage("You have received Death Whisper skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 9500)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(7050, 1), true); // Might
activeChar.sendMessage("You have received Might skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 11000)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(3089, 1), true); // Medusa
activeChar.sendMessage("You have received Medusa skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 13000)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(4, 1), true); // Dash
activeChar.sendMessage("You have received Dash skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 14000)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(3160, 1), true); // Resurrection
activeChar.sendMessage("You have received Resurrection skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 15000)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(7055, 1), true); // Wind Walk
activeChar.sendMessage("You have received Wind Walk skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 18000)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(1050, 2), true); // Pvp Return
activeChar.sendMessage("You have received Pvp Return skill for " + activeChar.getPvpKills() + " PvP's.");
}
else if (activeChar.getPvpKills() == 20000)
{
activeChar.addSkill(SkillTable.getInstance().getInfo(7064, 1), true); // Pvp Chant of Victory
activeChar.sendMessage("You have received Pvp Chant of Victory skill for " + activeChar.getPvpKills() + " PvP's.");
}
}
}