Potions.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  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.handler.itemhandlers;
  16. import java.util.logging.Logger;
  17. import net.sf.l2j.gameserver.datatables.SkillTable;
  18. import net.sf.l2j.gameserver.handler.IItemHandler;
  19. import net.sf.l2j.gameserver.model.L2Effect;
  20. import net.sf.l2j.gameserver.model.L2ItemInstance;
  21. import net.sf.l2j.gameserver.model.L2Skill;
  22. import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
  23. import net.sf.l2j.gameserver.model.actor.instance.L2PetInstance;
  24. import net.sf.l2j.gameserver.model.actor.instance.L2PlayableInstance;
  25. import net.sf.l2j.gameserver.model.actor.instance.L2SummonInstance;
  26. import net.sf.l2j.gameserver.model.entity.TvTEvent;
  27. import net.sf.l2j.gameserver.network.SystemMessageId;
  28. import net.sf.l2j.gameserver.network.serverpackets.ActionFailed;
  29. import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
  30. import net.sf.l2j.gameserver.templates.skills.L2EffectType;
  31. /**
  32. * This class ...
  33. *
  34. * @version $Revision: 1.2.4.4 $ $Date: 2005/03/27 15:30:07 $
  35. */
  36. public class Potions implements IItemHandler
  37. {
  38. protected static final Logger _log = Logger.getLogger(Potions.class.getName());
  39. private static final int[] ITEM_IDS =
  40. {
  41. 65, 725, 726, 727, 728, 734, 735, 1060, 1061, 1073,
  42. 1374, 1375, 1539, 1540, 5591, 5592, 6035, 6036,
  43. 6652, 6553, 6554, 6555, 8193, 8194, 8195, 8196,
  44. 8197, 8198, 8199, 8200, 8201, 8202, 8600, 8601,
  45. 8602, 8603, 8604, 8605, 8606, 8607,
  46. 8608, 8609, 8610, 8611, 8612, 8613, 8614, 10155, 10157,
  47. //Attribute Potion
  48. 9997, 9998, 9999, 10000, 10001, 10002,
  49. //elixir of life
  50. 8622, 8623, 8624, 8625, 8626, 8627,
  51. //elixir of Strength
  52. 8628, 8629, 8630, 8631, 8632, 8633,
  53. //elixir of cp
  54. 8634, 8635, 8636, 8637, 8638, 8639,
  55. // Endeavor Potion
  56. 733,
  57. // Juices
  58. 10260, 10261, 10262, 10263, 10264, 10265, 10266, 10267, 10268, 10269, 10270,
  59. // CT2 herbs
  60. 10655, 10656, 10657
  61. };
  62. /**
  63. *
  64. * @see net.sf.l2j.gameserver.handler.IItemHandler#useItem(net.sf.l2j.gameserver.model.actor.instance.L2PlayableInstance, net.sf.l2j.gameserver.model.L2ItemInstance)
  65. */
  66. public synchronized void useItem(L2PlayableInstance playable, L2ItemInstance item)
  67. {
  68. L2PcInstance activeChar;
  69. boolean res = false;
  70. if (playable instanceof L2PcInstance)
  71. activeChar = (L2PcInstance) playable;
  72. else if (playable instanceof L2PetInstance)
  73. activeChar = ((L2PetInstance) playable).getOwner();
  74. else
  75. return;
  76. if (!TvTEvent.onPotionUse(playable.getObjectId()))
  77. {
  78. playable.sendPacket(ActionFailed.STATIC_PACKET);
  79. return;
  80. }
  81. if (activeChar.isInOlympiadMode())
  82. {
  83. activeChar.sendPacket(new SystemMessage(SystemMessageId.THIS_ITEM_IS_NOT_AVAILABLE_FOR_THE_OLYMPIAD_EVENT));
  84. return;
  85. }
  86. if (activeChar.isAllSkillsDisabled())
  87. {
  88. ActionFailed af = ActionFailed.STATIC_PACKET;
  89. activeChar.sendPacket(af);
  90. return;
  91. }
  92. int itemId = item.getItemId();
  93. switch (itemId)
  94. {
  95. // HEALING AND SPEED POTIONS
  96. case 65: // red_potion, xml: 2001
  97. res = usePotion(activeChar, 2001, 1);
  98. break;
  99. case 725: // healing_drug, xml: 2002
  100. if (!isEffectReplaceable(activeChar, L2EffectType.HEAL_OVER_TIME, itemId))
  101. return;
  102. res = usePotion(activeChar, 2002, 1);
  103. break;
  104. case 727: // _healing_potion, xml: 2032
  105. if (!isEffectReplaceable(activeChar, L2EffectType.HEAL_OVER_TIME, itemId))
  106. return;
  107. res = usePotion(activeChar, 2032, 1);
  108. break;
  109. case 733: // Endeavor Potion, xml: 2010
  110. res = usePotion(activeChar, 2010, 1);
  111. break;
  112. case 734: // quick_step_potion, xml: 2011
  113. res = usePotion(activeChar, 2011, 1);
  114. break;
  115. case 735: // swift_attack_potion, xml: 2012
  116. res = usePotion(activeChar, 2012, 1);
  117. break;
  118. case 1060: // lesser_healing_potion,
  119. case 1073: // beginner's potion, xml: 2031
  120. if (!isEffectReplaceable(activeChar, L2EffectType.HEAL_OVER_TIME, itemId))
  121. return;
  122. res = usePotion(activeChar, 2031, 1);
  123. break;
  124. case 1061: // healing_potion, xml: 2032
  125. if (!isEffectReplaceable(activeChar, L2EffectType.HEAL_OVER_TIME, itemId))
  126. return;
  127. res = usePotion(activeChar, 2032, 1);
  128. break;
  129. case 10157: // instant haste_potion, xml: 2398
  130. res = usePotion(activeChar, 2398, 1);
  131. break;
  132. case 1374: // adv_quick_step_potion, xml: 2034
  133. res = usePotion(activeChar, 2034, 1);
  134. break;
  135. case 1375: // adv_swift_attack_potion, xml: 2035
  136. res = usePotion(activeChar, 2035, 1);
  137. break;
  138. case 1539: // greater_healing_potion, xml: 2037
  139. if (!isEffectReplaceable(activeChar, L2EffectType.HEAL_OVER_TIME, itemId))
  140. return;
  141. res = usePotion(activeChar, 2037, 1);
  142. break;
  143. case 1540: // quick_healing_potion, xml: 2038
  144. if (!isEffectReplaceable(activeChar, L2EffectType.HEAL_OVER_TIME, itemId))
  145. return;
  146. res = usePotion(activeChar, 2038, 1);
  147. break;
  148. case 5591:
  149. case 5592: // CP and Greater CP
  150. if (!isEffectReplaceable(activeChar, L2EffectType.COMBAT_POINT_HEAL_OVER_TIME, itemId))
  151. return;
  152. res = usePotion(activeChar, 2166, (itemId == 5591) ? 1 : 2);
  153. break;
  154. case 6035: // Magic Haste Potion, xml: 2169
  155. res = usePotion(activeChar, 2169, 1);
  156. break;
  157. case 6036: // Greater Magic Haste Potion, xml: 2169
  158. res = usePotion(activeChar, 2169, 2);
  159. break;
  160. case 10155: //Mental Potion XML:2396
  161. res = usePotion(activeChar, 2396, 1);
  162. break;
  163. // ATTRIBUTE POTION
  164. case 9997: // Fire Resist Potion, xml: 2335
  165. res = usePotion(activeChar, 2335, 1);
  166. break;
  167. case 9998: // Water Resist Potion, xml: 2336
  168. res = usePotion(activeChar, 2336, 1);
  169. break;
  170. case 9999: // Earth Resist Potion, xml: 2338
  171. res = usePotion(activeChar, 2338, 1);
  172. break;
  173. case 10000: // Wind Resist Potion, xml: 2337
  174. res = usePotion(activeChar, 2337, 1);
  175. break;
  176. case 10001: // Dark Resist Potion, xml: 2340
  177. res = usePotion(activeChar, 2340, 1);
  178. break;
  179. case 10002: // Divine Resist Potion, xml: 2339
  180. res = usePotion(activeChar, 2339, 1);
  181. break;
  182. // ELIXIR
  183. case 8622:
  184. case 8623:
  185. case 8624:
  186. case 8625:
  187. case 8626:
  188. case 8627:
  189. {
  190. // elixir of Life
  191. byte expIndex = (byte) activeChar.getExpertiseIndex();
  192. res = usePotion(activeChar, 2287, (expIndex > 5 ? expIndex : expIndex + 1));
  193. }
  194. case 8628:
  195. case 8629:
  196. case 8630:
  197. case 8631:
  198. case 8632:
  199. case 8633:
  200. {
  201. byte expIndex = (byte) activeChar.getExpertiseIndex();
  202. // elixir of Strength
  203. res = usePotion(activeChar, 2288, (expIndex > 5 ? expIndex : expIndex + 1));
  204. break;
  205. }
  206. case 8634:
  207. case 8635:
  208. case 8636:
  209. case 8637:
  210. case 8638:
  211. case 8639:
  212. {
  213. byte expIndex = (byte) activeChar.getExpertiseIndex();
  214. // elixir of cp
  215. res = usePotion(activeChar, 2289, (expIndex > 5 ? expIndex : expIndex + 1));
  216. break;
  217. }
  218. // VALAKAS AMULETS
  219. case 6652: // Amulet Protection of Valakas
  220. res = usePotion(activeChar, 2231, 1);
  221. break;
  222. case 6653: // Amulet Flames of Valakas
  223. res = usePotion(activeChar, 2223, 1);
  224. break;
  225. case 6654: // Amulet Flames of Valakas
  226. res = usePotion(activeChar, 2233, 1);
  227. break;
  228. case 6655: // Amulet Slay Valakas
  229. res = usePotion(activeChar, 2232, 1);
  230. break;
  231. // HERBS
  232. case 8600: // Herb of Life
  233. res = usePotion(playable, 2278, 1);
  234. break;
  235. case 8601: // Greater Herb of Life
  236. res = usePotion(playable, 2278, 2);
  237. break;
  238. case 8602: // Superior Herb of Life
  239. res = usePotion(playable, 2278, 3);
  240. break;
  241. case 8603: // Herb of Mana
  242. res = usePotion(playable, 2279, 1);
  243. break;
  244. case 8604: // Greater Herb of Mane
  245. res = usePotion(playable, 2279, 2);
  246. break;
  247. case 8605: // Superior Herb of Mane
  248. res = usePotion(playable, 2279, 3);
  249. break;
  250. case 8606: // Herb of Strength
  251. res = usePotion(playable, 2280, 1);
  252. break;
  253. case 8607: // Herb of Magic
  254. res = usePotion(playable, 2281, 1);
  255. break;
  256. case 8608: // Herb of Atk. Spd.
  257. res = usePotion(playable, 2282, 1);
  258. break;
  259. case 8609: // Herb of Casting Spd.
  260. res = usePotion(playable, 2283, 1);
  261. break;
  262. case 8610: // Herb of Critical Attack
  263. res = usePotion(playable, 2284, 1);
  264. break;
  265. case 8611: // Herb of Speed
  266. res = usePotion(playable, 2285, 1);
  267. break;
  268. case 8612: // Herb of Warrior
  269. res = usePotion(playable, 2280, 1);// Herb of Strength
  270. res = usePotion(playable, 2282, 1);// Herb of Atk. Spd
  271. res = usePotion(playable, 2284, 1);// Herb of Critical Attack
  272. break;
  273. case 8613: // Herb of Mystic
  274. res = usePotion(playable, 2281, 1);// Herb of Magic
  275. res = usePotion(playable, 2283, 1);// Herb of Casting Spd.
  276. break;
  277. case 8614: // Herb of Warrior
  278. res = usePotion(playable, 2278, 3);// Superior Herb of Life
  279. res = usePotion(playable, 2279, 3);// Superior Herb of Mana
  280. break;
  281. case 10655:
  282. res = usePotion(playable, 2512, 1);
  283. break;
  284. case 10656:
  285. res = usePotion(playable, 2514, 1);
  286. break;
  287. case 10657:
  288. res = usePotion(playable, 2513, 1);
  289. break;
  290. // FISHERMAN POTIONS
  291. case 8193: // Fisherman's Potion - Green
  292. if (activeChar.getSkillLevel(1315) <= 3)
  293. {
  294. playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
  295. playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
  296. return;
  297. }
  298. res = usePotion(activeChar, 2274, 1);
  299. break;
  300. case 8194: // Fisherman's Potion - Jade
  301. if (activeChar.getSkillLevel(1315) <= 6)
  302. {
  303. playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
  304. playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
  305. return;
  306. }
  307. res = usePotion(activeChar, 2274, 2);
  308. break;
  309. case 8195: // Fisherman's Potion - Blue
  310. if (activeChar.getSkillLevel(1315) <= 9)
  311. {
  312. playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
  313. playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
  314. return;
  315. }
  316. res = usePotion(activeChar, 2274, 3);
  317. break;
  318. case 8196: // Fisherman's Potion - Yellow
  319. if (activeChar.getSkillLevel(1315) <= 12)
  320. {
  321. playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
  322. playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
  323. return;
  324. }
  325. res = usePotion(activeChar, 2274, 4);
  326. break;
  327. case 8197: // Fisherman's Potion - Orange
  328. if (activeChar.getSkillLevel(1315) <= 15)
  329. {
  330. playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
  331. playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
  332. return;
  333. }
  334. res = usePotion(activeChar, 2274, 5);
  335. break;
  336. case 8198: // Fisherman's Potion - Purple
  337. if (activeChar.getSkillLevel(1315) <= 18)
  338. {
  339. playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
  340. playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
  341. return;
  342. }
  343. res = usePotion(activeChar, 2274, 6);
  344. break;
  345. case 8199: // Fisherman's Potion - Red
  346. if (activeChar.getSkillLevel(1315) <= 21)
  347. {
  348. playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
  349. playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
  350. return;
  351. }
  352. res = usePotion(activeChar, 2274, 7);
  353. break;
  354. case 8200: // Fisherman's Potion - White
  355. if (activeChar.getSkillLevel(1315) <= 24)
  356. {
  357. playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
  358. playable.sendPacket(new SystemMessage(SystemMessageId.NOTHING_HAPPENED));
  359. return;
  360. }
  361. res = usePotion(activeChar, 2274, 8);
  362. break;
  363. case 8201: // Fisherman's Potion - Black
  364. res = usePotion(activeChar, 2274, 9);
  365. break;
  366. case 8202: // Fishing Potion
  367. res = usePotion(activeChar, 2275, 1);
  368. break;
  369. // Juices
  370. // added by Z0mbie!
  371. case 10260: // Haste Juice,xml:2429
  372. res = usePotion(activeChar, 2429, 1);
  373. break;
  374. case 10261: // Accuracy Juice,xml:2430
  375. res = usePotion(activeChar, 2430, 1);
  376. break;
  377. case 10262: // Critical Power Juice,xml:2431
  378. res = usePotion(activeChar, 2431, 1);
  379. break;
  380. case 10263: // Critical Attack Juice,xml:2432
  381. res = usePotion(activeChar, 2432, 1);
  382. break;
  383. case 10264: // Casting Speed Juice,xml:2433
  384. res = usePotion(activeChar, 2433, 1);
  385. break;
  386. case 10265: // Evasion Juice,xml:2434
  387. res = usePotion(activeChar, 2434, 1);
  388. break;
  389. case 10266: // Magic Power Juice,xml:2435
  390. res = usePotion(activeChar, 2435, 1);
  391. break;
  392. case 10267: // Power Juice,xml:2436
  393. res = usePotion(activeChar, 2436, 1);
  394. break;
  395. case 10268: // Speed Juice,xml:2437
  396. res = usePotion(activeChar, 2437, 1);
  397. break;
  398. case 10269: // Defense Juice,xml:2438
  399. res = usePotion(activeChar, 2438, 1);
  400. break;
  401. case 10270: // MP Consumption Juice,xml: 2439
  402. res = usePotion(activeChar, 2439, 1);
  403. break;
  404. default:
  405. }
  406. if (res)
  407. playable.destroyItem("Consume", item.getObjectId(), 1, null, false);
  408. }
  409. /**
  410. *
  411. * @param activeChar
  412. * @param effectType
  413. * @param itemId
  414. * @return
  415. */
  416. @SuppressWarnings("unchecked")
  417. private boolean isEffectReplaceable(L2PcInstance activeChar, Enum effectType, int itemId)
  418. {
  419. L2Effect[] effects = activeChar.getAllEffects();
  420. if (effects == null)
  421. return true;
  422. for (L2Effect e : effects)
  423. {
  424. if (e.getEffectType() == effectType)
  425. {
  426. // One can reuse pots after 2/3 of their duration is over.
  427. // It would be faster to check if its > 10 but that would screw custom pot durations...
  428. if (e.getTaskTime() > (e.getSkill().getBuffDuration() * 67) / 100000)
  429. return true;
  430. SystemMessage sm = new SystemMessage(SystemMessageId.S1_PREPARED_FOR_REUSE);
  431. sm.addItemName(itemId);
  432. activeChar.sendPacket(sm);
  433. return false;
  434. }
  435. }
  436. return true;
  437. }
  438. /**
  439. *
  440. * @param activeChar
  441. * @param magicId
  442. * @param level
  443. * @return
  444. */
  445. public boolean usePotion(L2PlayableInstance activeChar, int magicId, int level)
  446. {
  447. L2Skill skill = SkillTable.getInstance().getInfo(magicId, level);
  448. if (skill != null)
  449. {
  450. // Return false if potion is in reuse
  451. // so is not destroyed from inventory
  452. if (activeChar.isSkillDisabled(skill.getId()))
  453. {
  454. SystemMessage sm = new SystemMessage(SystemMessageId.S1_PREPARED_FOR_REUSE);
  455. sm.addSkillName(skill);
  456. activeChar.sendPacket(sm);
  457. return false;
  458. }
  459. activeChar.doSimultaneousCast(skill);
  460. if (activeChar instanceof L2PcInstance)
  461. {
  462. L2PcInstance player = (L2PcInstance)activeChar;
  463. //only for Heal potions
  464. if (magicId == 2031 || magicId == 2032 || magicId == 2037)
  465. {
  466. player.shortBuffStatusUpdate(magicId, level, 15);
  467. }
  468. // Summons should be affected by herbs too, self time effect is handled at L2Effect constructor
  469. else if (((magicId > 2277 && magicId < 2286) || (magicId >= 2512 && magicId <= 2514))
  470. && (player.getPet() != null && player.getPet() instanceof L2SummonInstance))
  471. {
  472. player.getPet().doSimultaneousCast(skill);
  473. }
  474. if (!(player.isSitting() && !skill.isPotion()))
  475. return true;
  476. }
  477. else if (activeChar instanceof L2PetInstance)
  478. {
  479. SystemMessage sm = new SystemMessage(SystemMessageId.PET_USES_S1);
  480. sm.addString(skill.getName());
  481. ((L2PetInstance)(activeChar)).getOwner().sendPacket(sm);
  482. }
  483. }
  484. return false;
  485. }
  486. /**
  487. *
  488. * @see net.sf.l2j.gameserver.handler.IItemHandler#getItemIds()
  489. */
  490. public int[] getItemIds()
  491. {
  492. return ITEM_IDS;
  493. }
  494. }