Advertisement
Guest User

Untitled

a guest
Mar 5th, 2015
303
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 90.52 KB | None | 0 0
  1. /*
  2.  * This program is free software; you can redistribute it and/or modify
  3.  * it under the terms of the GNU General Public License as published by
  4.  * the Free Software Foundation; either version 2, or (at your option)
  5.  * any later version.
  6.  *
  7.  * This program is distributed in the hope that it will be useful,
  8.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  * GNU General Public License for more details.
  11.  *
  12.  * You should have received a copy of the GNU General Public License
  13.  * along with this program; if not, write to the Free Software
  14.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  15.  * 02111-1307, USA.
  16.  *
  17.  * http://www.gnu.org/copyleft/gpl.html
  18.  */
  19. package net.sf.l2j.gameserver.model.actor.instance;
  20.  
  21. import static net.sf.l2j.gameserver.ai.CtrlIntention.AI_INTENTION_ACTIVE;
  22.  
  23. import java.text.DateFormat;
  24. import java.util.List;
  25.  
  26. import javolution.text.TextBuilder;
  27. import javolution.util.FastList;
  28.  
  29. import net.sf.l2j.Config;
  30. import net.sf.l2j.gameserver.ClientThread;
  31. import net.sf.l2j.gameserver.Olympiad;
  32. import net.sf.l2j.gameserver.SevenSigns;
  33. import net.sf.l2j.gameserver.SevenSignsFestival;
  34. import net.sf.l2j.gameserver.ThreadPoolManager;
  35. import net.sf.l2j.gameserver.TradeController;
  36. import net.sf.l2j.gameserver.ai.CtrlIntention;
  37. import net.sf.l2j.gameserver.cache.HtmCache;
  38. import net.sf.l2j.gameserver.datatables.ClanTable;
  39. import net.sf.l2j.gameserver.datatables.HelperBuffTable;
  40. import net.sf.l2j.gameserver.datatables.ItemTable;
  41. import net.sf.l2j.gameserver.datatables.SkillTable;
  42. import net.sf.l2j.gameserver.datatables.SpawnTable;
  43. import net.sf.l2j.gameserver.idfactory.IdFactory;
  44. import net.sf.l2j.gameserver.instancemanager.CastleManager;
  45. import net.sf.l2j.gameserver.instancemanager.DimensionalRiftManager;
  46. import net.sf.l2j.gameserver.instancemanager.QuestManager;
  47. import net.sf.l2j.gameserver.instancemanager.TownManager;
  48. import net.sf.l2j.gameserver.instancemanager.games.Lottery;
  49. import net.sf.l2j.gameserver.lib.Rnd;
  50. import net.sf.l2j.gameserver.model.L2Attackable;
  51. import net.sf.l2j.gameserver.model.L2Character;
  52. import net.sf.l2j.gameserver.model.L2Clan;
  53. import net.sf.l2j.gameserver.model.L2DropCategory;
  54. import net.sf.l2j.gameserver.model.L2DropData;
  55. import net.sf.l2j.gameserver.model.L2ItemInstance;
  56. import net.sf.l2j.gameserver.model.L2Multisell;
  57. import net.sf.l2j.gameserver.model.L2Object;
  58. import net.sf.l2j.gameserver.model.L2Skill;
  59. import net.sf.l2j.gameserver.model.L2Skill.SkillType;
  60. import net.sf.l2j.gameserver.model.L2Spawn;
  61. import net.sf.l2j.gameserver.model.L2TradeList;
  62. import net.sf.l2j.gameserver.model.L2World;
  63. import net.sf.l2j.gameserver.model.L2WorldRegion;
  64. import net.sf.l2j.gameserver.model.MobGroupTable;
  65. import net.sf.l2j.gameserver.model.NpcInventory;
  66. import net.sf.l2j.gameserver.model.actor.knownlist.NpcKnownList;
  67. import net.sf.l2j.gameserver.model.actor.stat.NpcStat;
  68. import net.sf.l2j.gameserver.model.actor.status.NpcStatus;
  69. import net.sf.l2j.gameserver.model.entity.Castle;
  70. import net.sf.l2j.gameserver.model.entity.L2Event;
  71. import net.sf.l2j.gameserver.model.quest.Quest;
  72. import net.sf.l2j.gameserver.model.quest.QuestState;
  73. import net.sf.l2j.gameserver.model.zone.type.L2TownZone;
  74. import net.sf.l2j.gameserver.serverpackets.ActionFailed;
  75. import net.sf.l2j.gameserver.serverpackets.BuyList;
  76. import net.sf.l2j.gameserver.serverpackets.InventoryUpdate;
  77. import net.sf.l2j.gameserver.serverpackets.MagicSkillUser;
  78. import net.sf.l2j.gameserver.serverpackets.MyTargetSelected;
  79. import net.sf.l2j.gameserver.serverpackets.NpcHtmlMessage;
  80. import net.sf.l2j.gameserver.serverpackets.NpcInfo;
  81. import net.sf.l2j.gameserver.serverpackets.RadarControl;
  82. import net.sf.l2j.gameserver.serverpackets.ServerObjectInfo;
  83. import net.sf.l2j.gameserver.serverpackets.SocialAction;
  84. import net.sf.l2j.gameserver.serverpackets.StatusUpdate;
  85. import net.sf.l2j.gameserver.serverpackets.SystemMessage;
  86. import net.sf.l2j.gameserver.serverpackets.ValidateLocation;
  87. import net.sf.l2j.gameserver.skills.Stats;
  88. import net.sf.l2j.gameserver.taskmanager.DecayTaskManager;
  89. import net.sf.l2j.gameserver.templates.L2HelperBuff;
  90. import net.sf.l2j.gameserver.templates.L2Item;
  91. import net.sf.l2j.gameserver.templates.L2NpcTemplate;
  92. import net.sf.l2j.gameserver.templates.L2Weapon;
  93.  
  94. /**
  95.  * This class represents a Non-Player-Character in the world. It can be a monster or a friendly character.
  96.  * It also uses a template to fetch some static values. The templates are hardcoded in the client, so we can rely on them.<BR><BR>
  97.  *
  98.  * L2Character :<BR><BR>
  99.  * <li>L2Attackable</li>
  100.  * <li>L2BoxInstance</li>
  101.  * <li>L2FolkInstance</li>
  102.  *
  103.  * @version $Revision: 1.32.2.7.2.24 $ $Date: 2005/04/11 10:06:09 $
  104.  */
  105. public class L2NpcInstance extends L2Character
  106. {
  107.     //private static Logger _log = Logger.getLogger(L2NpcInstance.class.getName());
  108.  
  109.     /** The interaction distance of the L2NpcInstance(is used as offset in MovetoLocation method) */
  110.     public static final int INTERACTION_DISTANCE = 150;
  111.  
  112.     /** The L2Spawn object that manage this L2NpcInstance */
  113.     private L2Spawn _spawn;
  114.  
  115.     private NpcInventory _inventory = null;
  116.  
  117.     /** The flag to specify if this L2NpcInstance is busy */
  118.     private boolean _IsBusy = false;
  119.    
  120.     /** The busy message for this L2NpcInstance */
  121.     private String _BusyMessage = "";
  122.  
  123.     /** True if endDecayTask has already been called */
  124.     volatile boolean _isDecayed = false;
  125.  
  126.     /** True if a Dwarf has used Spoil on this L2NpcInstance */
  127.     private boolean _IsSpoil = false;
  128.  
  129.  
  130.  
  131.     /** The castle index in the array of L2Castle this L2NpcInstance belongs to */
  132.     private int _castleIndex = -2;
  133.  
  134.  
  135.     public boolean isEventMob = false;
  136.  
  137.     private boolean _isInTown = false;
  138.  
  139.     private int _isSpoiledBy = 0;
  140.  
  141.     protected RandomAnimationTask _rAniTask = null;
  142.  
  143.     private double _currentCollisionHeight;
  144.     private double _currentCollisionRadius;
  145.  
  146.     /** Task launching the function onRandomAnimation() */
  147.     protected class RandomAnimationTask implements Runnable
  148.     {
  149.         public void run()
  150.         {
  151.             try
  152.             {
  153.                 if (this != _rAniTask)
  154.                     return;
  155.  
  156.                 if (L2NpcInstance.this instanceof L2Attackable)
  157.                 {
  158.                     if (getAI().getIntention() != AI_INTENTION_ACTIVE)
  159.                         return;
  160.                 }
  161.  
  162.                 else
  163.                 {
  164.                     if (!isInActiveRegion())
  165.                         return;
  166.                 }
  167.  
  168.                 if (!(isDead() || isStunned() || isSleeping() || isParalyzed()))
  169.                     onRandomAnimation();
  170.  
  171.                 startRandomAnimationTimer();
  172.             }
  173.             catch (Throwable t) {}
  174.         }
  175.     }
  176.  
  177.  
  178.     /**
  179.      * Send a packet SocialAction to all L2PcInstance in the _KnownPlayers of the L2NpcInstance and create a new RandomAnimation Task.<BR><BR>
  180.      */
  181.     public void onRandomAnimation()
  182.     {
  183.         // Send a packet SocialAction to all L2PcInstance in the _KnownPlayers of the L2NpcInstance
  184.         SocialAction sa = new SocialAction(getObjectId(), Rnd.get(1, 3));
  185.         broadcastPacket(sa);
  186.     }
  187.  
  188.     /**
  189.      * Create a RandomAnimation Task that will be launched after the calculated delay.<BR><BR>
  190.      */
  191.     public void startRandomAnimationTimer()
  192.     {
  193.         if (!hasRandomAnimation())
  194.             return;
  195.  
  196.         int minWait =  this instanceof L2Attackable ? Config.MIN_MONSTER_ANIMATION : Config.MIN_NPC_ANIMATION;
  197.         int maxWait = this instanceof L2Attackable ? Config.MAX_MONSTER_ANIMATION : Config.MAX_NPC_ANIMATION;
  198.  
  199.         // Calculate the delay before the next animation
  200.         int interval = Rnd.get(minWait, maxWait) * 1000;
  201.  
  202.         // Create a RandomAnimation Task that will be launched after the calculated delay
  203.         _rAniTask = new RandomAnimationTask();
  204.         ThreadPoolManager.getInstance().scheduleGeneral(_rAniTask, interval);
  205.     }
  206.  
  207.     /**
  208.      * Check if the server allows Random Animation.<BR><BR>
  209.      */
  210.     public boolean hasRandomAnimation()
  211.     {
  212.         return (Config.MAX_NPC_ANIMATION > 0);
  213.     }
  214.  
  215.     /**
  216.      * Constructor of L2NpcInstance (use L2Character constructor).<BR><BR>
  217.      *  
  218.      * <B><U> Actions</U> :</B><BR><BR>
  219.      * <li>Call the L2Character constructor to set the _template of the L2Character (copy skills from template to object and link _calculators to NPC_STD_CALCULATOR)  </li>
  220.      * <li>Set the name of the L2Character</li>
  221.      * <li>Create a RandomAnimation Task that will be launched after the calculated delay if the server allow it </li><BR><BR>
  222.      *
  223.      * @param objectId Identifier of the object to initialized
  224.      * @param template The L2NpcTemplate to apply to the NPC
  225.      *
  226.      */
  227.     public L2NpcInstance(int objectId, L2NpcTemplate template)
  228.     {
  229.         // Call the L2Character constructor to set the _template of the L2Character, copy skills from template to object
  230.         // and link _calculators to NPC_STD_CALCULATOR
  231.         super(objectId, template);
  232.  
  233.         if (template == null)
  234.         {
  235.             _log.severe("No template for Npc. Please check your datapack is setup correctly.");
  236.             return;
  237.         }
  238.  
  239.         getKnownList();
  240.         getStat();
  241.         getStatus();
  242.  
  243.         super.initCharStatusUpdateValues(); // init status update values
  244.  
  245.         _currentCollisionHeight = getTemplate().collisionHeight;
  246.         _currentCollisionRadius = getTemplate().collisionRadius;
  247.  
  248.         // Set the name of the L2Character
  249.         setName(template.name);
  250.  
  251.         if ((template.ss > 0 || template.bss > 0) && template.ssRate > 0)
  252.             _inventory = new NpcInventory(this);
  253.     }
  254.  
  255.     public NpcKnownList getKnownList()
  256.     {
  257.         if (super.getKnownList() == null || !(super.getKnownList() instanceof NpcKnownList))
  258.             setKnownList(new NpcKnownList(this));
  259.         return (NpcKnownList)super.getKnownList();
  260.     }
  261.  
  262.     public NpcStat getStat()
  263.     {
  264.         if (super.getStat() == null || !(super.getStat() instanceof NpcStat))
  265.             setStat(new NpcStat(this));
  266.         return (NpcStat)super.getStat();
  267.     }
  268.  
  269.     public NpcStatus getStatus()
  270.     {
  271.         if (super.getStatus() == null || !(super.getStatus() instanceof NpcStatus))
  272.             setStatus(new NpcStatus(this));
  273.         return (NpcStatus)super.getStatus();
  274.     }
  275.  
  276.  
  277.     /** Return the L2NpcTemplate of the L2NpcInstance. */
  278.     public final L2NpcTemplate getTemplate()
  279.     {
  280.         return (L2NpcTemplate)super.getTemplate();
  281.     }
  282.    
  283.     /**
  284.      * Return the generic Identifier of this L2NpcInstance contained in the L2NpcTemplate.<BR><BR>
  285.      */
  286.     public int getNpcId()
  287.     {
  288.         return getTemplate().npcId;
  289.     }
  290.    
  291.     public boolean isAttackable()
  292.     {
  293.         return true;
  294.     }
  295.    
  296.     /**
  297.      * Return the faction Identifier of this L2NpcInstance contained in the L2NpcTemplate.<BR><BR>
  298.      *
  299.      * <B><U> Concept</U> :</B><BR><BR>
  300.      * If a NPC belows to a Faction, other NPC of the faction inside the Faction range will help it if it's attacked<BR><BR>
  301.      *
  302.      */
  303.     public final String getFactionId()
  304.     {
  305.         return getTemplate().factionId;
  306.     }
  307.    
  308.     /**
  309.      * Return the Level of this L2NpcInstance contained in the L2NpcTemplate.<BR><BR>
  310.      */
  311.     public final int getLevel()
  312.     {
  313.         return getTemplate().level;
  314.     }
  315.  
  316.     /**
  317.      * Return True if the L2NpcInstance is agressive (ex : L2MonsterInstance in function of aggroRange).<BR><BR>
  318.      */
  319.     public boolean isAggressive()
  320.     {
  321.         return false;
  322.     }
  323.    
  324.     /**
  325.      * Return the Aggro Range of this L2NpcInstance contained in the L2NpcTemplate.<BR><BR>
  326.      */
  327.     public int getAggroRange()
  328.     {
  329.         return getTemplate().aggroRange;
  330.     }
  331.    
  332.     /**
  333.      * Return the Faction Range of this L2NpcInstance contained in the L2NpcTemplate.<BR><BR>
  334.      */
  335.     public int getFactionRange()
  336.     {
  337.         return getTemplate().factionRange;
  338.     }
  339.    
  340.     /**
  341.      * Return True if this L2NpcInstance is undead in function of the L2NpcTemplate.<BR><BR>
  342.      */
  343.     public boolean isUndead()
  344.     {
  345.         return getTemplate().isUndead;
  346.     }
  347.  
  348.     /**
  349.      * Return True if this L2NpcInstance is quest monster in function of the L2NpcTemplate.<BR><BR>
  350.      */
  351.     public boolean isQuestMonster()
  352.     {
  353.         return getTemplate().isQuestMonster;
  354.     }
  355.  
  356.     /**
  357.      * Send a packet NpcInfo with state of abnormal effect to all L2PcInstance in the _KnownPlayers of the L2NpcInstance.<BR><BR>
  358.      */
  359.     public void updateAbnormalEffect()
  360.     {
  361.  
  362.         // Send a Server->Client packet NpcInfo with state of abnormal effect to all L2PcInstance in the _KnownPlayers of the L2NpcInstance
  363.         for (L2PcInstance player : getKnownList().getKnownPlayers().values())
  364.         {
  365.             if (player != null)
  366.             {
  367.                 if (getRunSpeed() == 0)
  368.                     player.sendPacket(new ServerObjectInfo(this, player));
  369.                 else
  370.                     player.sendPacket(new NpcInfo(this, player));
  371.             }
  372.         }
  373.     }
  374.    
  375.     /**
  376.      * Return the distance under which the object must be add to _knownObject in function of the object type.<BR><BR>
  377.      *  
  378.      * <B><U> Values </U> :</B><BR><BR>
  379.      * <li> object is a L2FolkInstance : 0 (don't remember it) </li>
  380.      * <li> object is a L2Character : 0 (don't remember it) </li>
  381.      * <li> object is a L2PlayableInstance : 1500 </li>
  382.      * <li> others : 500 </li><BR><BR>
  383.      *
  384.      * <B><U> Overriden in </U> :</B><BR><BR>
  385.      * <li> L2Attackable</li><BR><BR>
  386.      *
  387.      * @param object The Object to add to _knownObject
  388.      *
  389.      */
  390.     public int getDistanceToWatchObject(L2Object object)
  391.     {
  392.         if (object instanceof L2FestivalGuideInstance)
  393.             return 10000;
  394.        
  395.         if (object instanceof L2FolkInstance || !(object instanceof L2Character))
  396.             return 0;
  397.        
  398.         if (object instanceof L2PlayableInstance)
  399.             return 1500;
  400.        
  401.         return 500;
  402.     }
  403.    
  404.     /**
  405.      * Return the distance after which the object must be remove from _knownObject in function of the object type.<BR><BR>
  406.      *  
  407.      * <B><U> Values </U> :</B><BR><BR>
  408.      * <li> object is not a L2Character : 0 (don't remember it) </li>
  409.      * <li> object is a L2FolkInstance : 0 (don't remember it)</li>
  410.      * <li> object is a L2PlayableInstance : 3000 </li>
  411.      * <li> others : 1000 </li><BR><BR>
  412.      *
  413.      * <B><U> Overriden in </U> :</B><BR><BR>
  414.      * <li> L2Attackable</li><BR><BR>
  415.      *
  416.      * @param object The Object to remove from _knownObject
  417.      *
  418.      */
  419.     public int getDistanceToForgetObject(L2Object object)
  420.     {
  421.         return 2*getDistanceToWatchObject(object);
  422.     }
  423.    
  424.     /**
  425.      * Return False.<BR><BR>
  426.      *  
  427.      * <B><U> Overriden in </U> :</B><BR><BR>
  428.      * <li> L2MonsterInstance : Check if the attacker is not another L2MonsterInstance</li>
  429.      * <li> L2PcInstance</li><BR><BR>
  430.      */
  431.     public boolean isAutoAttackable(@SuppressWarnings("unused") L2Character attacker)
  432.     {
  433.         return false;
  434.     }
  435.    
  436.     /**
  437.      * Return the Identifier of the item in the left hand of this L2NpcInstance contained in the L2NpcTemplate.<BR><BR>
  438.      */
  439.     public int getLeftHandItem()
  440.     {
  441.         return getTemplate().lhand;
  442.     }
  443.    
  444.     /**
  445.      * Return the Identifier of the item in the right hand of this L2NpcInstance contained in the L2NpcTemplate.<BR><BR>
  446.      */
  447.     public int getRightHandItem()
  448.     {
  449.         return getTemplate().rhand;
  450.     }
  451.    
  452.     /**
  453.      * Return True if this L2NpcInstance has drops that can be sweeped.<BR><BR>
  454.      */
  455.     public boolean isSpoil()
  456.     {
  457.         return _IsSpoil;
  458.     }
  459.    
  460.     /**
  461.      * Set the spoil state of this L2NpcInstance.<BR><BR>
  462.      */
  463.     public void setSpoil(boolean isSpoil)
  464.     {
  465.         _IsSpoil = isSpoil;
  466.     }
  467.  
  468.     public final int getIsSpoiledBy()
  469.     {
  470.         return _isSpoiledBy;
  471.     }
  472.    
  473.     public final void setIsSpoiledBy(int value)
  474.     {
  475.         _isSpoiledBy = value;
  476.     }
  477.    
  478.     /**
  479.      * Return the busy status of this L2NpcInstance.<BR><BR>
  480.      */
  481.     public final boolean isBusy()
  482.     {
  483.         return _IsBusy;
  484.     }
  485.    
  486.     /**
  487.      * Set the busy status of this L2NpcInstance.<BR><BR>
  488.      */
  489.     public void setBusy(boolean isBusy)
  490.     {
  491.         _IsBusy = isBusy;
  492.     }
  493.    
  494.     /**
  495.      * Return the busy message of this L2NpcInstance.<BR><BR>
  496.      */
  497.     public final String getBusyMessage()
  498.     {
  499.         return _BusyMessage;
  500.     }
  501.    
  502.     /**
  503.      * Set the busy message of this L2NpcInstance.<BR><BR>
  504.      */
  505.     public void setBusyMessage(String message)
  506.     {
  507.         _BusyMessage = message;
  508.     }
  509.  
  510.     protected boolean canTarget(L2PcInstance player)
  511.     {
  512.         if (player.isOutOfControl())
  513.         {
  514.             player.sendPacket(new ActionFailed());
  515.             return false;
  516.         }
  517.  
  518.         if (player.getEventTeam() > 0)
  519.             return false;
  520.  
  521.         // TODO: More checks...
  522.  
  523.         return true;
  524.     }
  525.  
  526.     public boolean canInteract(L2PcInstance player)
  527.     {
  528.         // TODO: NPC busy check etc...
  529.  
  530.         if (player.isCastingNow() || player.isSitting())
  531.             return false;
  532.  
  533.         if (player.isDead() || player.isFakeDeath())
  534.             return false;
  535.  
  536.         if (player.getPrivateStoreType() != 0)
  537.             return false;
  538.  
  539.  
  540.         if (!isInsideRadius(player, INTERACTION_DISTANCE, false, false))
  541.             return false;
  542.  
  543.         if (player.getEventTeam() > 0)
  544.             return false;
  545.  
  546.         return true;
  547.     }
  548.  
  549.     /**
  550.      * Manage actions when a player click on the L2NpcInstance.<BR><BR>
  551.      *
  552.      * <B><U> Actions on first click on the L2NpcInstance (Select it)</U> :</B><BR><BR>
  553.      * <li>Set the L2NpcInstance as target of the L2PcInstance player (if necessary)</li>
  554.      * <li>Send a Server->Client packet MyTargetSelected to the L2PcInstance player (display the select window)</li>
  555.      * <li>If L2NpcInstance is autoAttackable, send a Server->Client packet StatusUpdate to the L2PcInstance in order to update L2NpcInstance HP bar </li>
  556.      * <li>Send a Server->Client packet ValidateLocation to correct the L2NpcInstance position and heading on the client </li><BR><BR>
  557.      *
  558.      * <B><U> Actions on second click on the L2NpcInstance (Attack it/Intercat with it)</U> :</B><BR><BR>
  559.      * <li>Send a Server->Client packet MyTargetSelected to the L2PcInstance player (display the select window)</li>
  560.      * <li>If L2NpcInstance is autoAttackable, notify the L2PcInstance AI with AI_INTENTION_ATTACK (after a height verification)</li>
  561.      * <li>If L2NpcInstance is NOT autoAttackable, notify the L2PcInstance AI with AI_INTENTION_INTERACT (after a distance verification) and show message</li><BR><BR>
  562.      *
  563.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : Each group of Server->Client packet must be terminated by a ActionFailed packet in order to avoid
  564.      * that client wait an other packet</B></FONT><BR><BR>
  565.      *
  566.      * <B><U> Example of use </U> :</B><BR><BR>
  567.      * <li> Client packet : Action, AttackRequest</li><BR><BR>
  568.      *
  569.      * <B><U> Overriden in </U> :</B><BR><BR>
  570.      * <li> L2ArtefactInstance : Manage only fisrt click to select Artefact</li><BR><BR>
  571.      * <li> L2GuardInstance : </li><BR><BR>
  572.      *
  573.      * @param player The L2PcInstance that start an action on the L2NpcInstance
  574.      *
  575.      */
  576.     public void onAction(L2PcInstance player)
  577.     {
  578.         if (!canTarget(player))
  579.             return;
  580.  
  581.         // Check if the L2PcInstance already target the L2NpcInstance
  582.         if (this != player.getTarget())
  583.         {
  584.             if (Config.DEBUG) _log.fine("new target selected:"+getObjectId());
  585.  
  586.             // Set the target of the L2PcInstance player
  587.             player.setTarget(this);
  588.  
  589.             // Check if the player is attackable (without a forced attack)
  590.             if (isAutoAttackable(player))
  591.             {
  592.                 // Send a Server->Client packet MyTargetSelected to the L2PcInstance player
  593.                 // The player.getLevel() - getLevel() permit to display the correct color in the select window
  594.                 MyTargetSelected my = new MyTargetSelected(getObjectId(), player.getLevel() - getLevel());
  595.                 player.sendPacket(my);
  596.  
  597.                 // Send a Server->Client packet StatusUpdate of the L2NpcInstance to the L2PcInstance to update its HP bar
  598.                 StatusUpdate su = new StatusUpdate(getObjectId());
  599.                 su.addAttribute(StatusUpdate.CUR_HP, (int)getCurrentHp());
  600.                 su.addAttribute(StatusUpdate.MAX_HP, getMaxHp());
  601.                 player.sendPacket(su);
  602.             }
  603.             else
  604.             {
  605.                 // Send a Server->Client packet MyTargetSelected to the L2PcInstance player
  606.                 MyTargetSelected my = new MyTargetSelected(getObjectId(), 0);
  607.                 player.sendPacket(my);
  608.             }
  609.  
  610.             // Send a Server->Client packet ValidateLocation to correct the L2NpcInstance position and heading on the client
  611.             player.sendPacket(new ValidateLocation(this));
  612.         }
  613.         else
  614.         {
  615.             player.sendPacket(new ValidateLocation(this));
  616.             // Check if the player is attackable (without a forced attack) and isn't dead
  617.             if (isAutoAttackable(player) && !isAlikeDead())
  618.             {
  619.                 // Check the height difference
  620.                 if (Math.abs(player.getZ() - getZ()) < 400) // this max heigth difference might need some tweaking
  621.                 {
  622.                     // Set the L2PcInstance Intention to AI_INTENTION_ATTACK
  623.                     player.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, this);
  624.  
  625.                 }
  626.                 else
  627.                 {
  628.                     // Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
  629.                     player.sendPacket(new ActionFailed());
  630.                 }
  631.             }
  632.             else if (!isAutoAttackable(player))
  633.             {
  634.                 // Calculate the distance between the L2PcInstance and the L2NpcInstance
  635.                 if (!canInteract(player))
  636.                 {
  637.                     // Notify the L2PcInstance AI with AI_INTENTION_INTERACT
  638.                     player.getAI().setIntention(CtrlIntention.AI_INTENTION_INTERACT, this);
  639.                 }
  640.                 else
  641.                 {
  642.                     // Send a Server->Client packet SocialAction to the all L2PcInstance on the _knownPlayer of the L2NpcInstance
  643.                     // to display a social action of the L2NpcInstance on their client
  644.                     SocialAction sa = new SocialAction(getObjectId(), Rnd.get(8));
  645.                     broadcastPacket(sa);
  646.  
  647.                     // Open a chat window on client with the text of the L2NpcInstance
  648.                     if (isEventMob)
  649.  
  650.                         L2Event.showEventHtml(player, String.valueOf(getObjectId()));
  651.  
  652.                     else
  653.                     {
  654.                         Quest[] qlsa = getTemplate().getEventQuests(Quest.QuestEventType.QUEST_START);
  655.                         if ((qlsa != null) && qlsa.length > 0)
  656.                             player.setLastQuestNpcObject(getObjectId());
  657.  
  658.                         Quest[] qlst = getTemplate().getEventQuests(Quest.QuestEventType.NPC_FIRST_TALK);
  659.                         if ((qlst != null) && qlst.length == 1)
  660.                             qlst[0].notifyFirstTalk(this, player);
  661.                         else
  662.  
  663.                             showChatWindow(player, 0);
  664.                     }
  665.  
  666.                 }
  667.             }
  668.             else
  669.                 player.sendPacket(new ActionFailed());
  670.         }
  671.     }
  672.    
  673.     /**
  674.      * Manage and Display the GM console to modify the L2NpcInstance (GM only).<BR><BR>
  675.      *
  676.      * <B><U> Actions (If the L2PcInstance is a GM only)</U> :</B><BR><BR>
  677.      * <li>Set the L2NpcInstance as target of the L2PcInstance player (if necessary)</li>
  678.      * <li>Send a Server->Client packet MyTargetSelected to the L2PcInstance player (display the select window)</li>
  679.      * <li>If L2NpcInstance is autoAttackable, send a Server->Client packet StatusUpdate to the L2PcInstance in order to update L2NpcInstance HP bar </li>
  680.      * <li>Send a Server->Client NpcHtmlMessage() containing the GM console about this L2NpcInstance </li><BR><BR>
  681.      *
  682.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : Each group of Server->Client packet must be terminated by a ActionFailed packet in order to avoid
  683.      * that client wait an other packet</B></FONT><BR><BR>
  684.      *
  685.      * <B><U> Example of use </U> :</B><BR><BR>
  686.      * <li> Client packet : Action</li><BR><BR>
  687.      *
  688.      * @param client The thread that manage the player that pessed Shift and click on the L2NpcInstance
  689.      *
  690.      */
  691.     public void onActionShift(ClientThread client)
  692.     {
  693.         // Get the L2PcInstance corresponding to the thread
  694.         L2PcInstance player = client.getActiveChar();
  695.  
  696.         if (player == null)
  697.             return;
  698.  
  699.         if (!canTarget(player))
  700.             return;
  701.  
  702.         // Check if the L2PcInstance already target the L2NpcInstance
  703.         if (this != player.getTarget())
  704.         {
  705.             // Set the target of the L2PcInstance player
  706.             player.setTarget(this);
  707.  
  708.             // Check if the player is attackable (without a forced attack)
  709.             if (isAutoAttackable(player))
  710.             {
  711.                 // Send a Server->Client packet MyTargetSelected to the L2PcInstance player
  712.                 // The player.getLevel() - getLevel() permit to display the correct color in the select window
  713.                 MyTargetSelected my = new MyTargetSelected(getObjectId(), player.getLevel() - getLevel());
  714.                 player.sendPacket(my);
  715.  
  716.                 // Send a Server->Client packet StatusUpdate of the L2NpcInstance to the L2PcInstance to update its HP bar
  717.                 StatusUpdate su = new StatusUpdate(getObjectId());
  718.                 su.addAttribute(StatusUpdate.CUR_HP, (int)getCurrentHp());
  719.                 su.addAttribute(StatusUpdate.MAX_HP, getMaxHp());
  720.                 player.sendPacket(su);
  721.             }
  722.             else
  723.             {
  724.                 // Send a Server->Client packet MyTargetSelected to the L2PcInstance player
  725.                 MyTargetSelected my = new MyTargetSelected(getObjectId(), 0);
  726.                 player.sendPacket(my);
  727.             }
  728.         }
  729.  
  730.         // Send a Server->Client packet ValidateLocation to correct the L2NpcInstance position and heading on the client
  731.         player.sendPacket(new ValidateLocation(this));
  732.  
  733.         // Check if the L2PcInstance is a GM
  734.         if (player.getAccessLevel() >= Config.GM_ACCESSLEVEL)
  735.         {
  736.             // Send a Server->Client NpcHtmlMessage() containing the GM console about this L2NpcInstance
  737.             NpcHtmlMessage html = new NpcHtmlMessage(0);
  738.             TextBuilder html1 = new TextBuilder("<html><body><center><font color=\"LEVEL\">NPC Information</font></center>");
  739.             String className = getClass().getName().substring(43);
  740.  
  741.             html1.append("<br>");
  742.  
  743.             html1.append("Instance Type: " + className + "<br1>Faction: " + getFactionId() + "<br1>Location ID: " + (getSpawn() != null ? getSpawn().getLocation() : 0) + "<br1>");
  744.            
  745.             if (this instanceof L2ControllableMobInstance)
  746.                 html1.append("Mob Group: " + MobGroupTable.getInstance().getGroupForMob((L2ControllableMobInstance)this).getGroupId() + "<br>");
  747.             else
  748.                 html1.append("Respawn Time: " + (getSpawn()!=null ? (getSpawn().getRespawnDelay() / 1000)+"  Seconds<br>" : "?  Seconds<br>"));
  749.            
  750.             html1.append("<table border=\"0\" width=\"100%\">");
  751.             html1.append("<tr><td>Object ID</td><td>"+getObjectId()+"</td><td>NPC ID</td><td>"+getTemplate().npcId+"</td></tr>");
  752.  
  753.             html1.append("<tr><td>Castle</td><td>"+(getCastle() != null ? getCastle().getCastleId() : 0)+"</td><td>Coords</td><td>"+getX()+","+getY()+","+getZ()+"</td></tr>");
  754.  
  755.             html1.append("<tr><td>Level</td><td>"+getLevel()+"</td><td>Aggro</td><td>"+((this instanceof L2Attackable)? ((L2Attackable)this).getAggroRange() : 0)+"</td></tr>");
  756.             html1.append("</table><br>");
  757.            
  758.             html1.append("<font color=\"LEVEL\">Combat</font>");
  759.             html1.append("<table border=\"0\" width=\"100%\">");
  760.             html1.append("<tr><td>Current HP</td><td>"+getCurrentHp()+"</td><td>Current MP</td><td>"+getCurrentMp()+"</td></tr>");
  761.             html1.append("<tr><td>Max.HP</td><td>"+(int)(getMaxHp()/getStat().calcStat(Stats.MAX_HP , 1, this, null))+"*"+getStat().calcStat(Stats.MAX_HP , 1, this, null)+"</td><td>Max.MP</td><td>"+getMaxMp()+"</td></tr>");
  762.             html1.append("<tr><td>P.Atk.</td><td>"+getPAtk(null)+"</td><td>M.Atk.</td><td>"+getMAtk(null,null)+"</td></tr>");
  763.             html1.append("<tr><td>P.Def.</td><td>"+getPDef(null)+"</td><td>M.Def.</td><td>"+getMDef(null,null)+"</td></tr>");
  764.             html1.append("<tr><td>Accuracy</td><td>"+getAccuracy()+"</td><td>Evasion</td><td>"+getEvasionRate(null)+"</td></tr>");
  765.             html1.append("<tr><td>Critical</td><td>"+getCriticalHit(null,null)+"</td><td>Speed</td><td>"+getRunSpeed()+"</td></tr>");
  766.             html1.append("<tr><td>Atk.Speed</td><td>"+getPAtkSpd()+"</td><td>Cast.Speed</td><td>"+getMAtkSpd()+"</td></tr>");
  767.             html1.append("</table><br>");
  768.            
  769.             html1.append("<font color=\"LEVEL\">Basic Stats</font>");
  770.             html1.append("<table border=\"0\" width=\"100%\">");
  771.             html1.append("<tr><td>STR</td><td>"+getSTR()+"</td><td>DEX</td><td>"+getDEX()+"</td><td>CON</td><td>"+getCON()+"</td></tr>");
  772.             html1.append("<tr><td>INT</td><td>"+getINT()+"</td><td>WIT</td><td>"+getWIT()+"</td><td>MEN</td><td>"+getMEN()+"</td></tr>");
  773.             html1.append("</table>");
  774.            
  775.             html1.append("<br><center><table><tr><td><button value=\"Edit NPC\" action=\"bypass -h admin_edit_npc " + getTemplate().npcId + "\" width=100 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"><br1></td>");
  776.             html1.append("<td><button value=\"Kill\" action=\"bypass -h admin_kill\" width=40 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"></td><br1></tr>");
  777.             html1.append("<tr><td><button value=\"Show DropList\" action=\"bypass -h admin_show_droplist " + getTemplate().npcId + "\" width=100 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"></td></tr>");           
  778.             html1.append("<td><button value=\"Delete\" action=\"bypass -h admin_delete\" width=40 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"></td></tr>");
  779.             html1.append("</table></center><br>");
  780.             html1.append("</body></html>");
  781.            
  782.             html.setHtml(html1.toString());
  783.             player.sendPacket(html);
  784.         }
  785.         else if (Config.ALT_GAME_VIEWNPC)
  786.         {
  787.             NpcHtmlMessage html = new NpcHtmlMessage(0);
  788.             TextBuilder html1 = new TextBuilder("<html><body>");
  789.            
  790.             html1.append("<br><center><font color=\"LEVEL\">[Combat Stats]</font></center>");
  791.             html1.append("<table border=0 width=\"100%\">");
  792.             html1.append("<tr><td>Max.HP</td><td>"+(int)(getMaxHp()/getStat().calcStat(Stats.MAX_HP , 1, this, null))+"*"+(int) getStat().calcStat(Stats.MAX_HP , 1, this, null)+"</td><td>Max.MP</td><td>"+getMaxMp()+"</td></tr>");
  793.             html1.append("<tr><td>P.Atk.</td><td>"+getPAtk(null)+"</td><td>M.Atk.</td><td>"+getMAtk(null,null)+"</td></tr>");
  794.             html1.append("<tr><td>P.Def.</td><td>"+getPDef(null)+"</td><td>M.Def.</td><td>"+getMDef(null,null)+"</td></tr>");
  795.             html1.append("<tr><td>Accuracy</td><td>"+getAccuracy()+"</td><td>Evasion</td><td>"+getEvasionRate(null)+"</td></tr>");
  796.             html1.append("<tr><td>Critical</td><td>"+getCriticalHit(null,null)+"</td><td>Speed</td><td>"+getRunSpeed()+"</td></tr>");
  797.             html1.append("<tr><td>Atk.Speed</td><td>"+getPAtkSpd()+"</td><td>Cast.Speed</td><td>"+getMAtkSpd()+"</td></tr>");
  798.             html1.append("<tr><td>Race</td><td>"+getTemplate().race+"</td><td></td><td></td></tr>");
  799.             html1.append("</table>");
  800.  
  801.             html1.append("<br><center><font color=\"LEVEL\">[Basic Stats]</font></center>");
  802.             html1.append("<table border=0 width=\"100%\">");
  803.             html1.append("<tr><td>STR</td><td>"+getSTR()+"</td><td>DEX</td><td>"+getDEX()+"</td><td>CON</td><td>"+getCON()+"</td></tr>");
  804.             html1.append("<tr><td>INT</td><td>"+getINT()+"</td><td>WIT</td><td>"+getWIT()+"</td><td>MEN</td><td>"+getMEN()+"</td></tr>");
  805.             html1.append("</table>");
  806.            
  807.             html1.append("<br><center><font color=\"LEVEL\">[Drop Info]</font></center>");
  808.             html1.append("Rates legend: <font color=\"ff0000\">50%+</font> <font color=\"00ff00\">30%+</font> <font color=\"0000ff\">less than 30%</font>");
  809.             html1.append("<table border=0 width=\"100%\">");
  810.  
  811.  
  812.             if (getTemplate().getDropData() != null)
  813.             {
  814.                 for (L2DropCategory cat : getTemplate().getDropData())
  815.                 {
  816.                     for (L2DropData drop : cat.getAllDrops())
  817.                     {
  818.                         String name = ItemTable.getInstance().getTemplate(drop.getItemId()).getName();
  819.  
  820.                         if (drop.getChance() >= 600000)
  821.                             html1.append("<tr><td><font color=\"ff0000\">" + name + "</font></td><td>" + (drop.isQuestDrop()?"Quest":(cat.isSweep()?"Sweep":"Drop")) + "</td></tr>");
  822.                         else if (drop.getChance() >= 300000)
  823.                             html1.append("<tr><td><font color=\"00ff00\">" + name + "</font></td><td>" + (drop.isQuestDrop()?"Quest":(cat.isSweep()?"Sweep":"Drop")) + "</td></tr>");
  824.                         else
  825.                             html1.append("<tr><td><font color=\"0000ff\">" + name + "</font></td><td>" + (drop.isQuestDrop()?"Quest":(cat.isSweep()?"Sweep":"Drop")) + "</td></tr>");
  826.                     }
  827.                 }
  828.             }
  829.            
  830.             html1.append("</table>");
  831.             html1.append("</body></html>");
  832.  
  833.             html.setHtml(html1.toString());
  834.             player.sendPacket(html);
  835.         }
  836.        
  837.         // Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
  838.         player.sendPacket(new ActionFailed());
  839.     }
  840.    
  841.     /** Return the L2Castle this L2NpcInstance belongs to. */
  842.     public final Castle getCastle()
  843.     {
  844.  
  845.         if (_castleIndex < 0)
  846.         {
  847.  
  848.             L2TownZone town = TownManager.getInstance().getTown(getX(), getY(), getZ());
  849.             if (town != null)
  850.                 _castleIndex = CastleManager.getInstance().getCastleIndex(town.getTaxById());
  851.  
  852.  
  853.  
  854.             if (_castleIndex < 0)
  855.                 _castleIndex = CastleManager.getInstance().findNearestCastleIndex(this);
  856.             else
  857.  
  858.                 _isInTown = true; // Npc was spawned in town
  859.  
  860.         }
  861.  
  862.         if (_castleIndex < 0)
  863.             return null;
  864.  
  865.  
  866.         return CastleManager.getInstance().getCastles().get(_castleIndex);
  867.  
  868.     }
  869.  
  870.  
  871.     public boolean getIsInCastleTown()
  872.     {
  873.         if (_castleIndex < 0)
  874.             getCastle();
  875.  
  876.         return _isInTown;
  877.     }
  878.  
  879.     /**
  880.      * Open a quest or chat window on client with the text of the L2NpcInstance in function of the command.<BR><BR>
  881.      *
  882.      * <B><U> Example of use </U> :</B><BR><BR>
  883.      * <li> Client packet : RequestBypassToServer</li><BR><BR>
  884.      *
  885.      * @param command The command string received from client
  886.      *
  887.      */
  888.     public void onBypassFeedback(L2PcInstance player, String command)
  889.     {
  890.  
  891.         if (isBusy() && getBusyMessage().length() > 0)
  892.         {
  893.             player.sendPacket(new ActionFailed());
  894.             NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
  895.             html.setFile("data/html/npcbusy.htm");
  896.             html.replace("%busymessage%", getBusyMessage());
  897.             html.replace("%npcname%", getName());
  898.             html.replace("%playername%", player.getName());
  899.             player.sendPacket(html);
  900.         }
  901.  
  902.         else if (command.equalsIgnoreCase("TerritoryStatus"))
  903.         {
  904.             NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
  905.             html.setFile("data/html/territorystatus.htm");
  906.             html.replace("%objectId%", String.valueOf(getObjectId()));
  907.             html.replace("%npcname%", getName());
  908.  
  909.  
  910.             if (getIsInCastleTown())
  911.             {
  912.                 html.replace("%castlename%", getCastle().getName());
  913.                 html.replace("%taxpercent%", "" + getCastle().getTaxPercent());
  914.  
  915.  
  916.                 if (getCastle().getOwnerId() > 0)
  917.                 {
  918.                     L2Clan clan = ClanTable.getInstance().getClan(getCastle().getOwnerId());
  919.                     html.replace("%clanname%", clan.getName());
  920.                     html.replace("%clanleadername%", clan.getLeaderName());
  921.                 }
  922.                 else
  923.                 {
  924.                     html.replace("%clanname%", "NPC");
  925.                     html.replace("%clanleadername%", "NPC");
  926.                 }
  927.             }
  928.             else
  929.             {
  930.                 html.replace("%castlename%", "Open");
  931.                 html.replace("%taxpercent%", "0");
  932.  
  933.  
  934.                 html.replace("%clanname%", "No");
  935.                 html.replace("%clanleadername%", "None");
  936.             }
  937.  
  938.  
  939.             player.sendPacket(html);
  940.         }
  941.         else if (command.startsWith("Quest"))
  942.         {
  943.             String quest = "";
  944.             try
  945.             {
  946.                 quest = command.substring(5).trim();
  947.             }
  948.             catch (IndexOutOfBoundsException ioobe) {}
  949.  
  950.             if (quest.length() == 0)
  951.                 showQuestWindow(player);
  952.             else
  953.                 showQuestWindow(player, quest);
  954.         }
  955.         else if (command.startsWith("Chat"))
  956.         {
  957.             int val = 0;
  958.             try
  959.             {
  960.                 val = Integer.parseInt(command.substring(5));
  961.             }
  962.             catch (IndexOutOfBoundsException ioobe)
  963. {
  964. }
  965.             catch (NumberFormatException nfe) {}
  966.  
  967.             showChatWindow(player, val);
  968.         }
  969.         else if (command.startsWith("Link"))
  970.         {
  971.             String path = command.substring(5).trim();
  972.             if (path.indexOf("..") != -1)
  973.                 return;
  974.  
  975.             String filename = "data/html/"+path;
  976.             NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
  977.             html.setFile(filename);
  978.             html.replace("%objectId%", String.valueOf(getObjectId()));
  979.             player.sendPacket(html);
  980.         }
  981.         else if (command.startsWith("NobleTeleport"))
  982.         {
  983.             if (!player.isNoble())
  984.             {
  985.                 String filename = "data/html/teleporter/nobleteleporter-no.htm";
  986.                 NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
  987.                 html.setFile(filename);
  988.                 html.replace("%objectId%", String.valueOf(getObjectId()));
  989.                 html.replace("%npcname%", getName());
  990.                 player.sendPacket(html);
  991.                 return;
  992.             }
  993.  
  994.             int val = 0;
  995.             try
  996.             {
  997.                 val = Integer.parseInt(command.substring(14));
  998.             }
  999.             catch (IndexOutOfBoundsException ioobe) {
  1000. }
  1001.             catch (NumberFormatException nfe) {}
  1002.  
  1003.             showChatWindow(player, val);
  1004.         }
  1005.         else if (command.startsWith("Loto"))
  1006.         {
  1007.             int val = 0;
  1008.             try
  1009.             {
  1010.                 val = Integer.parseInt(command.substring(5));
  1011.             }
  1012.             catch (IndexOutOfBoundsException ioobe) {
  1013. }
  1014.             catch (NumberFormatException nfe) {}
  1015.  
  1016.             if (val == 0)
  1017.             {
  1018.                 // new loto ticket
  1019.                 for (int i=0;i<5;i++)
  1020.                     player.setLoto(i,0);
  1021.             }
  1022.             showLotoWindow(player, val);
  1023.         }
  1024.         else if (command.startsWith("CPRecovery"))
  1025.         {
  1026.             makeCPRecovery(player);
  1027.         }
  1028.         else if (command.startsWith("SupportMagic"))
  1029.         {
  1030.             makeSupportMagic(player);
  1031.         }
  1032.         else if (command.startsWith("multisell"))
  1033.         {
  1034.             L2Multisell.getInstance().createMultiSell(Integer.parseInt(command.substring(9).trim()), player, false, this);
  1035.         }
  1036.         else if (command.startsWith("exc_multisell"))
  1037.         {
  1038.             L2Multisell.getInstance().createMultiSell(Integer.parseInt(command.substring(13).trim()), player, true, this);
  1039.         }
  1040.         else if (command.startsWith("npcfind_byid"))
  1041.         {
  1042.             try
  1043.             {
  1044.                 L2Spawn spawn = SpawnTable.getInstance().getTemplate(Integer.parseInt(command.substring(12).trim()));
  1045.  
  1046.  
  1047.                 if (spawn != null)
  1048.                 {
  1049.                     player.sendPacket(new RadarControl(2, 2, spawn.getLocx(), spawn.getLocy(), spawn.getLocz()));
  1050.                     player.sendPacket(new RadarControl(0, 1, spawn.getLocx(), spawn.getLocy(), spawn.getLocz()));
  1051.                 }
  1052.             }
  1053.             catch (NumberFormatException nfe)
  1054.             {
  1055.                 player.sendMessage("Wrong command parameters.");
  1056.             }
  1057.         }
  1058.         else if (command.startsWith("EnterRift"))
  1059.         {
  1060.             try
  1061.             {
  1062.                 Byte b1 = Byte.parseByte(command.substring(10)); // Selected Area: Recruit, Soldier etc
  1063.                 DimensionalRiftManager.getInstance().start(player, b1, this);
  1064.             }
  1065.             catch(Exception e){}
  1066.         }
  1067.         else if (command.startsWith("ChangeRiftRoom"))
  1068.         {
  1069.             if (player.isInParty() && player.getParty().isInDimensionalRift())
  1070.                 player.getParty().getDimensionalRift().manualTeleport(player, this);
  1071.             else
  1072.                 DimensionalRiftManager.getInstance().handleCheat(player, this);
  1073.         }
  1074.         else if (command.startsWith("ExitRift"))
  1075.         {
  1076.             if (player.isInParty() && player.getParty().isInDimensionalRift())
  1077.                 player.getParty().getDimensionalRift().manualExitRift(player, this);
  1078.             else
  1079.                 DimensionalRiftManager.getInstance().handleCheat(player, this);
  1080.         }
  1081.  
  1082.     }
  1083.    
  1084.     /**
  1085.      * Return null (regular NPCs don't have weapons instancies).<BR><BR>
  1086.      */
  1087.     public L2ItemInstance getActiveWeaponInstance()
  1088.     {
  1089.         // regular NPCs dont have weapons instancies
  1090.         return null;
  1091.     }
  1092.    
  1093.     /**
  1094.      * Return the weapon item equiped in the right hand of the L2NpcInstance or null.<BR><BR>
  1095.      */
  1096.     public L2Weapon getActiveWeaponItem()
  1097.     {
  1098.         // Get the weapon identifier equiped in the right hand of the L2NpcInstance
  1099.         int weaponId = getTemplate().rhand;
  1100.        
  1101.         if (weaponId < 1)
  1102.             return null;
  1103.        
  1104.         // Get the weapon item equiped in the right hand of the L2NpcInstance
  1105.         L2Item item = ItemTable.getInstance().getTemplate(getTemplate().rhand);
  1106.        
  1107.         if (!(item instanceof L2Weapon))
  1108.             return null;
  1109.        
  1110.         return (L2Weapon)item;
  1111.     }
  1112.    
  1113.     /**
  1114.      * Return null (regular NPCs don't have weapons instancies).<BR><BR>
  1115.      */
  1116.     public L2ItemInstance getSecondaryWeaponInstance()
  1117.     {
  1118.         // regular NPCs dont have weapons instancies
  1119.         return null;
  1120.     }
  1121.    
  1122.     /**
  1123.      * Return the weapon item equiped in the left hand of the L2NpcInstance or null.<BR><BR>
  1124.      */
  1125.     public L2Weapon getSecondaryWeaponItem()
  1126.     {
  1127.         // Get the weapon identifier equiped in the right hand of the L2NpcInstance
  1128.         int weaponId = getTemplate().lhand;
  1129.        
  1130.         if (weaponId < 1)
  1131.             return null;
  1132.        
  1133.         // Get the weapon item equiped in the right hand of the L2NpcInstance
  1134.         L2Item item = ItemTable.getInstance().getTemplate(getTemplate().lhand);
  1135.        
  1136.         if (!(item instanceof L2Weapon))
  1137.             return null;
  1138.        
  1139.         return (L2Weapon)item;
  1140.     }
  1141.    
  1142.     /**
  1143.      * Send a Server->Client packet NpcHtmlMessage to the L2PcInstance in order to display the message of the L2NpcInstance.<BR><BR>
  1144.      *
  1145.      * @param player The L2PcInstance who talks with the L2NpcInstance
  1146.      * @param content The text of the L2NpcMessage
  1147.      *
  1148.      */
  1149.     public void insertObjectIdAndShowChatWindow(L2PcInstance player, String content)
  1150.     {
  1151.         // Send a Server->Client packet NpcHtmlMessage to the L2PcInstance in order to display the message of the L2NpcInstance
  1152.         content = content.replaceAll("%objectId%", String.valueOf(getObjectId()));
  1153.         NpcHtmlMessage npcReply = new NpcHtmlMessage(getObjectId());
  1154.         npcReply.setHtml(content);
  1155.         player.sendPacket(npcReply);
  1156.     }
  1157.    
  1158.     /**
  1159.      * Return the pathfile of the selected HTML file in function of the npcId and of the page number.<BR><BR>
  1160.      *  
  1161.      * <B><U> Format of the pathfile </U> :</B><BR><BR>
  1162.      * <li> if the file exists on the server (page number = 0) : <B>data/html/default/12006.htm</B> (npcId-page number)</li>
  1163.      * <li> if the file exists on the server (page number > 0) : <B>data/html/default/12006-1.htm</B> (npcId-page number)</li>
  1164.      * <li> if the file doesn't exist on the server : <B>data/html/npcdefault.htm</B> (message : "I have nothing to say to you")</li><BR><BR>
  1165.      *
  1166.      * <B><U> Overriden in </U> :</B><BR><BR>
  1167.      * <li> L2GuardInstance : Set the pathfile to data/html/guard/12006-1.htm (npcId-page number)</li><BR><BR>
  1168.      *
  1169.      * @param npcId The Identifier of the L2NpcInstance whose text must be display
  1170.      * @param val The number of the page to display
  1171.      *
  1172.      */
  1173.     public String getHtmlPath(int npcId, int val)
  1174.     {
  1175.         String pom = "";
  1176.        
  1177.         if (val == 0)
  1178.             pom = "" + npcId;
  1179.         else
  1180.             pom = npcId + "-" + val;
  1181.        
  1182.         String temp = "data/html/default/" + pom + ".htm";
  1183.        
  1184.         if (!Config.LAZY_CACHE)
  1185.         {
  1186.             // If not running lazy cache the file must be in the cache or it doesnt exist
  1187.             if (HtmCache.getInstance().contains(temp))
  1188.                 return temp;
  1189.         }
  1190.         else
  1191.         {
  1192.             if (HtmCache.getInstance().isLoadable(temp))
  1193.                 return temp;
  1194.         }
  1195.        
  1196.         // If the file is not found, the standard message "I have nothing to say to you" is returned
  1197.         return "data/html/npcdefault.htm";
  1198.     }
  1199.  
  1200.     public void showBuyWindow(L2PcInstance player, int val)
  1201.     {
  1202.         double taxRate = 0;
  1203.         if (getIsInCastleTown())
  1204.             taxRate = getCastle().getTaxRate();
  1205.  
  1206.         player.tempInventoryDisable();
  1207.  
  1208.         if (Config.DEBUG)
  1209.             _log.fine("Showing buylist :"+player.getName()+" List ID :"+val);
  1210.  
  1211.         L2TradeList list = TradeController.getInstance().getBuyList(val);
  1212.  
  1213.         if (list != null && list.getNpcId().equals(String.valueOf(getNpcId())))
  1214.  
  1215.             player.sendPacket(new BuyList(list, player.getAdena(), taxRate));
  1216.  
  1217.         else
  1218.         {
  1219.             _log.warning("possible client hacker: " + player.getName()
  1220.                 + " attempting to buy from GM shop! < Ban him!");
  1221.             _log.warning("buylist id:" + val);
  1222.         }
  1223.  
  1224.         player.sendPacket(new ActionFailed());
  1225.     }
  1226.  
  1227.     /**
  1228.      * Open a choose quest window on client with all quests available of the L2NpcInstance.<BR><BR>
  1229.      *
  1230.      * <B><U> Actions</U> :</B><BR><BR>
  1231.      * <li>Send a Server->Client NpcHtmlMessage containing the text of the L2NpcInstance to the L2PcInstance </li><BR><BR>
  1232.      *
  1233.      * @param player The L2PcInstance that talk with the L2NpcInstance
  1234.      * @param quests The table containing quests of the L2NpcInstance
  1235.      *
  1236.      */
  1237.     public void showQuestChooseWindow(L2PcInstance player, Quest[] quests)
  1238.     {
  1239.         TextBuilder sb = new TextBuilder();
  1240.        
  1241.         sb.append("<html><body><title>Talk about:</title><br>");
  1242.        
  1243.         for (Quest q : quests)
  1244.         {
  1245.             sb.append("<a action=\"bypass -h npc_").append(getObjectId())
  1246.             .append("_Quest ").append(q.getName()).append("\">")
  1247.             .append(q.getDescr()).append("</a><br>");
  1248.         }
  1249.        
  1250.         sb.append("</body></html>");
  1251.        
  1252.         // Send a Server->Client packet NpcHtmlMessage to the L2PcInstance in order to display the message of the L2NpcInstance
  1253.         insertObjectIdAndShowChatWindow(player, sb.toString());
  1254.     }
  1255.    
  1256.     /**
  1257.      * Open a quest window on client with the text of the L2NpcInstance.<BR><BR>
  1258.      *
  1259.      * <B><U> Actions</U> :</B><BR><BR>
  1260.      * <li>Get the text of the quest state in the folder data/scripts/quests/questId/stateId.htm </li>
  1261.      * <li>Send a Server->Client NpcHtmlMessage containing the text of the L2NpcInstance to the L2PcInstance </li>
  1262.      * <li>Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet </li><BR><BR>
  1263.      *
  1264.      * @param player The L2PcInstance that talk with the L2NpcInstance
  1265.      * @param questId The Identifier of the quest to display the message
  1266.      *
  1267.      */
  1268.     public void showQuestWindow(L2PcInstance player, String questId)
  1269.     {
  1270.         String content;
  1271.  
  1272.  
  1273.         // Get the state of the selected quest
  1274.         QuestState qs = player.getQuestState(questId);
  1275.        
  1276.         if (qs != null)
  1277.         {
  1278.             // If the quest is already started, no need to show a window
  1279.             if (!qs.getQuest().notifyTalk(this, qs))
  1280.                 return;
  1281.         }
  1282.         else
  1283.         {
  1284.             Quest q = QuestManager.getInstance().getQuest(questId);
  1285.             if (q != null)
  1286.             {
  1287.                 if (q.getQuestIntId() >= 1 && q.getQuestIntId() < 1000)
  1288.                 {
  1289.                     Quest[] questList = player.getAllActiveQuests();
  1290.                     if (questList.length >= 15) // if too many ongoing quests, don't show window and send message
  1291.                     {
  1292.                         player.sendPacket(new SystemMessage(401));
  1293.                         return;
  1294.                     }
  1295.  
  1296.                     if (player.getWeightPenalty() >= 3 || player.getInventoryLimit() * 0.8 <= player.getInventory().getSize())
  1297.                     {  
  1298.                         player.sendPacket(new SystemMessage(SystemMessage.INVENTORY_80_PERCENT_FOR_QUEST));
  1299.                         return;
  1300.                     }
  1301.                 }
  1302.  
  1303.                 // check for start point
  1304.                 Quest[] qlst = getTemplate().getEventQuests(Quest.QuestEventType.QUEST_START);
  1305.                
  1306.                 if (qlst != null && qlst.length > 0)
  1307.                 {
  1308.                     for (int i=0; i < qlst.length; i++)
  1309.                     {
  1310.                         if (qlst[i] == q)
  1311.                         {
  1312.                             qs = q.newQuestState(player);
  1313.                             //disabled by mr. because quest dialog only show on second click.
  1314.                             //if(qs.getState().getName().equalsIgnoreCase("completed"))
  1315.                             //{
  1316.                             if (!qs.getQuest().notifyTalk(this, qs))
  1317.                                 return; // no need to show a window
  1318.                             //}
  1319.                             break;
  1320.                         }
  1321.                     }
  1322.                 }
  1323.             }
  1324.         }
  1325.        
  1326.         if (qs == null)
  1327.         {
  1328.             // no quests found
  1329.             content = "<html><body>I have no tasks for you right now.</body></html>";
  1330.         }
  1331.         else
  1332.         {
  1333.             questId = qs.getQuest().getName();
  1334.             String stateId = qs.getStateId();
  1335.             String path = "data/scripts/quests/"+questId+"/"+stateId+".htm";
  1336.             content = HtmCache.getInstance().getHtm(path); //TODO path for quests html
  1337.            
  1338.             if (Config.DEBUG)
  1339.             {
  1340.                 if (content != null)
  1341.                 {
  1342.                     _log.fine("Showing quest window for quest "+questId+" html path: " + path);
  1343.                 }
  1344.                 else
  1345.                 {
  1346.                     _log.fine("File not exists for quest "+questId+" html path: " + path);
  1347.                 }
  1348.             }
  1349.         }
  1350.        
  1351.         // Send a Server->Client packet NpcHtmlMessage to the L2PcInstance in order to display the message of the L2NpcInstance
  1352.         if (content != null)
  1353.             insertObjectIdAndShowChatWindow(player, content);
  1354.        
  1355.         // Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
  1356.         player.sendPacket(new ActionFailed());
  1357.     }
  1358.    
  1359.     /**
  1360.      * Collect awaiting quests/start points and display a QuestChooseWindow (if several available) or QuestWindow.<BR><BR>
  1361.      *
  1362.      * @param player The L2PcInstance that talk with the L2NpcInstance
  1363.      *
  1364.      */
  1365.     public void showQuestWindow(L2PcInstance player)
  1366.     {
  1367.         // collect awaiting quests and start points
  1368.         List<Quest> options = new FastList<>();
  1369.        
  1370.         QuestState[] awaits = player.getQuestsForTalk(getTemplate().npcId);
  1371.         Quest[] starts = getTemplate().getEventQuests(Quest.QuestEventType.QUEST_START);
  1372.        
  1373.         // Quests are limited between 1 and 999 because those are the quests that are supported by the client.
  1374.         if (awaits != null)
  1375.         {
  1376.             for (QuestState x : awaits)
  1377.             {
  1378.                 if (!options.contains(x))
  1379.                     if((x.getQuest().getQuestIntId()>0) && (x.getQuest().getQuestIntId()<1000))
  1380.                         options.add(x.getQuest());
  1381.             }
  1382.         }
  1383.        
  1384.         if (starts != null)
  1385.         {
  1386.             for (Quest x : starts)
  1387.             {
  1388.                 if (!options.contains(x))
  1389.                     if((x.getQuestIntId()>0) && (x.getQuestIntId()<1000))
  1390.                         options.add(x);
  1391.             }
  1392.         }
  1393.        
  1394.         // Display a QuestChooseWindow (if several quests are available) or QuestWindow
  1395.         if (options.size() > 1)
  1396.         {
  1397.             showQuestChooseWindow(player, options.toArray(new Quest[options.size()]));
  1398.         }
  1399.         else if (options.size() == 1)
  1400.         {
  1401.             showQuestWindow(player, options.get(0).getName());
  1402.         }
  1403.         else
  1404.         {
  1405.             showQuestWindow(player, "");
  1406.         }
  1407.     }
  1408.    
  1409.     /**
  1410.      * Open a Loto window on client with the text of the L2NpcInstance.<BR><BR>
  1411.      *
  1412.      * <B><U> Actions</U> :</B><BR><BR>
  1413.      * <li>Get the text of the selected HTML file in function of the npcId and of the page number </li>
  1414.      * <li>Send a Server->Client NpcHtmlMessage containing the text of the L2NpcInstance to the L2PcInstance </li>
  1415.      * <li>Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet </li><BR>
  1416.      *
  1417.      * @param player The L2PcInstance that talk with the L2NpcInstance
  1418.      * @param val The number of the page of the L2NpcInstance to display
  1419.      *
  1420.      */
  1421.     // 0 - first buy lottery ticket window
  1422.     // 1-20 - buttons
  1423.     // 21 - second buy lottery ticket window
  1424.     // 22 - selected ticket with 5 numbers
  1425.     // 23 - current lottery jackpot
  1426.     // 24 - Previous winning numbers/Prize claim
  1427.     // >24 - check lottery ticket by item object id
  1428.     public void showLotoWindow(L2PcInstance player, int val)
  1429.     {
  1430.         int npcId = getTemplate().npcId;
  1431.         String filename;
  1432.         SystemMessage sm;
  1433.         NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
  1434.        
  1435.         if (val == 0) // 0 - first buy lottery ticket window
  1436.         {
  1437.             filename = (getHtmlPath(npcId, 1));
  1438.             html.setFile(filename);
  1439.         }
  1440.         else if (val >= 1 && val <= 21) // 1-20 - buttons, 21 - second buy lottery ticket window
  1441.         {
  1442.             if (!Lottery.getInstance().isStarted())
  1443.             {
  1444.                 //tickets can't be sold
  1445.                 player.sendPacket(new SystemMessage(930));
  1446.                 return;
  1447.             }
  1448.             if (!Lottery.getInstance().isSellableTickets())
  1449.             {
  1450.                 //tickets can't be sold
  1451.                 player.sendPacket(new SystemMessage(784));
  1452.                 return;
  1453.             }
  1454.  
  1455.             filename = (getHtmlPath(npcId, 5));
  1456.             html.setFile(filename);
  1457.            
  1458.             int count = 0;
  1459.             int found = 0;
  1460.             // counting buttons and unsetting button if found
  1461.             for (int i = 0; i < 5; i++)
  1462.             {
  1463.                 if (player.getLoto(i) == val)
  1464.                 {
  1465.                          //unsetting button
  1466.                     player.setLoto(i, 0);
  1467.                     found = 1;
  1468.                 }
  1469.                 else if (player.getLoto(i) > 0)
  1470.                 {
  1471.                     count++;
  1472.                 }
  1473.             }
  1474.            
  1475.                  //if not rearched limit 5 and not unseted value
  1476.             if (count < 5 && found == 0 && val <= 20)
  1477.                 for (int i = 0; i < 5; i++)
  1478.                     if (player.getLoto(i) == 0)
  1479.                     {
  1480.                         player.setLoto(i, val);
  1481.                         break;
  1482.                     }
  1483.            
  1484.             //setting pusshed buttons
  1485.             count = 0;
  1486.             for (int i = 0; i < 5; i++)
  1487.                 if (player.getLoto(i) > 0)
  1488.                 {
  1489.                     count++;
  1490.                     String button = String.valueOf(player.getLoto(i));
  1491.                     if (player.getLoto(i) < 10) button = "0" + button;
  1492.                     String search = "fore=\"L2UI.lottoNum" + button + "\" back=\"L2UI.lottoNum" + button + "a_check\"";
  1493.                     String replace = "fore=\"L2UI.lottoNum" + button + "a_check\" back=\"L2UI.lottoNum" + button + "\"";
  1494.                     html.replace(search, replace);
  1495.                 }
  1496.            
  1497.             if (count == 5)
  1498.             {
  1499.                 String search = "0\">Return";
  1500.                 String replace = "22\">The winner selected the numbers above.";
  1501.                 html.replace(search, replace);
  1502.             }
  1503.         }
  1504.         else if (val == 22) //22 - selected ticket with 5 numbers
  1505.         {
  1506.             if (!Lottery.getInstance().isStarted())
  1507.             {
  1508.                 //tickets can't be sold
  1509.                 player.sendPacket(new SystemMessage(930));
  1510.                 return;
  1511.             }
  1512.             if (!Lottery.getInstance().isSellableTickets())
  1513.             {
  1514.                 //tickets can't be sold
  1515.                 player.sendPacket(new SystemMessage(784));
  1516.                 return;
  1517.             }
  1518.                  
  1519.             int price = Config.ALT_LOTTERY_TICKET_PRICE;
  1520.             int lotonumber = Lottery.getInstance().getId();
  1521.             int enchant = 0;
  1522.             int type2 = 0;
  1523.                  
  1524.             for (int i = 0; i < 5; i++)
  1525.             {
  1526.                 if (player.getLoto(i) == 0) return;
  1527.                      
  1528.                 if (player.getLoto(i) < 17) enchant += Math.pow(2, player.getLoto(i) - 1);
  1529.                 else type2 += Math.pow(2, player.getLoto(i) - 17);
  1530.             }
  1531.             if (player.getAdena() < price)
  1532.             {
  1533.                      sm = new SystemMessage(SystemMessage.YOU_NOT_ENOUGH_ADENA);
  1534.                      player.sendPacket(sm);
  1535.                      return;
  1536.             }
  1537.             if (!player.reduceAdena("Loto", price, this, true)) return;
  1538.             Lottery.getInstance().increasePrize(price);
  1539.  
  1540.             sm = new SystemMessage(SystemMessage.ACQUIRED);
  1541.             sm.addNumber(lotonumber);
  1542.             sm.addItemName(4442);
  1543.             player.sendPacket(sm);
  1544.            
  1545.             L2ItemInstance item = new L2ItemInstance(IdFactory.getInstance().getNextId(), 4442);
  1546.             item.setCount(1);
  1547.             item.setCustomType1(lotonumber);
  1548.             item.setEnchantLevel(enchant);
  1549.             item.setCustomType2(type2);
  1550.             player.getInventory().addItem("Loto", item, player, this);
  1551.            
  1552.             InventoryUpdate iu = new InventoryUpdate();
  1553.             iu.addItem(item);
  1554.             L2ItemInstance adenaupdate = player.getInventory().getItemByItemId(57);
  1555.             iu.addModifiedItem(adenaupdate);
  1556.             player.sendPacket(iu);
  1557.            
  1558.             filename = (getHtmlPath(npcId, 3));
  1559.             html.setFile(filename);
  1560.         }
  1561.         else if (val == 23) //23 - current lottery jackpot
  1562.         {
  1563.             filename = (getHtmlPath(npcId, 3));
  1564.             html.setFile(filename);
  1565.         }
  1566.         else if (val == 24) // 24 - Previous winning numbers/Prize claim
  1567.         {
  1568.             filename = (getHtmlPath(npcId, 4));
  1569.             html.setFile(filename);
  1570.            
  1571.             int lotonumber = Lottery.getInstance().getId();
  1572.             String message = "";
  1573.             for (L2ItemInstance item : player.getInventory().getItems())
  1574.             {
  1575.                 if (item == null) continue;
  1576.                 if (item.getItemId() == 4442 && item.getCustomType1() < lotonumber)
  1577.                 {
  1578.                     message = message + "<a action=\"bypass -h npc_%objectId%_Loto "
  1579.                     + item.getObjectId() + "\">" + item.getCustomType1() + " Event Number ";
  1580.                     int[] numbers = Lottery.getInstance().decodeNumbers(item.getEnchantLevel(),
  1581.                                                                         item.getCustomType2());
  1582.                     for (int i = 0; i < 5; i++)
  1583.                     {
  1584.                         message += numbers[i] + " ";
  1585.                     }
  1586.                     int[] check = Lottery.getInstance().checkTicket(item);
  1587.                     if (check[0] > 0)
  1588.                     {
  1589.                         switch (check[0])
  1590.                         {
  1591.                             case 1:
  1592.                                 message += "- 1st Prize";
  1593.                                 break;
  1594.                             case 2:
  1595.                                 message += "- 2nd Prize";
  1596.                                 break;
  1597.                             case 3:
  1598.                                 message += "- 3th Prize";
  1599.                                 break;
  1600.                             case 4:
  1601.                                 message += "- 4th Prize";
  1602.                                 break;
  1603.                         }
  1604.                         message += " " + check[1] + "a.";
  1605.                     }
  1606.                     message += "</a><br>";
  1607.                 }
  1608.             }
  1609.             if (message.isEmpty())
  1610.             {
  1611.                 message += "There is no winning lottery ticket...<br>";
  1612.             }
  1613.             html.replace("%result%", message);
  1614.         }
  1615.         else if (val > 24) // >24 - check lottery ticket by item object id
  1616.         {
  1617.             int lotonumber = Lottery.getInstance().getId();
  1618.             L2ItemInstance item = player.getInventory().getItemByObjectId(val);
  1619.             if (item == null || item.getItemId() != 4442 || item.getCustomType1() >= lotonumber) return;
  1620.             int[] check = Lottery.getInstance().checkTicket(item);
  1621.            
  1622.             sm = new SystemMessage(SystemMessage.DISSAPEARED_ITEM);
  1623.             sm.addItemName(4442);
  1624.             player.sendPacket(sm);
  1625.            
  1626.             int adena = check[1];
  1627.             if (adena > 0)
  1628.                 player.addAdena("Loto", adena, this, true);
  1629.             player.destroyItem("Loto", item, this, false);
  1630.             return;
  1631.         }
  1632.         html.replace("%objectId%", String.valueOf(getObjectId()));
  1633.         html.replace("%race%", "" + Lottery.getInstance().getId());
  1634.         html.replace("%adena%", "" + Lottery.getInstance().getPrize());
  1635.         html.replace("%ticket_price%", "" + Config.ALT_LOTTERY_TICKET_PRICE);
  1636.         html.replace("%prize5%", "" + (Config.ALT_LOTTERY_5_NUMBER_RATE * 100));
  1637.         html.replace("%prize4%", "" + (Config.ALT_LOTTERY_4_NUMBER_RATE * 100));
  1638.         html.replace("%prize3%", "" + (Config.ALT_LOTTERY_3_NUMBER_RATE * 100));
  1639.         html.replace("%prize2%", "" + Config.ALT_LOTTERY_2_AND_1_NUMBER_PRIZE);
  1640.         html.replace("%enddate%", "" + DateFormat.getDateInstance().format(Lottery.getInstance().getEndDate()));
  1641.         player.sendPacket(html);
  1642.              
  1643.         // Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
  1644.         player.sendPacket(new ActionFailed());
  1645.     }
  1646.    
  1647.     public void makeCPRecovery(L2PcInstance player)
  1648.     {
  1649.         if (getNpcId() != 8225 && getNpcId() != 8226)
  1650.             return;
  1651.  
  1652.         int neededmoney = 100;
  1653.  
  1654.         if (!player.reduceAdena("RestoreCP", neededmoney, player.getLastFolkNPC(), true))
  1655.             return;
  1656.  
  1657.         L2Skill skill = SkillTable.getInstance().getInfo(4380, 1);
  1658.         if (skill != null)
  1659.         {
  1660.             setTarget(player);
  1661.             doCast(skill);
  1662.         }
  1663.         player.sendPacket(new ActionFailed());
  1664.     }
  1665.  
  1666.    
  1667.     /**
  1668.      * Add Newbie helper buffs to L2Player according to its level.<BR><BR>
  1669.      *
  1670.      * <B><U> Actions</U> :</B><BR><BR>
  1671.      * <li>Get the range level in wich player must be to obtain buff </li>
  1672.      * <li>If player level is out of range, display a message and return </li>
  1673.      * <li>According to player level cast buff </li><BR><BR>
  1674.      *
  1675.      * <FONT COLOR=#FF0000><B> Newbie Helper Buff list is define in sql table helper_buff_list</B></FONT><BR><BR>
  1676.      *
  1677.      * @param player The L2PcInstance that talk with the L2NpcInstance
  1678.      *
  1679.      */
  1680.     public void makeSupportMagic(L2PcInstance player)
  1681.     {
  1682.         int player_level = player.getLevel();        
  1683.         int lowestLevel;
  1684.         int highestLevel;
  1685.         L2Skill skill;
  1686.        
  1687.        
  1688.         // Select the player
  1689.         setTarget(player);
  1690.        
  1691.        
  1692.         // Calculate the min and max level between wich the player must be to obtain buff
  1693.         if(player.isMageClass())
  1694.         {
  1695.             lowestLevel = HelperBuffTable.getInstance().getMagicClassLowestLevel();
  1696.             highestLevel = HelperBuffTable.getInstance().getMagicClassHighestLevel();
  1697.         }
  1698.         else
  1699.         {
  1700.             lowestLevel = HelperBuffTable.getInstance().getPhysicClassLowestLevel();
  1701.             highestLevel = HelperBuffTable.getInstance().getPhysicClassHighestLevel();
  1702.         }
  1703.  
  1704.         // If the player is too high level, display a message and return
  1705.         if (player_level > highestLevel)
  1706.         {
  1707.             String content = "<html><body>Newbie Guide:<br>Only a <font color=\"LEVEL\">novice character of level "+ highestLevel +" or less</font> can receive my support magic.<br>Your novice character is the first one that you created and raised in this world.</body></html>";
  1708.             insertObjectIdAndShowChatWindow(player, content);
  1709.             return;
  1710.         }
  1711.        
  1712.        
  1713.         // If the player is too low level, display a message and return
  1714.         if (player_level < lowestLevel)
  1715.         {
  1716.             String content = "<html><body>Come back here when you have reached level "+ lowestLevel +". I will give you support magic then.</body></html>";
  1717.             insertObjectIdAndShowChatWindow(player, content);
  1718.             return;
  1719.         }
  1720.  
  1721.         // If the player is not a newbie, display a message and return
  1722.         if (player.getNewbieState() != L2PcInstance.NEW)
  1723.         {
  1724.             String content = "<html><body>Newbie Guide:<br>Your novice character is not the first one that you created and raised in this world.<br>Therefore, you cannot receive support magic anymore.</body></html>";
  1725.             insertObjectIdAndShowChatWindow(player, content);
  1726.             return;
  1727.         }
  1728.  
  1729.         // Go through the Helper Buff list define in sql table helper_buff_list and cast skill
  1730.         for (L2HelperBuff helperBuffItem : HelperBuffTable.getInstance().getHelperBuffTable())
  1731.         {
  1732.            if( helperBuffItem.isMagicClassBuff() == player.isMageClass())
  1733.            {
  1734.               if(player_level>=helperBuffItem.getLowerLevel() && player_level<=helperBuffItem.getUpperLevel())
  1735.               {
  1736.                   skill = SkillTable.getInstance().getInfo(helperBuffItem.getSkillID(),helperBuffItem.getSkillLevel());
  1737.                   if (skill.getSkillType() == SkillType.SUMMON)
  1738.                       player.doCast(skill);
  1739.                   else
  1740.                       doCast(skill);
  1741.               }
  1742.            }
  1743.         }
  1744.     }
  1745.    
  1746.     public void showChatWindow(L2PcInstance player)
  1747.     {
  1748.         showChatWindow(player, 0);
  1749.     }
  1750.  
  1751.     /**
  1752.      * Open a chat window on client with the text of the L2NpcInstance.<BR><BR>
  1753.      *
  1754.      * <B><U> Actions</U> :</B><BR><BR>
  1755.      * <li>Get the text of the selected HTML file in function of the npcId and of the page number </li>
  1756.      * <li>Send a Server->Client NpcHtmlMessage containing the text of the L2NpcInstance to the L2PcInstance </li>
  1757.      * <li>Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet </li><BR>
  1758.      *
  1759.      * @param player The L2PcInstance that talk with the L2NpcInstance
  1760.      * @param val The number of the page of the L2NpcInstance to display
  1761.      *
  1762.      */
  1763.     public void showChatWindow(L2PcInstance player, int val)
  1764.     {
  1765.         if (getTemplate().type.equals("L2Auctioneer") && val==0)
  1766.             return;
  1767.         int npcId = getTemplate().npcId;
  1768.        
  1769.         /* For use with Seven Signs implementation */
  1770.         String filename = SevenSigns.SEVEN_SIGNS_HTML_PATH;
  1771.         int sealAvariceOwner = SevenSigns.getInstance().getSealOwner(SevenSigns.SEAL_AVARICE);
  1772.         int sealGnosisOwner = SevenSigns.getInstance().getSealOwner(SevenSigns.SEAL_GNOSIS);
  1773.         int playerCabal = SevenSigns.getInstance().getPlayerCabal(player);
  1774.         boolean isSealValidationPeriod = SevenSigns.getInstance().isSealValidationPeriod();
  1775.         int compWinner = SevenSigns.getInstance().getCabalHighestScore();
  1776.        
  1777.         switch (npcId) {
  1778.             case 8078:
  1779.             case 8079:
  1780.             case 8080:
  1781.             case 8081:
  1782.             case 8082: // Dawn Priests
  1783.             case 8083:
  1784.             case 8084:
  1785.             case 8168:
  1786.             case 8692:
  1787.             case 8694:
  1788.                 switch (playerCabal)
  1789.                 {
  1790.                     case SevenSigns.CABAL_DAWN:
  1791.                         if (isSealValidationPeriod)
  1792.                             if (compWinner == SevenSigns.CABAL_DAWN)
  1793.                                 if (compWinner != sealGnosisOwner)
  1794.                                     filename += "dawn_priest_2c.htm";
  1795.                                 else
  1796.                                     filename += "dawn_priest_2a.htm";
  1797.                             else
  1798.                                 filename += "dawn_priest_2b.htm";
  1799.                         else
  1800.                             filename += "dawn_priest_1b.htm";
  1801.                         break;
  1802.                     case SevenSigns.CABAL_DUSK:
  1803.                         if (isSealValidationPeriod)
  1804.                             filename += "dawn_priest_3b.htm";
  1805.                         else
  1806.                             filename += "dawn_priest_3a.htm";
  1807.                         break;
  1808.                     default:
  1809.                         if (isSealValidationPeriod)
  1810.                             if (compWinner == SevenSigns.CABAL_DAWN)
  1811.                                 filename += "dawn_priest_4.htm";
  1812.                             else
  1813.                                 filename += "dawn_priest_2b.htm";  
  1814.                         else
  1815.                             filename += "dawn_priest_1a.htm";
  1816.                     break;
  1817.                 }
  1818.                 break;
  1819.             case 8085:
  1820.             case 8086:
  1821.             case 8087:
  1822.             case 8088: // Dusk Priest
  1823.             case 8089:
  1824.             case 8090:
  1825.             case 8091:
  1826.             case 8169:
  1827.             case 8693:
  1828.             case 8695:
  1829.                 switch (playerCabal)
  1830.                 {
  1831.                     case SevenSigns.CABAL_DUSK:
  1832.                         if (isSealValidationPeriod)
  1833.                             if (compWinner == SevenSigns.CABAL_DUSK)
  1834.                                 if (compWinner != sealGnosisOwner)
  1835.                                     filename += "dusk_priest_2c.htm";
  1836.                                 else
  1837.                                     filename += "dusk_priest_2a.htm";
  1838.                             else
  1839.                                 filename += "dusk_priest_2b.htm";
  1840.                         else
  1841.                             filename += "dusk_priest_1b.htm";
  1842.                         break;
  1843.                     case SevenSigns.CABAL_DAWN:
  1844.                         if (isSealValidationPeriod)
  1845.                             filename += "dusk_priest_3b.htm";
  1846.                         else
  1847.                             filename += "dusk_priest_3a.htm";
  1848.                         break;
  1849.                     default:
  1850.                         if (isSealValidationPeriod)
  1851.                             if (compWinner == SevenSigns.CABAL_DUSK)
  1852.                                 filename += "dusk_priest_4.htm";
  1853.                             else
  1854.                                 filename += "dusk_priest_2b.htm";
  1855.                         else
  1856.                             filename += "dusk_priest_1a.htm";
  1857.                     break;
  1858.                 }
  1859.                 break;
  1860.             case 8095: //
  1861.             case 8096: //
  1862.             case 8097: //
  1863.             case 8098: // Enter Necropolises
  1864.             case 8099: //
  1865.             case 8100: //
  1866.             case 8101: //
  1867.             case 8102: //
  1868.                 if (isSealValidationPeriod)
  1869.                 {
  1870.                         if (playerCabal != compWinner || sealAvariceOwner != compWinner)
  1871.                     {
  1872.                             switch (compWinner)
  1873.                             {
  1874.                                     case SevenSigns.CABAL_DAWN:
  1875.                                                 player.sendPacket(new SystemMessage(SystemMessage.CAN_BE_USED_BY_DAWN));
  1876.                                                 filename += "necro_no.htm";
  1877.                                         break;
  1878.                                 case SevenSigns.CABAL_DUSK:
  1879.                                                 player.sendPacket(new SystemMessage(SystemMessage.CAN_BE_USED_BY_DUSK));
  1880.                                                 filename += "necro_no.htm";
  1881.                                     break;
  1882.                                 case SevenSigns.CABAL_NULL:
  1883.                                             filename = (getHtmlPath(npcId, val)); // do the default!
  1884.                                         break;
  1885.                         }
  1886.                 }
  1887.                 else
  1888.                                 filename = (getHtmlPath(npcId, val)); // do the default!
  1889.                 }
  1890.                 else
  1891.                 {
  1892.                     if (playerCabal == SevenSigns.CABAL_NULL)
  1893.                         filename += "necro_no.htm";
  1894.                     else
  1895.                         filename = (getHtmlPath(npcId, val)); // do the default!    
  1896.                 }
  1897.                 break;
  1898.             case 8114: //
  1899.             case 8115: //
  1900.             case 8116: // Enter Catacombs
  1901.             case 8117: //
  1902.             case 8118: //
  1903.             case 8119: //
  1904.                 if (isSealValidationPeriod)
  1905.                 {
  1906.                     if (playerCabal != compWinner || sealGnosisOwner != compWinner)
  1907.                 {
  1908.                     switch (compWinner)
  1909.                     {
  1910.                         case SevenSigns.CABAL_DAWN:
  1911.                                         player.sendPacket(new SystemMessage(SystemMessage.CAN_BE_USED_BY_DAWN));
  1912.                                         filename += "cata_no.htm";
  1913.                             break;
  1914.                         case SevenSigns.CABAL_DUSK:
  1915.                                         player.sendPacket(new SystemMessage(SystemMessage.CAN_BE_USED_BY_DUSK));
  1916.                                         filename += "cata_no.htm";
  1917.                             break;
  1918.                         case SevenSigns.CABAL_NULL:
  1919.                                 filename = (getHtmlPath(npcId, val)); // do the default!
  1920.                                 break;
  1921.                     }
  1922.                 }
  1923.                 else
  1924.                         filename = (getHtmlPath(npcId, val)); // do the default!
  1925.                 }
  1926.                 else
  1927.                 {
  1928.                     if (playerCabal == SevenSigns.CABAL_NULL)
  1929.                         filename += "cata_no.htm";
  1930.                     else
  1931.                         filename = (getHtmlPath(npcId, val)); // do the default!    
  1932.                 }
  1933.                 break;
  1934.             case 8111: // Gatekeeper Spirit (Disciples)
  1935.                 if (playerCabal == sealAvariceOwner && playerCabal == compWinner)
  1936.                 {
  1937.                     switch (sealAvariceOwner)
  1938.                     {
  1939.                         case SevenSigns.CABAL_DAWN:
  1940.                             filename += "spirit_dawn.htm";
  1941.                             break;
  1942.                         case SevenSigns.CABAL_DUSK:
  1943.                             filename += "spirit_dusk.htm";
  1944.                             break;
  1945.                         case SevenSigns.CABAL_NULL:
  1946.                             filename += "spirit_null.htm";
  1947.                             break;
  1948.                     }
  1949.                 }
  1950.                 else
  1951.                 {
  1952.                     filename += "spirit_null.htm";
  1953.                 }
  1954.                 break;
  1955.             case 8112: // Gatekeeper Spirit (Disciples)
  1956.                 filename += "spirit_exit.htm";
  1957.                 break;
  1958.             case 8127: //
  1959.             case 8128: //
  1960.             case 8129: // Dawn Festival Guides
  1961.             case 8130: //
  1962.             case 8131: //
  1963.                 filename += "festival/dawn_guide.htm";
  1964.                 break;
  1965.             case 8137: //
  1966.             case 8138: //
  1967.             case 8139: // Dusk Festival Guides
  1968.             case 8140: //
  1969.             case 8141: //
  1970.                 filename += "festival/dusk_guide.htm";
  1971.                 break;
  1972.             case 8092: // Black Marketeer of Mammon
  1973.                 filename += "blkmrkt_1.htm";
  1974.                 break;
  1975.             case 8113: // Merchant of Mammon
  1976.                 switch (compWinner)
  1977.                 {
  1978.                     case SevenSigns.CABAL_DAWN:
  1979.                         if (playerCabal != compWinner || playerCabal != sealAvariceOwner)
  1980.                         {
  1981.                             player.sendPacket(new SystemMessage(SystemMessage.CAN_BE_USED_BY_DAWN));
  1982.                             player.sendPacket(new ActionFailed());
  1983.                             return;
  1984.                         }
  1985.                         break;
  1986.                     case SevenSigns.CABAL_DUSK:
  1987.                         if (playerCabal != compWinner || playerCabal != sealAvariceOwner)
  1988.                         {
  1989.                             player.sendPacket(new SystemMessage(SystemMessage.CAN_BE_USED_BY_DUSK));
  1990.                             player.sendPacket(new ActionFailed());
  1991.                             return;
  1992.                         }
  1993.                         break;
  1994.                 }
  1995.                 filename += "mammmerch_1.htm";
  1996.                 break;
  1997.             case 8126: // Blacksmith of Mammon
  1998.                 switch (compWinner)
  1999.                 {
  2000.                     case SevenSigns.CABAL_DAWN:
  2001.                         if (playerCabal != compWinner || playerCabal != sealGnosisOwner)
  2002.                         {
  2003.                             player.sendPacket(new SystemMessage(SystemMessage.CAN_BE_USED_BY_DAWN));
  2004.                             player.sendPacket(new ActionFailed());
  2005.                             return;
  2006.                         }
  2007.                         break;
  2008.                     case SevenSigns.CABAL_DUSK:
  2009.                         if (playerCabal != compWinner || playerCabal != sealGnosisOwner)
  2010.                         {
  2011.                             player.sendPacket(new SystemMessage(SystemMessage.CAN_BE_USED_BY_DUSK));
  2012.                             player.sendPacket(new ActionFailed());
  2013.                             return;
  2014.                         }
  2015.                         break;
  2016.                 }
  2017.                 filename += "mammblack_1.htm";
  2018.                 break;
  2019.             case 8132:
  2020.             case 8133:
  2021.             case 8134:
  2022.             case 8135:
  2023.             case 8136:  // Festival Witches
  2024.             case 8142:
  2025.             case 8143:
  2026.             case 8144:
  2027.             case 8145:
  2028.             case 8146:            
  2029.                 filename += "festival/festival_witch.htm";
  2030.                 break;
  2031.             case 8688:
  2032.                 if (player.isNoble())
  2033.                     filename = Olympiad.OLYMPIAD_HTML_FILE + "noble_main.htm";
  2034.                 else
  2035.                     filename = (getHtmlPath(npcId, val));
  2036.                 break;
  2037.             case 8690:
  2038.             case 8769:
  2039.             case 8770:
  2040.             case 8771:
  2041.             case 8772:
  2042.                 if (player.isHero())
  2043.                     filename = Olympiad.OLYMPIAD_HTML_FILE + "hero_main.htm";
  2044.                 else
  2045.                     filename = (getHtmlPath(npcId, val));
  2046.                 break;
  2047.             default:
  2048.                 if (npcId >= 12901 && npcId <= 12954)
  2049.                 {
  2050.                     if (val == 0)
  2051.                         filename += "rift/GuardianOfBorder.htm";
  2052.                     else
  2053.                         filename += "rift/GuardianOfBorder-" + val + ".htm";
  2054.                     break;
  2055.                 }
  2056.  
  2057.                 if ((npcId >= 8093 && npcId <= 8094) ||
  2058.                         (npcId >= 8172 && npcId <= 8201) ||
  2059.                         (npcId >= 8239 && npcId <= 8254))
  2060.                     return;
  2061.             // Get the text of the selected HTML file in function of the npcId and of the page number
  2062.             filename = (getHtmlPath(npcId, val));
  2063.             break;
  2064.         }
  2065.        
  2066.         // Send a Server->Client NpcHtmlMessage containing the text of the L2NpcInstance to the L2PcInstance
  2067.         NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
  2068.         html.setFile(filename);
  2069.        
  2070.         //String word = "npc-"+npcId+(val>0 ? "-"+val : "" )+"-dialog-append";
  2071.        
  2072.         if (this instanceof L2MerchantInstance)
  2073.             if (Config.LIST_PET_RENT_NPC.contains(npcId))
  2074.                 html.replace("_Quest", "_RentPet\">Rent Pet</a><br><a action=\"bypass -h npc_%objectId%_Quest");
  2075.        
  2076.         html.replace("%objectId%", String.valueOf(getObjectId()));
  2077.         html.replace("%festivalMins%", SevenSignsFestival.getInstance().getTimeToNextFestivalStr());        
  2078.         player.sendPacket(html);
  2079.        
  2080.         // Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
  2081.         player.sendPacket( new ActionFailed());
  2082.     }
  2083.    
  2084.     /**
  2085.      * Open a chat window on client with the text specified by the given file name and path,<BR>
  2086.      * relative to the datapack root.
  2087.      * <BR><BR>
  2088.      * Added by Tempy
  2089.      * @param player The L2PcInstance that talk with the L2NpcInstance
  2090.      * @param filename The filename that contains the text to send
  2091.      *  
  2092.      */
  2093.     public void showChatWindow(L2PcInstance player, String filename)
  2094.     {
  2095.         // Send a Server->Client NpcHtmlMessage containing the text of the L2NpcInstance to the L2PcInstance
  2096.         NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
  2097.         html.setFile(filename);
  2098.         html.replace("%objectId%",String.valueOf(getObjectId()));
  2099.         player.sendPacket(html);
  2100.        
  2101.         // Send a Server->Client ActionFailed to the L2PcInstance in order to avoid that the client wait another packet
  2102.         player.sendPacket( new ActionFailed() );
  2103.     }
  2104.    
  2105.     /**
  2106.      * Return the Exp Reward of this L2NpcInstance contained in the L2NpcTemplate (modified by RATE_XP).<BR><BR>
  2107.      */
  2108.     public int getExpReward()
  2109.     {
  2110.         double rateXp = getStat().calcStat(Stats.MAX_HP , 1, this, null);
  2111.         return (int)(getTemplate().rewardExp * rateXp * Config.RATE_XP);
  2112.     }
  2113.    
  2114.     /**
  2115.      * Return the SP Reward of this L2NpcInstance contained in the L2NpcTemplate (modified by RATE_SP).<BR><BR>
  2116.      */
  2117.     public int getSpReward()
  2118.     {
  2119.         double rateSp = getStat().calcStat(Stats.MAX_HP , 1, this, null);
  2120.         return (int)(getTemplate().rewardSp * rateSp * Config.RATE_SP);
  2121.     }
  2122.    
  2123.     /**
  2124.      * Kill the L2NpcInstance (the corpse disappeared after 7 seconds).<BR><BR>
  2125.      *
  2126.      * <B><U> Actions</U> :</B><BR><BR>
  2127.      * <li>Create a DecayTask to remove the corpse of the L2NpcInstance after 7 seconds </li>
  2128.      * <li>Set target to null and cancel Attack or Cast </li>
  2129.      * <li>Stop movement </li>
  2130.      * <li>Stop HP/MP/CP Regeneration task </li>
  2131.      * <li>Stop all active skills effects in progress on the L2Character </li>
  2132.      * <li>Send the Server->Client packet StatusUpdate with current HP and MP to all other L2PcInstance to inform </li>
  2133.      * <li>Notify L2Character AI </li><BR><BR>
  2134.      *
  2135.      * <B><U> Overriden in </U> :</B><BR><BR>
  2136.      * <li> L2Attackable </li><BR><BR>
  2137.      *
  2138.      * @param killer The L2Character who killed it
  2139.      *
  2140.      */
  2141.     public boolean doDie(L2Character killer)
  2142.     {
  2143.         if (!super.doDie(killer))
  2144.             return false;
  2145.  
  2146.         _currentCollisionHeight = getTemplate().collisionHeight;
  2147.         _currentCollisionRadius = getTemplate().collisionRadius;
  2148.         DecayTaskManager.getInstance().addDecayTask(this);
  2149.         return true;
  2150.     }
  2151.  
  2152.     /**
  2153.      * Set the spawn of the L2NpcInstance.<BR><BR>
  2154.      *
  2155.      * @param spawn The L2Spawn that manage the L2NpcInstance
  2156.      *
  2157.      */
  2158.     public void setSpawn(L2Spawn spawn)
  2159.     {
  2160.         _spawn = spawn;
  2161.     }
  2162.  
  2163.     @Override
  2164.     public void onSpawn()
  2165.     {
  2166.         if (_inventory != null)
  2167.             _inventory.reset();
  2168.  
  2169.         super.onSpawn();
  2170.     }
  2171.  
  2172.     /**
  2173.      * Remove the L2NpcInstance from the world and update its spawn object (for a complete removal use the deleteMe method).<BR><BR>
  2174.      *
  2175.      * <B><U> Actions</U> :</B><BR><BR>
  2176.      * <li>Remove the L2NpcInstance from the world when the decay task is launched </li>
  2177.      * <li>Decrease its spawn counter </li>
  2178.      * <li>Manage Siege task (killFlag, killCT) </li><BR><BR>
  2179.      *
  2180.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T REMOVE the object from _allObjects of L2World </B></FONT><BR>
  2181.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T SEND Server->Client packets to players</B></FONT><BR><BR>
  2182.      *
  2183.      */
  2184.     public void onDecay()
  2185.     {
  2186.         if (isDecayed()) return;
  2187.         setDecayed(true);
  2188.  
  2189.         // Manage Life Control Tower
  2190.         if (this instanceof L2ControlTowerInstance)
  2191.             ((L2ControlTowerInstance)this).onDeath();
  2192.        
  2193.         // Remove the L2NpcInstance from the world when the decay task is launched
  2194.         super.onDecay();
  2195.        
  2196.         // Decrease its spawn counter
  2197.         if (_spawn != null)
  2198.             _spawn.decreaseCount(this);
  2199.     }
  2200.    
  2201.     /**
  2202.      * Remove PROPERLY the L2NpcInstance from the world.<BR><BR>
  2203.      *
  2204.      * <B><U> Actions</U> :</B><BR><BR>
  2205.      * <li>Remove the L2NpcInstance from the world and update its spawn object </li>
  2206.      * <li>Remove all L2Object from _knownObjects and _knownPlayer of the L2NpcInstance then cancel Attak or Cast and notify AI </li>
  2207.      * <li>Remove L2Object object from _allObjects of L2World </li><BR><BR>
  2208.      *
  2209.      * <FONT COLOR=#FF0000><B> <U>Caution</U> : This method DOESN'T SEND Server->Client packets to players</B></FONT><BR><BR>
  2210.      *
  2211.      */
  2212.     public void deleteMe()
  2213.     {
  2214.         L2WorldRegion oldRegion = getWorldRegion();
  2215.        
  2216.         try
  2217.         {
  2218.             decayMe();
  2219.         }
  2220.         catch (Throwable t)
  2221.         {
  2222.             _log.severe("deletedMe(): " + t);
  2223.         }
  2224.  
  2225.  
  2226.         if (oldRegion != null)
  2227.             oldRegion.removeFromZones(this);
  2228.  
  2229.         // Remove all L2Object from _knownObjects and _knownPlayer of the L2Character then cancel Attak or Cast and notify AI
  2230.         try { getKnownList().removeAllKnownObjects(); } catch (Throwable t) {_log.severe("deletedMe(): " + t); }
  2231.        
  2232.         // Remove L2Object object from _allObjects of L2World
  2233.         L2World.getInstance().removeObject(this);
  2234.     }
  2235.  
  2236.     /**
  2237.      * Return the L2Spawn object that manage this L2NpcInstance.<BR><BR>
  2238.      */
  2239.     public L2Spawn getSpawn()
  2240.     {
  2241.         return _spawn;
  2242.     }
  2243.    
  2244.     public String toString()
  2245.     {
  2246.         return getTemplate().name;
  2247.     }
  2248.  
  2249.     public boolean isDecayed()
  2250.     {
  2251.         return _isDecayed;
  2252.     }
  2253.  
  2254.     public void setDecayed(boolean decayed)
  2255.     {
  2256.         _isDecayed = decayed;
  2257.     }
  2258.  
  2259.     public void endDecayTask()
  2260.     {
  2261.         if (!isDecayed())
  2262.         {
  2263.  
  2264.             DecayTaskManager.getInstance().cancelDecayTask(this);
  2265.             onDecay();
  2266.         }
  2267.     }
  2268.  
  2269.  
  2270.     public void setCollisionHeight(double height)
  2271.     {
  2272.         _currentCollisionHeight = height;
  2273.     }
  2274.  
  2275.     public void setCollisionRadius(double radius)
  2276.     {
  2277.         _currentCollisionRadius = radius;
  2278.     }
  2279.  
  2280.     public double getCollisionHeight()
  2281.     {
  2282.         return _currentCollisionHeight;
  2283.     }
  2284.  
  2285.     public double getCollisionRadius()
  2286.     {
  2287.         return _currentCollisionRadius;
  2288.     }
  2289.  
  2290.     public boolean rechargeAutoSoulShot(boolean physical, boolean magic)
  2291.     {
  2292.         if (getTemplate().ssRate == 0)
  2293.             return false;
  2294.  
  2295.         L2Weapon weaponItem = getActiveWeaponItem();
  2296.         if (weaponItem == null)
  2297.             return false;
  2298.  
  2299.         if (magic)
  2300.         {
  2301.             if (getTemplate().ssRate < Rnd.get(100))
  2302.             {
  2303.                 _inventory.bshotInUse = false;
  2304.                 return false;
  2305.             }
  2306.  
  2307.             if (_inventory.destroyItemByItemId("Consume", 3947, weaponItem.getSpiritShotCount(), null, null) != null)
  2308.             {
  2309.                 _inventory.bshotInUse = true;
  2310.                 broadcastPacket(new MagicSkillUser(this, this, 2061, 1, 0, 0)); // no grade
  2311.                 return true;
  2312.             }
  2313.             else
  2314.                 _inventory.bshotInUse = false;
  2315.         }
  2316.  
  2317.         if (physical)
  2318.         {
  2319.             if (getTemplate().ssRate < Rnd.get(100))
  2320.             {
  2321.                 _inventory.sshotInUse = false;
  2322.                 return false;
  2323.             }
  2324.  
  2325.             if (_inventory.destroyItemByItemId("Consume", 1835, weaponItem.getSoulShotCount(), null, null) != null)
  2326.             {
  2327.                 _inventory.sshotInUse = true;
  2328.                 broadcastPacket(new MagicSkillUser(this, this, 2039, 1, 0, 0)); // no grade
  2329.                 return true;
  2330.             }
  2331.             else
  2332.                 _inventory.sshotInUse = false;
  2333.         }
  2334.         return false;
  2335.     }
  2336.  
  2337.     public boolean isUsingShot(boolean physical)
  2338.     {
  2339.         if (_inventory == null)
  2340.             return false;
  2341.  
  2342.         if (physical && _inventory.sshotInUse)
  2343.             return true;
  2344.  
  2345.         if (!physical && _inventory.bshotInUse)
  2346.             return true;
  2347.  
  2348.         return false;
  2349.     }
  2350. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement