FishingManager.java 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. package com.gmail.nossr50.skills.fishing;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7. import org.bukkit.Material;
  8. import org.bukkit.enchantments.Enchantment;
  9. import org.bukkit.entity.Entity;
  10. import org.bukkit.entity.Fish;
  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.inventory.ItemStack;
  18. import com.gmail.nossr50.config.AdvancedConfig;
  19. import com.gmail.nossr50.config.Config;
  20. import com.gmail.nossr50.config.treasure.TreasureConfig;
  21. import com.gmail.nossr50.datatypes.player.McMMOPlayer;
  22. import com.gmail.nossr50.datatypes.skills.SkillType;
  23. import com.gmail.nossr50.datatypes.treasure.FishingTreasure;
  24. import com.gmail.nossr50.locale.LocaleLoader;
  25. import com.gmail.nossr50.skills.SkillManager;
  26. import com.gmail.nossr50.skills.fishing.Fishing.Tier;
  27. import com.gmail.nossr50.util.ItemUtils;
  28. import com.gmail.nossr50.util.Misc;
  29. import com.gmail.nossr50.util.Permissions;
  30. import com.gmail.nossr50.util.skills.CombatUtils;
  31. import com.gmail.nossr50.util.skills.SkillUtils;
  32. public class FishingManager extends SkillManager {
  33. public FishingManager(McMMOPlayer mcMMOPlayer) {
  34. super(mcMMOPlayer, SkillType.FISHING);
  35. }
  36. public boolean canShake(Entity target) {
  37. return target instanceof LivingEntity && getSkillLevel() >= AdvancedConfig.getInstance().getShakeUnlockLevel() && Permissions.shake(getPlayer());
  38. }
  39. public boolean canMasterAngler() {
  40. return Permissions.masterAngler(getPlayer());
  41. }
  42. /**
  43. * Gets the loot tier
  44. *
  45. * @return the loot tier
  46. */
  47. public int getLootTier() {
  48. int skillLevel = getSkillLevel();
  49. for (Tier tier : Tier.values()) {
  50. if (skillLevel >= tier.getLevel()) {
  51. return tier.toNumerical();
  52. }
  53. }
  54. return 0;
  55. }
  56. /**
  57. * Gets the Shake Mob probability
  58. *
  59. * @return Shake Mob probability
  60. */
  61. public int getShakeProbability() {
  62. int skillLevel = getSkillLevel();
  63. for (Tier tier : Tier.values()) {
  64. if (skillLevel >= tier.getLevel()) {
  65. return tier.getShakeChance();
  66. }
  67. }
  68. return 0;
  69. }
  70. /**
  71. * Handle the Fisherman's Diet ability
  72. *
  73. * @param rankChange The # of levels to change rank for the food
  74. * @param eventFoodLevel The initial change in hunger from the event
  75. * @return the modified change in hunger for the event
  76. */
  77. public int handleFishermanDiet(int rankChange, int eventFoodLevel) {
  78. return SkillUtils.handleFoodSkills(getPlayer(), skill, eventFoodLevel, Fishing.fishermansDietRankLevel1, Fishing.fishermansDietMaxLevel, rankChange);
  79. }
  80. public void masterAngler(Fish hook) {
  81. System.out.println("BEFORE: " + hook.getBiteChance());
  82. hook.setBiteChance(Math.min(hook.getBiteChance() * Math.max((getSkillLevel() / 10.0), 1.0), 1.0));
  83. System.out.println("AFTER: " + hook.getBiteChance());
  84. }
  85. /**
  86. * Process the results from a successful fishing trip
  87. *
  88. * @param fishingCatch The {@link Item} initially caught
  89. */
  90. public void handleFishing(Item fishingCatch) {
  91. int treasureXp = 0;
  92. Player player = getPlayer();
  93. FishingTreasure treasure = null;
  94. if (Config.getInstance().getFishingDropsEnabled() && Permissions.fishingTreasureHunter(player)) {
  95. treasure = getFishingTreasure();
  96. }
  97. if (treasure != null) {
  98. player.sendMessage(LocaleLoader.getString("Fishing.ItemFound"));
  99. treasureXp = treasure.getXp();
  100. ItemStack treasureDrop = treasure.getDrop();
  101. if (Permissions.magicHunter(player) && ItemUtils.isEnchantable(treasureDrop) && handleMagicHunter(treasureDrop)) {
  102. player.sendMessage(LocaleLoader.getString("Fishing.MagicFound"));
  103. }
  104. // Drop the original catch at the feet of the player and set the treasure as the real catch
  105. Misc.dropItem(player.getEyeLocation(), fishingCatch.getItemStack());
  106. fishingCatch.setItemStack(treasureDrop);
  107. }
  108. applyXpGain(Config.getInstance().getFishingBaseXP() + treasureXp);
  109. }
  110. /**
  111. * Handle the vanilla XP boost for Fishing
  112. *
  113. * @param experience The amount of experience initially awarded by the event
  114. * @return the modified event damage
  115. */
  116. public int handleVanillaXpBoost(int experience) {
  117. return experience * getVanillaXpMultiplier();
  118. }
  119. /**
  120. * Handle the Shake ability
  121. *
  122. * @param mob The {@link LivingEntity} affected by the ability
  123. */
  124. public void shakeCheck(LivingEntity target) {
  125. if (getShakeProbability() > Misc.getRandom().nextInt(getActivationChance())) {
  126. Map<ItemStack, Integer> possibleDrops = new HashMap<ItemStack, Integer>();
  127. Fishing.findPossibleDrops(target, possibleDrops);
  128. if (possibleDrops.isEmpty()) {
  129. return;
  130. }
  131. ItemStack drop = Fishing.chooseDrop(possibleDrops);
  132. // It's possible that chooseDrop returns null if the sum of probability in possibleDrops is inferior than 100
  133. if (drop == null) {
  134. return;
  135. }
  136. // Extra processing depending on the mob and drop type
  137. switch (target.getType()) {
  138. case SHEEP:
  139. Sheep sheep = (Sheep) target;
  140. if (drop.getType() == Material.WOOL) {
  141. if (sheep.isSheared()) {
  142. return;
  143. }
  144. drop.setDurability(sheep.getColor().getWoolData());
  145. sheep.setSheared(true);
  146. }
  147. break;
  148. case SKELETON:
  149. Skeleton skeleton = (Skeleton) target;
  150. if (skeleton.getSkeletonType() == SkeletonType.WITHER) {
  151. switch (drop.getType()) {
  152. case SKULL_ITEM:
  153. drop.setDurability((short) 1);
  154. break;
  155. case ARROW:
  156. drop.setType(Material.COAL);
  157. break;
  158. default:
  159. break;
  160. }
  161. }
  162. break;
  163. default:
  164. break;
  165. }
  166. Misc.dropItem(target.getLocation(), drop);
  167. CombatUtils.dealDamage(target, Math.max(target.getMaxHealth() / 4, 1)); // Make it so you can shake a mob no more than 4 times.
  168. }
  169. }
  170. /**
  171. * Process the Treasure Hunter ability for Fishing
  172. *
  173. * @return The {@link FishingTreasure} found, or null if no treasure was found.
  174. */
  175. private FishingTreasure getFishingTreasure() {
  176. List<FishingTreasure> rewards = new ArrayList<FishingTreasure>();
  177. int skillLevel = getSkillLevel();
  178. for (FishingTreasure treasure : TreasureConfig.getInstance().fishingRewards) {
  179. int maxLevel = treasure.getMaxLevel();
  180. if (treasure.getDropLevel() <= skillLevel && (maxLevel >= skillLevel || maxLevel <= 0)) {
  181. rewards.add(treasure);
  182. }
  183. }
  184. if (rewards.isEmpty()) {
  185. return null;
  186. }
  187. FishingTreasure treasure = rewards.get(Misc.getRandom().nextInt(rewards.size()));
  188. ItemStack treasureDrop = treasure.getDrop();
  189. if (!SkillUtils.treasureDropSuccessful(treasure.getDropChance(), activationChance)) {
  190. return null;
  191. }
  192. short maxDurability = treasureDrop.getType().getMaxDurability();
  193. if (maxDurability > 0) {
  194. treasureDrop.setDurability((short) (Misc.getRandom().nextInt(maxDurability)));
  195. }
  196. return treasure;
  197. }
  198. /**
  199. * Process the Magic Hunter ability
  200. *
  201. * @param treasureDrop The {@link ItemStack} to enchant
  202. * @return true if the item has been enchanted
  203. */
  204. private boolean handleMagicHunter(ItemStack treasureDrop) {
  205. Player player = getPlayer();
  206. int activationChance = this.activationChance;
  207. if (player.getWorld().hasStorm()) {
  208. activationChance *= Fishing.STORM_MODIFIER;
  209. }
  210. if (Misc.getRandom().nextInt(activationChance) > getLootTier() * AdvancedConfig.getInstance().getFishingMagicMultiplier()) {
  211. return false;
  212. }
  213. List<Enchantment> possibleEnchantments = new ArrayList<Enchantment>();
  214. for (Enchantment enchantment : Enchantment.values()) {
  215. if (enchantment.canEnchantItem(treasureDrop)) {
  216. possibleEnchantments.add(enchantment);
  217. }
  218. }
  219. // This make sure that the order isn't always the same, for example previously Unbreaking had a lot more chance to be used than any other enchant
  220. Collections.shuffle(possibleEnchantments, Misc.getRandom());
  221. boolean enchanted = false;
  222. int specificChance = 1;
  223. for (Enchantment possibleEnchantment : possibleEnchantments) {
  224. if (!treasureDrop.getItemMeta().hasConflictingEnchant(possibleEnchantment) && Misc.getRandom().nextInt(specificChance) == 0) {
  225. treasureDrop.addEnchantment(possibleEnchantment, Misc.getRandom().nextInt(possibleEnchantment.getMaxLevel()) + 1);
  226. specificChance++;
  227. enchanted = true;
  228. }
  229. }
  230. return enchanted;
  231. }
  232. /**
  233. * Gets the vanilla XP multiplier
  234. *
  235. * @return the vanilla XP multiplier
  236. */
  237. private int getVanillaXpMultiplier() {
  238. int skillLevel = getSkillLevel();
  239. for (Tier tier : Tier.values()) {
  240. if (skillLevel >= tier.getLevel()) {
  241. return tier.getVanillaXPBoostModifier();
  242. }
  243. }
  244. return 0;
  245. }
  246. }