L2Weapon.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /*
  2. * This program is free software: you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation, either version 3 of the License, or (at your option) any later
  5. * version.
  6. *
  7. * This program is distributed in the hope that it will be useful, but WITHOUT
  8. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  10. * details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with
  13. * this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. package net.sf.l2j.gameserver.templates;
  16. import java.io.IOException;
  17. import java.util.List;
  18. import javolution.util.FastList;
  19. import net.sf.l2j.gameserver.datatables.SkillTable;
  20. import net.sf.l2j.gameserver.handler.ISkillHandler;
  21. import net.sf.l2j.gameserver.handler.SkillHandler;
  22. import net.sf.l2j.gameserver.model.L2Character;
  23. import net.sf.l2j.gameserver.model.L2Effect;
  24. import net.sf.l2j.gameserver.model.L2ItemInstance;
  25. import net.sf.l2j.gameserver.model.L2Object;
  26. import net.sf.l2j.gameserver.model.L2Skill;
  27. import net.sf.l2j.gameserver.model.L2Skill.SkillType;
  28. import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance;
  29. import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
  30. import net.sf.l2j.gameserver.model.quest.Quest;
  31. import net.sf.l2j.gameserver.skills.Env;
  32. import net.sf.l2j.gameserver.skills.conditions.ConditionGameChance;
  33. import net.sf.l2j.gameserver.skills.funcs.Func;
  34. import net.sf.l2j.gameserver.skills.funcs.FuncTemplate;
  35. /**
  36. * This class is dedicated to the management of weapons.
  37. *
  38. * @version $Revision: 1.4.2.3.2.5 $ $Date: 2005/04/02 15:57:51 $
  39. */
  40. public final class L2Weapon extends L2Item
  41. {
  42. private final int _soulShotCount;
  43. private final int _spiritShotCount;
  44. private final int _pDam;
  45. private final int _rndDam;
  46. private final int _critical;
  47. private final double _hitModifier;
  48. private final int _avoidModifier;
  49. private final int _shieldDef;
  50. private final double _shieldDefRate;
  51. private final int _atkSpeed;
  52. private final int _atkReuse;
  53. private final int _mpConsume;
  54. private final int _mDam;
  55. private L2Skill _enchant4Skill = null; // skill that activates when item is enchanted +4 (for duals)
  56. private final int _changeWeaponId;
  57. private final String[] _skill;
  58. // Attached skills for Special Abilities
  59. protected L2Skill[] _skillsOnCast;
  60. protected L2Skill[] _skillsOnCrit;
  61. /**
  62. * Constructor for Weapon.<BR><BR>
  63. * <U><I>Variables filled :</I></U><BR>
  64. * <LI>_soulShotCount & _spiritShotCount</LI>
  65. * <LI>_pDam & _mDam & _rndDam</LI>
  66. * <LI>_critical</LI>
  67. * <LI>_hitModifier</LI>
  68. * <LI>_avoidModifier</LI>
  69. * <LI>_shieldDes & _shieldDefRate</LI>
  70. * <LI>_atkSpeed & _AtkReuse</LI>
  71. * <LI>_mpConsume</LI>
  72. * @param type : L2ArmorType designating the type of armor
  73. * @param set : StatsSet designating the set of couples (key,value) caracterizing the armor
  74. * @see L2Item constructor
  75. */
  76. public L2Weapon(L2WeaponType type, StatsSet set)
  77. {
  78. super(type, set);
  79. _soulShotCount = set.getInteger("soulshots");
  80. _spiritShotCount = set.getInteger("spiritshots");
  81. _pDam = set.getInteger("p_dam");
  82. _rndDam = set.getInteger("rnd_dam");
  83. _critical = set.getInteger("critical");
  84. _hitModifier = set.getDouble("hit_modify");
  85. _avoidModifier = set.getInteger("avoid_modify");
  86. _shieldDef = set.getInteger("shield_def");
  87. _shieldDefRate = set.getDouble("shield_def_rate");
  88. _atkSpeed = set.getInteger("atk_speed");
  89. _atkReuse = set.getInteger("atk_reuse", (type==L2WeaponType.BOW) ? 1500 : (type==L2WeaponType.CROSSBOW) ? 1200 : 0);
  90. _mpConsume = set.getInteger("mp_consume");
  91. _mDam = set.getInteger("m_dam");
  92. _skill = set.getString("skill").split(";");
  93. int sId = set.getInteger("enchant4_skill_id");
  94. int sLv = set.getInteger("enchant4_skill_lvl");
  95. if(sId > 0 && sLv > 0)
  96. _enchant4Skill = SkillTable.getInstance().getInfo(sId, sLv);
  97. sId = set.getInteger("onCast_skill_id");
  98. sLv = set.getInteger("onCast_skill_lvl");
  99. int sCh = set.getInteger("onCast_skill_chance");
  100. if(sId > 0 && sLv > 0 && sCh > 0)
  101. {
  102. L2Skill skill = SkillTable.getInstance().getInfo(sId, sLv);
  103. skill.attach(new ConditionGameChance(sCh),true);
  104. attachOnCast(skill);
  105. }
  106. sId = set.getInteger("onCrit_skill_id");
  107. sLv = set.getInteger("onCrit_skill_lvl");
  108. sCh = set.getInteger("onCrit_skill_chance");
  109. if(sId > 0 && sLv > 0 && sCh > 0)
  110. {
  111. L2Skill skill = SkillTable.getInstance().getInfo(sId, sLv);
  112. skill.attach(new ConditionGameChance(sCh),true);
  113. attachOnCrit(skill);
  114. }
  115. _changeWeaponId = set.getInteger("change_weaponId");
  116. }
  117. /**
  118. * Returns the type of Weapon
  119. * @return L2WeaponType
  120. */
  121. @Override
  122. public L2WeaponType getItemType()
  123. {
  124. return (L2WeaponType)super._type;
  125. }
  126. /**
  127. * Returns the ID of the Etc item after applying the mask.
  128. * @return int : ID of the Weapon
  129. */
  130. @Override
  131. public int getItemMask()
  132. {
  133. return getItemType().mask();
  134. }
  135. /**
  136. * Returns the quantity of SoulShot used.
  137. * @return int
  138. */
  139. public int getSoulShotCount()
  140. {
  141. return _soulShotCount;
  142. }
  143. /**
  144. * Returns the quatity of SpiritShot used.
  145. * @return int
  146. */
  147. public int getSpiritShotCount()
  148. {
  149. return _spiritShotCount;
  150. }
  151. /**
  152. * Returns the physical damage.
  153. * @return int
  154. */
  155. public int getPDamage()
  156. {
  157. return _pDam;
  158. }
  159. /**
  160. * Returns the random damage inflicted by the weapon
  161. * @return int
  162. */
  163. public int getRandomDamage()
  164. {
  165. return _rndDam;
  166. }
  167. /**
  168. * Returns the attack speed of the weapon
  169. * @return int
  170. */
  171. public int getAttackSpeed()
  172. {
  173. return _atkSpeed;
  174. }
  175. /**
  176. * Return the Attack Reuse Delay of the L2Weapon.<BR><BR>
  177. * @return int
  178. */
  179. public int getAttackReuseDelay()
  180. {
  181. return _atkReuse;
  182. }
  183. /**
  184. * Returns the avoid modifier of the weapon
  185. * @return int
  186. */
  187. public int getAvoidModifier()
  188. {
  189. return _avoidModifier;
  190. }
  191. /**
  192. * Returns the rate of critical hit
  193. * @return int
  194. */
  195. public int getCritical()
  196. {
  197. return _critical;
  198. }
  199. /**
  200. * Returns the hit modifier of the weapon
  201. * @return double
  202. */
  203. public double getHitModifier()
  204. {
  205. return _hitModifier;
  206. }
  207. /**
  208. * Returns the magical damage inflicted by the weapon
  209. * @return int
  210. */
  211. public int getMDamage()
  212. {
  213. return _mDam;
  214. }
  215. /**
  216. * Returns the MP consumption with the weapon
  217. * @return int
  218. */
  219. public int getMpConsume()
  220. {
  221. return _mpConsume;
  222. }
  223. /**
  224. * Returns the shield defense of the weapon
  225. * @return int
  226. */
  227. public int getShieldDef()
  228. {
  229. return _shieldDef;
  230. }
  231. /**
  232. * Returns the rate of shield defense of the weapon
  233. * @return double
  234. */
  235. public double getShieldDefRate()
  236. {
  237. return _shieldDefRate;
  238. }
  239. /**
  240. * Returns passive skill linked to that weapon
  241. * @return
  242. */
  243. public String[] getSkills()
  244. {
  245. return _skill;
  246. }
  247. /**
  248. * Returns skill that player get when has equiped weapon +4 or more (for duals SA)
  249. * @return
  250. */
  251. public L2Skill getEnchant4Skill()
  252. {
  253. return _enchant4Skill;
  254. }
  255. /**
  256. * Returns the Id in wich weapon this weapon can be changed
  257. * @return
  258. */
  259. public int getChangeWeaponId()
  260. {
  261. return _changeWeaponId;
  262. }
  263. /**
  264. * Returns array of Func objects containing the list of functions used by the weapon
  265. * @param instance : L2ItemInstance pointing out the weapon
  266. * @param player : L2Character pointing out the player
  267. * @return Func[] : array of functions
  268. */
  269. @Override
  270. public Func[] getStatFuncs(L2ItemInstance instance, L2Character player)
  271. {
  272. List<Func> funcs = new FastList<Func>();
  273. if (_funcTemplates != null)
  274. {
  275. for (FuncTemplate t : _funcTemplates) {
  276. Env env = new Env();
  277. env.player = player;
  278. env.item = instance;
  279. Func f = t.getFunc(env, instance);
  280. if (f != null)
  281. funcs.add(f);
  282. }
  283. }
  284. return funcs.toArray(new Func[funcs.size()]);
  285. }
  286. /**
  287. * Returns effects of skills associated with the item to be triggered onHit.
  288. * @param caster : L2Character pointing out the caster
  289. * @param target : L2Character pointing out the target
  290. * @param crit : boolean tells whether the hit was critical
  291. * @return L2Effect[] : array of effects generated by the skill
  292. */
  293. public L2Effect[] getSkillEffects(L2Character caster, L2Character target, boolean crit)
  294. {
  295. if (_skillsOnCrit == null || !crit)
  296. return _emptyEffectSet;
  297. List<L2Effect> effects = new FastList<L2Effect>();
  298. for (L2Skill skill : _skillsOnCrit)
  299. {
  300. if (target.isRaid() && (skill.getSkillType() == SkillType.CONFUSION || skill.getSkillType() == SkillType.MUTE || skill.getSkillType() == SkillType.PARALYZE || skill.getSkillType() == SkillType.ROOT))
  301. continue; // These skills should not work on RaidBoss
  302. if (!skill.checkCondition(caster, target, true))
  303. continue; // Skill condition not met
  304. if (target.getFirstEffect(skill.getId()) != null)
  305. target.getFirstEffect(skill.getId()).exit();
  306. for (L2Effect e:skill.getEffects(caster, target))
  307. effects.add(e);
  308. }
  309. if (effects.size() == 0)
  310. return _emptyEffectSet;
  311. return effects.toArray(new L2Effect[effects.size()]);
  312. }
  313. /**
  314. * Returns effects of skills associated with the item to be triggered onCast.
  315. * @param caster : L2Character pointing out the caster
  316. * @param target : L2Character pointing out the target
  317. * @param trigger : L2Skill pointing out the skill triggering this action
  318. * @return L2Effect[] : array of effects generated by the skill
  319. */
  320. public L2Effect[] getSkillEffects(L2Character caster, L2Character target, L2Skill trigger)
  321. {
  322. if (_skillsOnCast == null)
  323. return _emptyEffectSet;
  324. List<L2Effect> effects = new FastList<L2Effect>();
  325. for (L2Skill skill : _skillsOnCast)
  326. {
  327. if (trigger.isOffensive() != skill.isOffensive())
  328. continue; // Trigger only same type of skill
  329. if (target.isRaid() && (skill.getSkillType() == SkillType.CONFUSION || skill.getSkillType() == SkillType.MUTE || skill.getSkillType() == SkillType.PARALYZE || skill.getSkillType() == SkillType.ROOT))
  330. continue; // These skills should not work on RaidBoss
  331. if (trigger.isToggle() && skill.getSkillType() == SkillType.BUFF)
  332. continue; // No buffing with toggle skills
  333. if (!skill.checkCondition(caster, target, true))
  334. continue; // Skill condition not met
  335. try
  336. {
  337. // Get the skill handler corresponding to the skill type
  338. ISkillHandler handler = SkillHandler.getInstance().getSkillHandler(skill.getSkillType());
  339. L2Character[] targets = new L2Character[1];
  340. targets[0] = target;
  341. // Launch the magic skill and calculate its effects
  342. if (handler != null)
  343. handler.useSkill(caster, skill, targets);
  344. else
  345. skill.useSkill(caster, targets);
  346. // notify quests of a skill use
  347. if (caster instanceof L2PcInstance)
  348. {
  349. // Mobs in range 1000 see spell
  350. for (L2Object spMob : caster.getKnownList().getKnownObjects().values())
  351. {
  352. if (spMob instanceof L2NpcInstance)
  353. {
  354. L2NpcInstance npcMob = (L2NpcInstance) spMob;
  355. if (npcMob.getTemplate().getEventQuests(Quest.QuestEventType.ON_SKILL_SEE) !=null)
  356. for (Quest quest: npcMob.getTemplate().getEventQuests(Quest.QuestEventType.ON_SKILL_SEE))
  357. quest.notifySkillSee(npcMob, (L2PcInstance) caster, skill, targets, false);
  358. }
  359. }
  360. }
  361. }
  362. catch (IOException e)
  363. {
  364. }
  365. }
  366. if (effects.size() == 0)
  367. return _emptyEffectSet;
  368. return effects.toArray(new L2Effect[effects.size()]);
  369. }
  370. /**
  371. * Add the L2Skill skill to the list of skills generated by the item triggered by critical hit
  372. * @param skill : L2Skill
  373. */
  374. public void attachOnCrit(L2Skill skill)
  375. {
  376. if (_skillsOnCrit == null)
  377. {
  378. _skillsOnCrit = new L2Skill[]{skill};
  379. }
  380. else
  381. {
  382. int len = _skillsOnCrit.length;
  383. L2Skill[] tmp = new L2Skill[len+1];
  384. // Definition : arraycopy(array source, begins copy at this position of source, array destination, begins copy at this position in dest,
  385. // number of components to be copied)
  386. System.arraycopy(_skillsOnCrit, 0, tmp, 0, len);
  387. tmp[len] = skill;
  388. _skillsOnCrit = tmp;
  389. }
  390. }
  391. /**
  392. * Add the L2Skill skill to the list of skills generated by the item triggered by casting spell
  393. * @param skill : L2Skill
  394. */
  395. public void attachOnCast(L2Skill skill)
  396. {
  397. if (_skillsOnCast == null)
  398. {
  399. _skillsOnCast = new L2Skill[]{skill};
  400. }
  401. else
  402. {
  403. int len = _skillsOnCast.length;
  404. L2Skill[] tmp = new L2Skill[len+1];
  405. // Definition : arraycopy(array source, begins copy at this position of source, array destination, begins copy at this position in dest,
  406. // number of components to be copied)
  407. System.arraycopy(_skillsOnCast, 0, tmp, 0, len);
  408. tmp[len] = skill;
  409. _skillsOnCast = tmp;
  410. }
  411. }
  412. }