L2Fishing.java 9.6 KB

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