2
0

Potions.java 18 KB

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