Fishing.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. package com.gmail.nossr50.skills.gathering;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.Map;
  5. import java.util.Random;
  6. import org.bukkit.DyeColor;
  7. import org.bukkit.Location;
  8. import org.bukkit.Material;
  9. import org.bukkit.enchantments.Enchantment;
  10. import org.bukkit.entity.EntityType;
  11. import org.bukkit.entity.Item;
  12. import org.bukkit.entity.LivingEntity;
  13. import org.bukkit.entity.Player;
  14. import org.bukkit.entity.Sheep;
  15. import org.bukkit.entity.Skeleton;
  16. import org.bukkit.entity.Skeleton.SkeletonType;
  17. import org.bukkit.event.player.PlayerFishEvent;
  18. import org.bukkit.inventory.ItemStack;
  19. import org.bukkit.material.MaterialData;
  20. import org.bukkit.material.Wool;
  21. import org.bukkit.potion.Potion;
  22. import org.bukkit.potion.PotionType;
  23. import com.gmail.nossr50.config.AdvancedConfig;
  24. import com.gmail.nossr50.config.Config;
  25. import com.gmail.nossr50.config.TreasuresConfig;
  26. import com.gmail.nossr50.datatypes.PlayerProfile;
  27. import com.gmail.nossr50.datatypes.SkillType;
  28. import com.gmail.nossr50.datatypes.treasure.FishingTreasure;
  29. import com.gmail.nossr50.locale.LocaleLoader;
  30. import com.gmail.nossr50.util.Combat;
  31. import com.gmail.nossr50.util.ItemChecks;
  32. import com.gmail.nossr50.util.Misc;
  33. import com.gmail.nossr50.util.Permissions;
  34. import com.gmail.nossr50.util.Skills;
  35. import com.gmail.nossr50.util.Users;
  36. public class Fishing {
  37. private static Random random = new Random();
  38. static AdvancedConfig advancedConfig = AdvancedConfig.getInstance();
  39. /**
  40. * Get the player's current fishing loot tier.
  41. *
  42. * @param profile
  43. * The profile of the player
  44. * @return the player's current fishing rank
  45. */
  46. public static int getFishingLootTier(PlayerProfile profile) {
  47. int level = profile.getSkillLevel(SkillType.FISHING);
  48. int fishingTier;
  49. if (level >= Config.getInstance().getFishingTierLevelsTier5()) {
  50. fishingTier = 5;
  51. } else if (level >= Config.getInstance().getFishingTierLevelsTier4()) {
  52. fishingTier = 4;
  53. } else if (level >= Config.getInstance().getFishingTierLevelsTier3()) {
  54. fishingTier = 3;
  55. } else if (level >= Config.getInstance().getFishingTierLevelsTier2()) {
  56. fishingTier = 2;
  57. } else {
  58. fishingTier = 1;
  59. }
  60. return fishingTier;
  61. }
  62. /**
  63. * Get item results from Fishing.
  64. *
  65. * @param player
  66. * The player that was fishing
  67. * @param event
  68. * The event to modify
  69. */
  70. private static void getFishingResults(Player player, PlayerFishEvent event) {
  71. if (player == null)
  72. return;
  73. PlayerProfile profile = Users.getProfile(player);
  74. List<FishingTreasure> rewards = new ArrayList<FishingTreasure>();
  75. Item theCatch = (Item) event.getCaught();
  76. switch (getFishingLootTier(profile)) {
  77. case 1:
  78. rewards = TreasuresConfig.getInstance().fishingRewardsTier1;
  79. break;
  80. case 2:
  81. rewards = TreasuresConfig.getInstance().fishingRewardsTier2;
  82. break;
  83. case 3:
  84. rewards = TreasuresConfig.getInstance().fishingRewardsTier3;
  85. break;
  86. case 4:
  87. rewards = TreasuresConfig.getInstance().fishingRewardsTier4;
  88. break;
  89. case 5:
  90. rewards = TreasuresConfig.getInstance().fishingRewardsTier5;
  91. break;
  92. default:
  93. break;
  94. }
  95. if (Config.getInstance().getFishingDropsEnabled() && rewards.size() > 0
  96. && Permissions.fishingTreasures(player)) {
  97. FishingTreasure treasure;
  98. treasure = rewards.get(random.nextInt(rewards.size()));
  99. int randomChance = 100;
  100. if (Permissions.luckyFishing(player)) {
  101. randomChance = (int) (randomChance * 0.75);
  102. }
  103. if (random.nextDouble() * randomChance <= treasure.getDropChance()) {
  104. Users.getPlayer(player).addXP(SkillType.FISHING,treasure.getXp());
  105. theCatch.setItemStack(treasure.getDrop());
  106. }
  107. } else {
  108. theCatch.setItemStack(new ItemStack(Material.RAW_FISH));
  109. }
  110. short maxDurability = theCatch.getItemStack().getType().getMaxDurability();
  111. if (maxDurability > 0) {
  112. theCatch.getItemStack().setDurability((short) (random.nextInt(maxDurability))); // Change durability to random value
  113. }
  114. Skills.xpProcessing(player, profile, SkillType.FISHING, Config.getInstance().getFishingBaseXP());
  115. }
  116. /**
  117. * Process results from Fishing.
  118. *
  119. * @param event
  120. * The event to modify
  121. */
  122. public static void processResults(PlayerFishEvent event) {
  123. Player player = event.getPlayer();
  124. if (player == null)
  125. return;
  126. PlayerProfile profile = Users.getProfile(player);
  127. getFishingResults(player, event);
  128. Item theCatch = (Item) event.getCaught();
  129. if (theCatch.getItemStack().getType() != Material.RAW_FISH) {
  130. final int ENCHANTMENT_CHANCE = advancedConfig.getFishingEnchantmentChance();
  131. boolean enchanted = false;
  132. ItemStack fishingResults = theCatch.getItemStack();
  133. player.sendMessage(LocaleLoader.getString("Fishing.ItemFound"));
  134. if (ItemChecks.isEnchantable(fishingResults)) {
  135. int randomChance = 100;
  136. if (Permissions.luckyFishing(player)) {
  137. randomChance = (int) (randomChance * 0.75);
  138. }
  139. if (random.nextInt(randomChance) <= ENCHANTMENT_CHANCE
  140. && Permissions.fishingMagic(player)) {
  141. for (Enchantment newEnchant : Enchantment.values()) {
  142. if (newEnchant.canEnchantItem(fishingResults)) {
  143. Map<Enchantment, Integer> resultEnchantments = fishingResults.getEnchantments();
  144. for (Enchantment oldEnchant : resultEnchantments.keySet()) {
  145. if (oldEnchant.conflictsWith(newEnchant))
  146. continue;
  147. }
  148. /*
  149. * Actual chance to have an enchantment is related
  150. * to your fishing skill
  151. */
  152. if (random.nextInt(15) < Fishing.getFishingLootTier(profile)) {
  153. enchanted = true;
  154. int randomEnchantLevel = random.nextInt(newEnchant.getMaxLevel()) + 1;
  155. if (randomEnchantLevel < newEnchant.getStartLevel()) {
  156. randomEnchantLevel = newEnchant.getStartLevel();
  157. }
  158. if (randomEnchantLevel >= 1000)
  159. continue;
  160. fishingResults.addEnchantment(newEnchant,randomEnchantLevel);
  161. }
  162. }
  163. }
  164. }
  165. }
  166. if (enchanted) {
  167. player.sendMessage(LocaleLoader.getString("Fishing.MagicFound"));
  168. }
  169. }
  170. }
  171. /**
  172. * Shake a mob, have them drop an item.
  173. *
  174. * @param event
  175. * The event to modify
  176. */
  177. public static void shakeMob(PlayerFishEvent event) {
  178. int randomChance = 100;
  179. if (Permissions.luckyFishing(event.getPlayer())) {
  180. randomChance = (int) (randomChance * 1.25);
  181. }
  182. final Player player = event.getPlayer();
  183. final PlayerProfile profile = Users.getProfile(player);
  184. int lootTier = getFishingLootTier(profile);
  185. int dropChance = getShakeChance(lootTier);
  186. if (Permissions.luckyFishing(player)) {
  187. // With lucky perk on max level tier, its 100%
  188. dropChance = (int) (dropChance * 1.25);
  189. }
  190. final int DROP_CHANCE = random.nextInt(100);
  191. final int DROP_NUMBER = random.nextInt(randomChance) + 1;
  192. LivingEntity le = (LivingEntity) event.getCaught();
  193. EntityType type = le.getType();
  194. Location location = le.getLocation();
  195. if (DROP_CHANCE < dropChance) {
  196. switch (type) {
  197. case BLAZE:
  198. Misc.dropItem(location, new ItemStack(Material.BLAZE_ROD));
  199. break;
  200. case CAVE_SPIDER:
  201. if (DROP_NUMBER > 50) {
  202. Misc.dropItem(location, new ItemStack(Material.SPIDER_EYE));
  203. } else {
  204. Misc.dropItem(location, new ItemStack(Material.STRING));
  205. }
  206. break;
  207. case CHICKEN:
  208. if (DROP_NUMBER > 66) {
  209. Misc.dropItem(location, new ItemStack(Material.FEATHER));
  210. } else if (DROP_NUMBER > 33) {
  211. Misc.dropItem(location, new ItemStack(Material.RAW_CHICKEN));
  212. } else {
  213. Misc.dropItem(location, new ItemStack(Material.EGG));
  214. }
  215. break;
  216. case COW:
  217. if (DROP_NUMBER > 95) {
  218. Misc.dropItem(location, new ItemStack(Material.MILK_BUCKET));
  219. } else if (DROP_NUMBER > 50) {
  220. Misc.dropItem(location, new ItemStack(Material.LEATHER));
  221. } else {
  222. Misc.dropItem(location, new ItemStack(Material.RAW_BEEF));
  223. }
  224. break;
  225. case CREEPER:
  226. if (DROP_NUMBER > 97) {
  227. Misc.dropItem(location, new ItemStack(Material.SKULL_ITEM, 1, (short) 4));
  228. } else {
  229. Misc.dropItem(location, new ItemStack(Material.SULPHUR));
  230. }
  231. break;
  232. case ENDERMAN:
  233. Misc.dropItem(location, new ItemStack(Material.ENDER_PEARL));
  234. break;
  235. case GHAST:
  236. if (DROP_NUMBER > 50) {
  237. Misc.dropItem(location, new ItemStack(Material.SULPHUR));
  238. } else {
  239. Misc.dropItem(location, new ItemStack(Material.GHAST_TEAR));
  240. }
  241. break;
  242. case IRON_GOLEM:
  243. if (DROP_NUMBER > 97) {
  244. Misc.dropItem(location, new ItemStack(Material.PUMPKIN));
  245. } else if (DROP_NUMBER > 85) {
  246. Misc.dropItem(location, new ItemStack(Material.IRON_INGOT));
  247. } else {
  248. Misc.dropItem(location, new ItemStack(Material.RED_ROSE));
  249. }
  250. break;
  251. case MAGMA_CUBE:
  252. Misc.dropItem(location, new ItemStack(Material.MAGMA_CREAM));
  253. break;
  254. case MUSHROOM_COW:
  255. if (DROP_NUMBER > 95) {
  256. Misc.dropItem(location, new ItemStack(Material.MILK_BUCKET));
  257. } else if (DROP_NUMBER > 90) {
  258. Misc.dropItem(location, new ItemStack(Material.MUSHROOM_SOUP));
  259. } else if (DROP_NUMBER > 60) {
  260. Misc.dropItem(location, new ItemStack(Material.LEATHER));
  261. } else if (DROP_NUMBER > 30) {
  262. Misc.dropItem(location, new ItemStack(Material.RAW_BEEF));
  263. } else {
  264. Misc.dropItem(location, new ItemStack(Material.RED_MUSHROOM));
  265. Misc.randomDropItems(location, new ItemStack(Material.RED_MUSHROOM), 50, 2);
  266. }
  267. break;
  268. case PIG:
  269. Misc.dropItem(location, new ItemStack(Material.PORK));
  270. break;
  271. case PIG_ZOMBIE:
  272. if (DROP_NUMBER > 50) {
  273. Misc.dropItem(location, new ItemStack(Material.ROTTEN_FLESH));
  274. } else {
  275. Misc.dropItem(location, new ItemStack(Material.GOLD_NUGGET));
  276. }
  277. break;
  278. case SHEEP:
  279. final Sheep sheep = (Sheep) le;
  280. if (!sheep.isSheared()) {
  281. final Wool wool = new Wool();
  282. wool.setColor(sheep.getColor());
  283. final ItemStack theWool = wool.toItemStack();
  284. theWool.setAmount(1 + random.nextInt(6));
  285. Misc.dropItem(location, theWool);
  286. sheep.setSheared(true);
  287. }
  288. break;
  289. case SKELETON:
  290. if (((Skeleton) le).getSkeletonType() == SkeletonType.WITHER) {
  291. if (DROP_NUMBER > 97) {
  292. Misc.dropItem(location, new ItemStack(Material.SKULL_ITEM, 1, (short) 1));
  293. } else if (DROP_NUMBER > 50) {
  294. Misc.dropItem(location, new ItemStack(Material.BONE));
  295. } else {
  296. Misc.dropItem(location, new ItemStack(Material.COAL));
  297. Misc.randomDropItems(location, new ItemStack(Material.COAL), 50, 2);
  298. }
  299. } else {
  300. if (DROP_NUMBER > 97) {
  301. Misc.dropItem(location, new ItemStack(Material.SKULL_ITEM));
  302. } else if (DROP_NUMBER > 50) {
  303. Misc.dropItem(location, new ItemStack(Material.BONE));
  304. } else {
  305. Misc.dropItem(location, new ItemStack(Material.ARROW));
  306. Misc.randomDropItems(location, new ItemStack(Material.ARROW), 50, 2);
  307. }
  308. }
  309. break;
  310. case SLIME:
  311. Misc.dropItem(location, new ItemStack(Material.SLIME_BALL));
  312. break;
  313. case SNOWMAN:
  314. if (DROP_NUMBER > 97) {
  315. Misc.dropItem(location, new ItemStack(Material.PUMPKIN));
  316. } else {
  317. Misc.dropItem(location, new ItemStack(Material.SNOW_BALL));
  318. Misc.randomDropItems(location, new ItemStack(Material.SNOW_BALL), 50, 4);
  319. }
  320. break;
  321. case SPIDER:
  322. if (DROP_NUMBER > 50) {
  323. Misc.dropItem(location, new ItemStack(Material.SPIDER_EYE));
  324. } else {
  325. Misc.dropItem(location, new ItemStack(Material.STRING));
  326. }
  327. break;
  328. case SQUID:
  329. ItemStack item;
  330. try {
  331. item = (new MaterialData(Material.INK_SACK, DyeColor.BLACK.getDyeData())).toItemStack(1);
  332. }
  333. catch(Exception e) {
  334. item = (new MaterialData(Material.INK_SACK, (byte) 0)).toItemStack(1);
  335. }
  336. Misc.dropItem(location, item);
  337. break;
  338. case WITCH:
  339. final int DROP_NUMBER_2 = random.nextInt(randomChance) + 1;
  340. if (DROP_NUMBER > 95) {
  341. if (DROP_NUMBER_2 > 66) {
  342. Misc.dropItem(location, new Potion(PotionType.INSTANT_HEAL).toItemStack(1));
  343. } else if (DROP_NUMBER_2 > 33) {
  344. Misc.dropItem(location, new Potion(PotionType.FIRE_RESISTANCE).toItemStack(1));
  345. } else {
  346. Misc.dropItem(location, new Potion(PotionType.SPEED).toItemStack(1));
  347. }
  348. } else {
  349. if (DROP_NUMBER_2 > 88) {
  350. Misc.dropItem(location, new ItemStack(Material.GLASS_BOTTLE));
  351. } else if (DROP_NUMBER_2 > 75) {
  352. Misc.dropItem(location, new ItemStack(Material.GLOWSTONE_DUST));
  353. } else if (DROP_NUMBER_2 > 63) {
  354. Misc.dropItem(location, new ItemStack(Material.SULPHUR));
  355. } else if (DROP_NUMBER_2 > 50) {
  356. Misc.dropItem(location, new ItemStack(Material.REDSTONE));
  357. } else if (DROP_NUMBER_2 > 38) {
  358. Misc.dropItem(location, new ItemStack(Material.SPIDER_EYE));
  359. } else if (DROP_NUMBER_2 > 25) {
  360. Misc.dropItem(location, new ItemStack(Material.STICK));
  361. } else if (DROP_NUMBER_2 > 13) {
  362. Misc.dropItem(location, new ItemStack(Material.SUGAR));
  363. } else {
  364. Misc.dropItem(location, new ItemStack(Material.POTION));
  365. }
  366. }
  367. break;
  368. case ZOMBIE:
  369. if (DROP_NUMBER > 97) {
  370. Misc.dropItem(location, new ItemStack(Material.SKULL_ITEM, 1, (short) 2));
  371. } else {
  372. Misc.dropItem(location, new ItemStack(Material.ROTTEN_FLESH));
  373. }
  374. break;
  375. default:
  376. break;
  377. }
  378. }
  379. Combat.dealDamage(le, 1);
  380. }
  381. /**
  382. * Gets chance of shake success.
  383. *
  384. * @param rank
  385. * Treasure hunter rank
  386. * @return The chance of a successful shake
  387. */
  388. public static int getShakeChance(int lootTier) {
  389. switch (lootTier) {
  390. case 1:
  391. return Config.getInstance().getShakeChanceRank1();
  392. case 2:
  393. return Config.getInstance().getShakeChanceRank2();
  394. case 3:
  395. return Config.getInstance().getShakeChanceRank3();
  396. case 4:
  397. return Config.getInstance().getShakeChanceRank4();
  398. case 5:
  399. return Config.getInstance().getShakeChanceRank5();
  400. default:
  401. return 10;
  402. }
  403. }
  404. }