L2Weapon.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  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 _itemSkill = null; // for passive skill
  56. private L2Skill _enchant4Skill = null; // skill that activates when item is enchanted +4 (for duals)
  57. private final int _changeWeaponId;
  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. int sId = set.getInteger("item_skill_id");
  93. int sLv = set.getInteger("item_skill_lvl");
  94. if(sId > 0 && sLv > 0)
  95. _itemSkill = SkillTable.getInstance().getInfo(sId,sLv);
  96. sId = set.getInteger("enchant4_skill_id");
  97. sLv = set.getInteger("enchant4_skill_lvl");
  98. if(sId > 0 && sLv > 0)
  99. _enchant4Skill = SkillTable.getInstance().getInfo(sId, sLv);
  100. sId = set.getInteger("onCast_skill_id");
  101. sLv = set.getInteger("onCast_skill_lvl");
  102. int sCh = set.getInteger("onCast_skill_chance");
  103. if(sId > 0 && sLv > 0 && sCh > 0)
  104. {
  105. L2Skill skill = SkillTable.getInstance().getInfo(sId, sLv);
  106. skill.attach(new ConditionGameChance(sCh),true);
  107. attachOnCast(skill);
  108. }
  109. sId = set.getInteger("onCrit_skill_id");
  110. sLv = set.getInteger("onCrit_skill_lvl");
  111. sCh = set.getInteger("onCrit_skill_chance");
  112. if(sId > 0 && sLv > 0 && sCh > 0)
  113. {
  114. L2Skill skill = SkillTable.getInstance().getInfo(sId, sLv);
  115. skill.attach(new ConditionGameChance(sCh),true);
  116. attachOnCrit(skill);
  117. }
  118. _changeWeaponId = set.getInteger("change_weaponId");
  119. }
  120. /**
  121. * Returns the type of Weapon
  122. * @return L2WeaponType
  123. */
  124. @Override
  125. public L2WeaponType getItemType()
  126. {
  127. return (L2WeaponType)super._type;
  128. }
  129. /**
  130. * Returns the ID of the Etc item after applying the mask.
  131. * @return int : ID of the Weapon
  132. */
  133. @Override
  134. public int getItemMask()
  135. {
  136. return getItemType().mask();
  137. }
  138. /**
  139. * Returns the quantity of SoulShot used.
  140. * @return int
  141. */
  142. public int getSoulShotCount()
  143. {
  144. return _soulShotCount;
  145. }
  146. /**
  147. * Returns the quatity of SpiritShot used.
  148. * @return int
  149. */
  150. public int getSpiritShotCount()
  151. {
  152. return _spiritShotCount;
  153. }
  154. /**
  155. * Returns the physical damage.
  156. * @return int
  157. */
  158. public int getPDamage()
  159. {
  160. return _pDam;
  161. }
  162. /**
  163. * Returns the random damage inflicted by the weapon
  164. * @return int
  165. */
  166. public int getRandomDamage()
  167. {
  168. return _rndDam;
  169. }
  170. /**
  171. * Returns the attack speed of the weapon
  172. * @return int
  173. */
  174. public int getAttackSpeed()
  175. {
  176. return _atkSpeed;
  177. }
  178. /**
  179. * Return the Attack Reuse Delay of the L2Weapon.<BR><BR>
  180. * @return int
  181. */
  182. public int getAttackReuseDelay()
  183. {
  184. return _atkReuse;
  185. }
  186. /**
  187. * Returns the avoid modifier of the weapon
  188. * @return int
  189. */
  190. public int getAvoidModifier()
  191. {
  192. return _avoidModifier;
  193. }
  194. /**
  195. * Returns the rate of critical hit
  196. * @return int
  197. */
  198. public int getCritical()
  199. {
  200. return _critical;
  201. }
  202. /**
  203. * Returns the hit modifier of the weapon
  204. * @return double
  205. */
  206. public double getHitModifier()
  207. {
  208. return _hitModifier;
  209. }
  210. /**
  211. * Returns the magical damage inflicted by the weapon
  212. * @return int
  213. */
  214. public int getMDamage()
  215. {
  216. return _mDam;
  217. }
  218. /**
  219. * Returns the MP consumption with the weapon
  220. * @return int
  221. */
  222. public int getMpConsume()
  223. {
  224. return _mpConsume;
  225. }
  226. /**
  227. * Returns the shield defense of the weapon
  228. * @return int
  229. */
  230. public int getShieldDef()
  231. {
  232. return _shieldDef;
  233. }
  234. /**
  235. * Returns the rate of shield defense of the weapon
  236. * @return double
  237. */
  238. public double getShieldDefRate()
  239. {
  240. return _shieldDefRate;
  241. }
  242. /**
  243. * Returns passive skill linked to that weapon
  244. * @return
  245. */
  246. public L2Skill getSkill()
  247. {
  248. return _itemSkill;
  249. }
  250. /**
  251. * Returns skill that player get when has equiped weapon +4 or more (for duals SA)
  252. * @return
  253. */
  254. public L2Skill getEnchant4Skill()
  255. {
  256. return _enchant4Skill;
  257. }
  258. /**
  259. * Returns the Id in wich weapon this weapon can be changed
  260. * @return
  261. */
  262. public int getChangeWeaponId()
  263. {
  264. return _changeWeaponId;
  265. }
  266. /**
  267. * Returns array of Func objects containing the list of functions used by the weapon
  268. * @param instance : L2ItemInstance pointing out the weapon
  269. * @param player : L2Character pointing out the player
  270. * @return Func[] : array of functions
  271. */
  272. @Override
  273. public Func[] getStatFuncs(L2ItemInstance instance, L2Character player)
  274. {
  275. List<Func> funcs = new FastList<Func>();
  276. if (_funcTemplates != null)
  277. {
  278. for (FuncTemplate t : _funcTemplates) {
  279. Env env = new Env();
  280. env.player = player;
  281. env.item = instance;
  282. Func f = t.getFunc(env, instance);
  283. if (f != null)
  284. funcs.add(f);
  285. }
  286. }
  287. return funcs.toArray(new Func[funcs.size()]);
  288. }
  289. /**
  290. * Returns effects of skills associated with the item to be triggered onHit.
  291. * @param caster : L2Character pointing out the caster
  292. * @param target : L2Character pointing out the target
  293. * @param crit : boolean tells whether the hit was critical
  294. * @return L2Effect[] : array of effects generated by the skill
  295. */
  296. public L2Effect[] getSkillEffects(L2Character caster, L2Character target, boolean crit)
  297. {
  298. if (_skillsOnCrit == null || !crit)
  299. return _emptyEffectSet;
  300. List<L2Effect> effects = new FastList<L2Effect>();
  301. for (L2Skill skill : _skillsOnCrit)
  302. {
  303. if (target.isRaid() && (skill.getSkillType() == SkillType.CONFUSION || skill.getSkillType() == SkillType.MUTE || skill.getSkillType() == SkillType.PARALYZE || skill.getSkillType() == SkillType.ROOT))
  304. continue; // These skills should not work on RaidBoss
  305. if (!skill.checkCondition(caster, target, true))
  306. continue; // Skill condition not met
  307. if (target.getFirstEffect(skill.getId()) != null)
  308. target.getFirstEffect(skill.getId()).exit();
  309. for (L2Effect e:skill.getEffects(caster, target))
  310. effects.add(e);
  311. }
  312. if (effects.size() == 0)
  313. return _emptyEffectSet;
  314. return effects.toArray(new L2Effect[effects.size()]);
  315. }
  316. /**
  317. * Returns effects of skills associated with the item to be triggered onCast.
  318. * @param caster : L2Character pointing out the caster
  319. * @param target : L2Character pointing out the target
  320. * @param trigger : L2Skill pointing out the skill triggering this action
  321. * @return L2Effect[] : array of effects generated by the skill
  322. */
  323. public L2Effect[] getSkillEffects(L2Character caster, L2Character target, L2Skill trigger)
  324. {
  325. if (_skillsOnCast == null)
  326. return _emptyEffectSet;
  327. List<L2Effect> effects = new FastList<L2Effect>();
  328. for (L2Skill skill : _skillsOnCast)
  329. {
  330. if (trigger.isOffensive() != skill.isOffensive())
  331. continue; // Trigger only same type of skill
  332. if (target.isRaid() && (skill.getSkillType() == SkillType.CONFUSION || skill.getSkillType() == SkillType.MUTE || skill.getSkillType() == SkillType.PARALYZE || skill.getSkillType() == SkillType.ROOT))
  333. continue; // These skills should not work on RaidBoss
  334. if (trigger.isToggle() && skill.getSkillType() == SkillType.BUFF)
  335. continue; // No buffing with toggle skills
  336. if (!skill.checkCondition(caster, target, true))
  337. continue; // Skill condition not met
  338. try
  339. {
  340. // Get the skill handler corresponding to the skill type
  341. ISkillHandler handler = SkillHandler.getInstance().getSkillHandler(skill.getSkillType());
  342. L2Character[] targets = new L2Character[1];
  343. targets[0] = target;
  344. // Launch the magic skill and calculate its effects
  345. if (handler != null)
  346. handler.useSkill(caster, skill, targets);
  347. else
  348. skill.useSkill(caster, targets);
  349. // notify quests of a skill use
  350. if (caster instanceof L2PcInstance)
  351. {
  352. // Mobs in range 1000 see spell
  353. for (L2Object spMob : caster.getKnownList().getKnownObjects().values())
  354. {
  355. if (spMob instanceof L2NpcInstance)
  356. {
  357. L2NpcInstance npcMob = (L2NpcInstance) spMob;
  358. if (npcMob.getTemplate().getEventQuests(Quest.QuestEventType.ON_SKILL_SEE) !=null)
  359. for (Quest quest: npcMob.getTemplate().getEventQuests(Quest.QuestEventType.ON_SKILL_SEE))
  360. quest.notifySkillSee(npcMob, (L2PcInstance) caster, skill, targets, false);
  361. }
  362. }
  363. }
  364. }
  365. catch (IOException e)
  366. {
  367. }
  368. }
  369. if (effects.size() == 0)
  370. return _emptyEffectSet;
  371. return effects.toArray(new L2Effect[effects.size()]);
  372. }
  373. /**
  374. * Add the L2Skill skill to the list of skills generated by the item triggered by critical hit
  375. * @param skill : L2Skill
  376. */
  377. public void attachOnCrit(L2Skill skill)
  378. {
  379. if (_skillsOnCrit == null)
  380. {
  381. _skillsOnCrit = new L2Skill[]{skill};
  382. }
  383. else
  384. {
  385. int len = _skillsOnCrit.length;
  386. L2Skill[] tmp = new L2Skill[len+1];
  387. // Definition : arraycopy(array source, begins copy at this position of source, array destination, begins copy at this position in dest,
  388. // number of components to be copied)
  389. System.arraycopy(_skillsOnCrit, 0, tmp, 0, len);
  390. tmp[len] = skill;
  391. _skillsOnCrit = tmp;
  392. }
  393. }
  394. /**
  395. * Add the L2Skill skill to the list of skills generated by the item triggered by casting spell
  396. * @param skill : L2Skill
  397. */
  398. public void attachOnCast(L2Skill skill)
  399. {
  400. if (_skillsOnCast == null)
  401. {
  402. _skillsOnCast = new L2Skill[]{skill};
  403. }
  404. else
  405. {
  406. int len = _skillsOnCast.length;
  407. L2Skill[] tmp = new L2Skill[len+1];
  408. // Definition : arraycopy(array source, begins copy at this position of source, array destination, begins copy at this position in dest,
  409. // number of components to be copied)
  410. System.arraycopy(_skillsOnCast, 0, tmp, 0, len);
  411. tmp[len] = skill;
  412. _skillsOnCast = tmp;
  413. }
  414. }
  415. }