Chests.java 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation, either version 3 of the License, or (at your option) any later
  5. * version.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT
  8. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. * details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with
  13. * this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package ai.group_template;
  16. import com.l2jserver.gameserver.ai.CtrlIntention;
  17. import com.l2jserver.gameserver.model.L2Object;
  18. import com.l2jserver.gameserver.model.L2Skill;
  19. import com.l2jserver.gameserver.model.actor.L2Character;
  20. import com.l2jserver.gameserver.model.actor.L2Npc;
  21. import com.l2jserver.gameserver.model.actor.instance.L2ChestInstance;
  22. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  23. import com.l2jserver.gameserver.util.Util;
  24. import com.l2jserver.util.Rnd;
  25. /**
  26. * Chest AI implementation.
  27. * @author Fulminus
  28. */
  29. public class Chests extends L2AttackableAIScript
  30. {
  31. private static final int SKILL_DELUXE_KEY = 2229;
  32. //Base chance for BOX to be opened
  33. private static final int BASE_CHANCE = 100;
  34. // Percent to decrease base chance when grade of DELUXE key not match
  35. private static final int LEVEL_DECREASE = 40;
  36. // Chance for a chest to actually be a BOX (as opposed to being a mimic).
  37. private static final int IS_BOX = 40;
  38. private static final int[] NPC_IDS = { 18265,18266,18267,18268,18269,18270,18271,
  39. 18272,18273,18274,18275,18276,18277,18278,18279,18280,18281,
  40. 18282,18283,18284,18285,18286,18287,18288,18289,18290,18291,
  41. 18292,18293,18294,18295,18296,18297,18298,21671,21694,21717,
  42. 21740,21763,21786,21801,21802,21803,21804,21805,21806,21807,
  43. 21808,21809,21810,21811,21812,21813,21814,21815,21816,21817,
  44. 21818,21819,21820,21821,21822 };
  45. public Chests(int questId, String name, String descr)
  46. {
  47. // firstly, don't forget to call the parent constructor to prepare the event triggering
  48. // mechanisms etc.
  49. super(questId, name, descr);
  50. this.registerMobs(NPC_IDS, QuestEventType.ON_ATTACK, QuestEventType.ON_SKILL_SEE);
  51. }
  52. @Override
  53. public String onSkillSee (L2Npc npc, L2PcInstance caster, L2Skill skill, L2Object[] targets, boolean isPet)
  54. {
  55. if (npc instanceof L2ChestInstance)
  56. {
  57. // this behavior is only run when the target of skill is the passed npc (chest)
  58. // i.e. when the player is attempting to open the chest using a skill
  59. if (!Util.contains(targets,npc))
  60. {
  61. return super.onSkillSee(npc,caster,skill,targets,isPet);
  62. }
  63. L2ChestInstance chest = ((L2ChestInstance)npc);
  64. int npcId = chest.getNpcId();
  65. int skillId = skill.getId();
  66. int skillLevel= skill.getLevel();
  67. // check if the chest and skills used are valid for this script. Exit if invalid.
  68. if (!Util.contains(NPC_IDS,npcId))
  69. {
  70. return super.onSkillSee(npc,caster,skill,targets,isPet);
  71. }
  72. // if this has already been interacted, no further ai decisions are needed
  73. // if it's the first interaction, check if this is a box or mimic
  74. if (!chest.isInteracted())
  75. {
  76. chest.setInteracted();
  77. if (Rnd.get(100) < IS_BOX)
  78. {
  79. // if it's a box, either it will be successfully openned by a proper key, or instantly disappear
  80. if (skillId == SKILL_DELUXE_KEY)
  81. {
  82. // check the chance to open the box
  83. int keyLevelNeeded = chest.getLevel()/10;
  84. keyLevelNeeded -= skillLevel;
  85. if (keyLevelNeeded < 0)
  86. keyLevelNeeded *= -1;
  87. int chance = BASE_CHANCE - keyLevelNeeded * LEVEL_DECREASE;
  88. // success, pretend-death with rewards: chest.reduceCurrentHp(99999999, player)
  89. if (Rnd.get(100) < chance)
  90. {
  91. chest.setMustRewardExpSp(false);
  92. chest.setSpecialDrop();
  93. chest.reduceCurrentHp(99999999, caster, null);
  94. return null;
  95. }
  96. }
  97. // used a skill other than chest-key, or used a chest-key but failed to open: disappear with no rewards
  98. chest.deleteMe();
  99. }
  100. else
  101. {
  102. L2Character originalCaster = isPet? caster.getPet(): caster;
  103. chest.setRunning();
  104. chest.addDamageHate(originalCaster,0,999);
  105. chest.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, originalCaster);
  106. }
  107. }
  108. }
  109. return super.onSkillSee(npc,caster,skill,targets,isPet);
  110. }
  111. @Override
  112. public String onAttack (L2Npc npc, L2PcInstance attacker, int damage, boolean isPet)
  113. {
  114. if (npc instanceof L2ChestInstance)
  115. {
  116. L2ChestInstance chest = ((L2ChestInstance)npc);
  117. int npcId = chest.getNpcId();
  118. // check if the chest and skills used are valid for this script. Exit if invalid.
  119. if (!Util.contains(NPC_IDS, npcId))
  120. {
  121. return super.onAttack(npc,attacker,damage,isPet);
  122. }
  123. // if this was a mimic, set the target, start the skills and become agro
  124. if (!chest.isInteracted())
  125. {
  126. chest.setInteracted();
  127. if (Rnd.get(100) < IS_BOX)
  128. {
  129. chest.deleteMe();
  130. }
  131. else
  132. {
  133. // if this weren't a box, upon interaction start the mimic behaviors...
  134. // todo: perhaps a self-buff (skill id 4245) with random chance goes here?
  135. L2Character originalAttacker = isPet? attacker.getPet(): attacker;
  136. chest.setRunning();
  137. chest.addDamageHate(originalAttacker,0,(damage*100)/(chest.getLevel()+7));
  138. chest.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, originalAttacker);
  139. }
  140. }
  141. }
  142. return super.onAttack(npc,attacker,damage,isPet);
  143. }
  144. public static void main(String[] args)
  145. {
  146. // now call the constructor (starts up the ai)
  147. new Chests(-1,"chests","ai");
  148. }
  149. }