L2Fishing.java 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /*
  2. * Copyright (C) 2004-2013 L2J Server
  3. *
  4. * This file is part of L2J Server.
  5. *
  6. * L2J Server is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J Server is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.l2jserver.gameserver.model.fishing;
  20. import java.util.concurrent.Future;
  21. import com.l2jserver.gameserver.ThreadPoolManager;
  22. import com.l2jserver.gameserver.datatables.FishingMonstersData;
  23. import com.l2jserver.gameserver.datatables.NpcTable;
  24. import com.l2jserver.gameserver.model.L2Spawn;
  25. import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
  26. import com.l2jserver.gameserver.model.actor.instance.L2PenaltyMonsterInstance;
  27. import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
  28. import com.l2jserver.gameserver.network.SystemMessageId;
  29. import com.l2jserver.gameserver.network.serverpackets.ExFishingHpRegen;
  30. import com.l2jserver.gameserver.network.serverpackets.ExFishingStartCombat;
  31. import com.l2jserver.gameserver.network.serverpackets.PlaySound;
  32. import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
  33. import com.l2jserver.util.Rnd;
  34. public class L2Fishing implements Runnable
  35. {
  36. private L2PcInstance _fisher;
  37. private int _time;
  38. private int _stop = 0;
  39. private int _goodUse = 0;
  40. private int _anim = 0;
  41. private int _mode = 0;
  42. private int _deceptiveMode = 0;
  43. private Future<?> _fishAiTask;
  44. private boolean _thinking;
  45. // Fish datas
  46. private final int _fishId;
  47. private final int _fishMaxHp;
  48. private int _fishCurHp;
  49. private final double _regenHp;
  50. private final boolean _isUpperGrade;
  51. private int _lureType;
  52. @Override
  53. public void run()
  54. {
  55. if (_fisher == null)
  56. {
  57. return;
  58. }
  59. if (_fishCurHp >= (_fishMaxHp * 2))
  60. {
  61. // The fish got away
  62. _fisher.sendPacket(SystemMessageId.BAIT_STOLEN_BY_FISH);
  63. doDie(false);
  64. }
  65. else if (_time <= 0)
  66. {
  67. // Time is up, so that fish got away
  68. _fisher.sendPacket(SystemMessageId.FISH_SPIT_THE_HOOK);
  69. doDie(false);
  70. }
  71. else
  72. {
  73. aiTask();
  74. }
  75. }
  76. public L2Fishing(L2PcInstance Fisher, L2Fish fish, boolean isNoob, boolean isUpperGrade)
  77. {
  78. _fisher = Fisher;
  79. _fishMaxHp = fish.getFishHp();
  80. _fishCurHp = _fishMaxHp;
  81. _regenHp = fish.getHpRegen();
  82. _fishId = fish.getItemId();
  83. _time = fish.getCombatDuration();
  84. _isUpperGrade = isUpperGrade;
  85. if (isUpperGrade)
  86. {
  87. _deceptiveMode = Rnd.get(100) >= 90 ? 1 : 0;
  88. _lureType = 2;
  89. }
  90. else
  91. {
  92. _deceptiveMode = 0;
  93. _lureType = isNoob ? 0 : 1;
  94. }
  95. _mode = Rnd.get(100) >= 80 ? 1 : 0;
  96. ExFishingStartCombat efsc = new ExFishingStartCombat(_fisher, _time, _fishMaxHp, _mode, _lureType, _deceptiveMode);
  97. _fisher.broadcastPacket(efsc);
  98. _fisher.sendPacket(new PlaySound(1, "SF_S_01", 0, 0, 0, 0, 0));
  99. // Succeeded in getting a bite
  100. _fisher.sendPacket(SystemMessageId.GOT_A_BITE);
  101. if (_fishAiTask == null)
  102. {
  103. _fishAiTask = ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(this, 1000, 1000);
  104. }
  105. }
  106. public void changeHp(int hp, int pen)
  107. {
  108. _fishCurHp -= hp;
  109. if (_fishCurHp < 0)
  110. {
  111. _fishCurHp = 0;
  112. }
  113. ExFishingHpRegen efhr = new ExFishingHpRegen(_fisher, _time, _fishCurHp, _mode, _goodUse, _anim, pen, _deceptiveMode);
  114. _fisher.broadcastPacket(efhr);
  115. _anim = 0;
  116. if (_fishCurHp > (_fishMaxHp * 2))
  117. {
  118. _fishCurHp = _fishMaxHp * 2;
  119. doDie(false);
  120. return;
  121. }
  122. else if (_fishCurHp == 0)
  123. {
  124. doDie(true);
  125. return;
  126. }
  127. }
  128. public synchronized void doDie(boolean win)
  129. {
  130. if (_fishAiTask != null)
  131. {
  132. _fishAiTask.cancel(false);
  133. _fishAiTask = null;
  134. }
  135. if (_fisher == null)
  136. {
  137. return;
  138. }
  139. if (win)
  140. {
  141. int lvl = _fisher.getLevel();
  142. L2NpcTemplate monster;
  143. L2FishingMonster fishingMonster = FishingMonstersData.getInstance().getFishingMonster(lvl);
  144. if (Rnd.get(100) <= fishingMonster.getProbability())
  145. {
  146. monster = NpcTable.getInstance().getTemplate(fishingMonster.getFishingMonsterId());
  147. _fisher.sendPacket(SystemMessageId.YOU_CAUGHT_SOMETHING_SMELLY_THROW_IT_BACK);
  148. spawnMonster(monster);
  149. }
  150. else
  151. {
  152. _fisher.sendPacket(SystemMessageId.YOU_CAUGHT_SOMETHING);
  153. _fisher.addItem("Fishing", _fishId, 1, null, true);
  154. }
  155. }
  156. _fisher.endFishing(win);
  157. _fisher = null;
  158. }
  159. protected void aiTask()
  160. {
  161. if (_thinking)
  162. {
  163. return;
  164. }
  165. _thinking = true;
  166. _time--;
  167. try
  168. {
  169. if (_mode == 1)
  170. {
  171. if (_deceptiveMode == 0)
  172. {
  173. _fishCurHp += (int) _regenHp;
  174. }
  175. }
  176. else
  177. {
  178. if (_deceptiveMode == 1)
  179. {
  180. _fishCurHp += (int) _regenHp;
  181. }
  182. }
  183. if (_stop == 0)
  184. {
  185. _stop = 1;
  186. int check = Rnd.get(100);
  187. if (check >= 70)
  188. {
  189. _mode = _mode == 0 ? 1 : 0;
  190. }
  191. if (_isUpperGrade)
  192. {
  193. check = Rnd.get(100);
  194. if (check >= 90)
  195. {
  196. _deceptiveMode = _deceptiveMode == 0 ? 1 : 0;
  197. }
  198. }
  199. }
  200. else
  201. {
  202. _stop--;
  203. }
  204. }
  205. finally
  206. {
  207. _thinking = false;
  208. ExFishingHpRegen efhr = new ExFishingHpRegen(_fisher, _time, _fishCurHp, _mode, 0, _anim, 0, _deceptiveMode);
  209. if (_anim != 0)
  210. {
  211. _fisher.broadcastPacket(efhr);
  212. }
  213. else
  214. {
  215. _fisher.sendPacket(efhr);
  216. }
  217. }
  218. }
  219. public void useReeling(int dmg, int pen)
  220. {
  221. _anim = 2;
  222. if (Rnd.get(100) > 90)
  223. {
  224. _fisher.sendPacket(SystemMessageId.FISH_RESISTED_ATTEMPT_TO_BRING_IT_IN);
  225. _goodUse = 0;
  226. changeHp(0, pen);
  227. return;
  228. }
  229. if (_fisher == null)
  230. {
  231. return;
  232. }
  233. if (_mode == 1)
  234. {
  235. if (_deceptiveMode == 0)
  236. {
  237. // Reeling is successful, Damage: $s1
  238. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.REELING_SUCCESFUL_S1_DAMAGE);
  239. sm.addNumber(dmg);
  240. _fisher.sendPacket(sm);
  241. if (pen > 0)
  242. {
  243. sm = SystemMessage.getSystemMessage(SystemMessageId.REELING_SUCCESSFUL_PENALTY_S1);
  244. sm.addNumber(pen);
  245. _fisher.sendPacket(sm);
  246. }
  247. _goodUse = 1;
  248. changeHp(dmg, pen);
  249. }
  250. else
  251. {
  252. // Reeling failed, Damage: $s1
  253. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.FISH_RESISTED_REELING_S1_HP_REGAINED);
  254. sm.addNumber(dmg);
  255. _fisher.sendPacket(sm);
  256. _goodUse = 2;
  257. changeHp(-dmg, pen);
  258. }
  259. }
  260. else
  261. {
  262. if (_deceptiveMode == 0)
  263. {
  264. // Reeling failed, Damage: $s1
  265. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.FISH_RESISTED_REELING_S1_HP_REGAINED);
  266. sm.addNumber(dmg);
  267. _fisher.sendPacket(sm);
  268. _goodUse = 2;
  269. changeHp(-dmg, pen);
  270. }
  271. else
  272. {
  273. // Reeling is successful, Damage: $s1
  274. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.REELING_SUCCESFUL_S1_DAMAGE);
  275. sm.addNumber(dmg);
  276. _fisher.sendPacket(sm);
  277. if (pen > 0)
  278. {
  279. sm = SystemMessage.getSystemMessage(SystemMessageId.REELING_SUCCESSFUL_PENALTY_S1);
  280. sm.addNumber(pen);
  281. _fisher.sendPacket(sm);
  282. }
  283. _goodUse = 1;
  284. changeHp(dmg, pen);
  285. }
  286. }
  287. }
  288. public void usePumping(int dmg, int pen)
  289. {
  290. _anim = 1;
  291. if (Rnd.get(100) > 90)
  292. {
  293. _fisher.sendPacket(SystemMessageId.FISH_RESISTED_ATTEMPT_TO_BRING_IT_IN);
  294. _goodUse = 0;
  295. changeHp(0, pen);
  296. return;
  297. }
  298. if (_fisher == null)
  299. {
  300. return;
  301. }
  302. if (_mode == 0)
  303. {
  304. if (_deceptiveMode == 0)
  305. {
  306. // Pumping is successful. Damage: $s1
  307. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.PUMPING_SUCCESFUL_S1_DAMAGE);
  308. sm.addNumber(dmg);
  309. _fisher.sendPacket(sm);
  310. if (pen > 0)
  311. {
  312. sm = SystemMessage.getSystemMessage(SystemMessageId.PUMPING_SUCCESSFUL_PENALTY_S1);
  313. sm.addNumber(pen);
  314. _fisher.sendPacket(sm);
  315. }
  316. _goodUse = 1;
  317. changeHp(dmg, pen);
  318. }
  319. else
  320. {
  321. // Pumping failed, Regained: $s1
  322. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.FISH_RESISTED_PUMPING_S1_HP_REGAINED);
  323. sm.addNumber(dmg);
  324. _fisher.sendPacket(sm);
  325. _goodUse = 2;
  326. changeHp(-dmg, pen);
  327. }
  328. }
  329. else
  330. {
  331. if (_deceptiveMode == 0)
  332. {
  333. // Pumping failed, Regained: $s1
  334. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.FISH_RESISTED_PUMPING_S1_HP_REGAINED);
  335. sm.addNumber(dmg);
  336. _fisher.sendPacket(sm);
  337. _goodUse = 2;
  338. changeHp(-dmg, pen);
  339. }
  340. else
  341. {
  342. // Pumping is successful. Damage: $s1
  343. SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.PUMPING_SUCCESFUL_S1_DAMAGE);
  344. sm.addNumber(dmg);
  345. _fisher.sendPacket(sm);
  346. if (pen > 0)
  347. {
  348. sm = SystemMessage.getSystemMessage(SystemMessageId.PUMPING_SUCCESSFUL_PENALTY_S1);
  349. sm.addNumber(pen);
  350. _fisher.sendPacket(sm);
  351. }
  352. _goodUse = 1;
  353. changeHp(dmg, pen);
  354. }
  355. }
  356. }
  357. private void spawnMonster(L2NpcTemplate monster)
  358. {
  359. if (monster != null)
  360. {
  361. try
  362. {
  363. L2Spawn spawn = new L2Spawn(monster);
  364. spawn.setLocx(_fisher.getX());
  365. spawn.setLocy(_fisher.getY());
  366. spawn.setLocz(_fisher.getZ());
  367. spawn.setAmount(1);
  368. spawn.setHeading(_fisher.getHeading());
  369. spawn.stopRespawn();
  370. ((L2PenaltyMonsterInstance) spawn.doSpawn().scheduleDespawn(3 * 60 * 1000)).setPlayerToKill(_fisher);
  371. }
  372. catch (Exception e)
  373. {
  374. // Nothing
  375. }
  376. }
  377. }
  378. }