RepairManager.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. package com.gmail.nossr50.skills.repair;
  2. import com.gmail.nossr50.datatypes.interactions.NotificationType;
  3. import com.gmail.nossr50.datatypes.player.McMMOPlayer;
  4. import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
  5. import com.gmail.nossr50.datatypes.skills.SubSkillType;
  6. import com.gmail.nossr50.mcMMO;
  7. import com.gmail.nossr50.skills.SkillManager;
  8. import com.gmail.nossr50.util.Misc;
  9. import com.gmail.nossr50.util.Permissions;
  10. import com.gmail.nossr50.util.random.RandomChanceSkillStatic;
  11. import com.gmail.nossr50.util.skills.SkillActivationType;
  12. import com.gmail.nossr50.util.sounds.SoundManager;
  13. import com.gmail.nossr50.util.sounds.SoundType;
  14. import org.bukkit.enchantments.Enchantment;
  15. import org.bukkit.entity.Player;
  16. import org.bukkit.inventory.ItemStack;
  17. import java.util.Map;
  18. import java.util.Map.Entry;
  19. public class RepairManager extends SkillManager {
  20. private boolean placedAnvil;
  21. private int lastClick;
  22. public RepairManager(mcMMO pluginRef, McMMOPlayer mcMMOPlayer) {
  23. super(pluginRef, mcMMOPlayer, PrimarySkillType.REPAIR);
  24. }
  25. /**
  26. * Handles notifications for placing an anvil.
  27. */
  28. public void placedAnvilCheck() {
  29. Player player = getPlayer();
  30. if (getPlacedAnvil()) {
  31. return;
  32. }
  33. if (pluginRef.getConfigManager().getConfigRepair().getRepairGeneral().isAnvilMessages()) {
  34. pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Repair.Listener.Anvil");
  35. }
  36. if (pluginRef.getConfigManager().getConfigRepair().getRepairGeneral().isAnvilPlacedSounds()) {
  37. SoundManager.sendSound(player, player.getLocation(), SoundType.ANVIL);
  38. }
  39. togglePlacedAnvil();
  40. }
  41. public void handleRepair(ItemStack item) {
  42. // Player player = getPlayer();
  43. // Repairable repairable = mcMMO.getRepairableManager().getRepairable(item.getType());
  44. //
  45. // if(item.getItemMeta() != null && item.getItemMeta().isUnbreakable()) {
  46. // mcMMO.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Anvil.Unbreakable");
  47. // return;
  48. // }
  49. //
  50. // // Permissions checks on material and item types
  51. //// if (!Permissions.repairMaterialType(player, repairable.getRepairItemMaterialCategory())) {
  52. //// mcMMO.getNotificationManager().sendPlayerInformation(player, NotificationType.NO_PERMISSION, "mcMMO.NoPermission");
  53. //// return;
  54. //// }
  55. ////
  56. //// if (!Permissions.repairItemType(player, repairable.getRepairItemType())) {
  57. //// mcMMO.getNotificationManager().sendPlayerInformation(player, NotificationType.NO_PERMISSION, "mcMMO.NoPermission");
  58. //// return;
  59. //// }
  60. //
  61. // int skillLevel = getSkillLevel();
  62. // int minimumRepairableLevel = repairable.getMinimumLevel();
  63. //
  64. // // Level check
  65. // if (skillLevel < minimumRepairableLevel) {
  66. // mcMMO.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Repair.Skills.Adept", String.valueOf(minimumRepairableLevel), StringUtils.getPrettyItemString(item.getType()));
  67. // return;
  68. // }
  69. //
  70. // PlayerInventory inventory = player.getInventory();
  71. // Material repairMaterial = null;
  72. // boolean foundNonBasicMaterial = false;
  73. //
  74. // //Find the first compatible repair material
  75. // for (Material repairMaterialCandidate : repairable.getRepairMaterials()) {
  76. // for (ItemStack is : player.getInventory().getContents()) {
  77. // if(is == null)
  78. // continue; //Ignore IntelliJ this can be null
  79. //
  80. // //Match to repair material
  81. // if (is.getType() == repairMaterialCandidate) {
  82. // //Check for item meta
  83. // if(is.getItemMeta() != null) {
  84. // //Check for lore
  85. // if(is.getItemMeta().getLore() != null) {
  86. // if(is.getItemMeta().getLore().isEmpty()) {
  87. // //Lore is empty so this item is fine
  88. // repairMaterial = repairMaterialCandidate;
  89. // break;
  90. // } else {
  91. // foundNonBasicMaterial = true;
  92. // }
  93. // } else {
  94. // //No lore so this item is fine
  95. // repairMaterial = repairMaterialCandidate;
  96. // break;
  97. // }
  98. // } else {
  99. // //No Item Meta so this item is fine
  100. // repairMaterial = repairMaterialCandidate;
  101. // break;
  102. // }
  103. // }
  104. // }
  105. // }
  106. //
  107. // /* Abort the repair if no compatible basic repairing item found */
  108. // if (repairMaterial == null && foundNonBasicMaterial == true) {
  109. // player.sendMessage(pluginRef.getLocaleManager().getString("Repair.NoBasicRepairMatsFound"));
  110. // return;
  111. // }
  112. //
  113. // ItemStack toRemove = new ItemStack(repairMaterial);
  114. // toRemove.setAmount(1);
  115. //
  116. // short startDurability = item.getDurability();
  117. //
  118. // // Do not repair if at full durability
  119. // if (startDurability <= 0) {
  120. // mcMMO.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Repair.Skills.FullDurability");
  121. // return;
  122. // }
  123. //
  124. // // Clear ability buffs before trying to repair.
  125. // SkillUtils.removeAbilityBuff(item);
  126. //
  127. // // Lets get down to business,
  128. // // To defeat, the huns.
  129. // int baseRepairAmount = repairable.getBaseRepairDurability(); // Did they send me daughters?
  130. // short newDurability = repairCalculate(startDurability, baseRepairAmount); // When I asked for sons?
  131. //
  132. // // Call event
  133. // if (EventUtils.callRepairCheckEvent(player, (short) (startDurability - newDurability), toRemove, item).isCancelled()) {
  134. // return;
  135. // }
  136. //
  137. // // Handle the enchants
  138. // if (mcMMO.getConfigManager().getConfigRepair().getArcaneForging().isMayLoseEnchants() && !Permissions.hasRepairEnchantBypassPerk(player)) {
  139. // addEnchants(item);
  140. // }
  141. //
  142. // // Remove the item
  143. // inventory.removeItem(toRemove);
  144. //
  145. // // Give out XP like candy
  146. // applyXpGain(((getPercentageRepaired(startDurability, newDurability, repairable.getMaximumDurability())
  147. // * repairable.getXpMultiplier())
  148. // * mcMMO.getConfigManager().getConfigExperience().getRepairXPBase())
  149. // * mcMMO.getConfigManager().getConfigExperience().getExperienceRepair().getItemMaterialXPMultiplier(repairable.getRepairItemMaterialCategory()), XPGainReason.PVE);
  150. //
  151. // // BWONG BWONG BWONG
  152. // if (mcMMO.getConfigManager().getConfigRepair().getRepairGeneral().isAnvilUseSounds()) {
  153. // SoundManager.sendSound(player, player.getLocation(), SoundType.ANVIL);
  154. // SoundManager.sendSound(player, player.getLocation(), SoundType.ITEM_BREAK);
  155. // }
  156. //
  157. // // Repair the item!
  158. // item.setDurability(newDurability);
  159. }
  160. private double getPercentageRepaired(short startDurability, short newDurability, short totalDurability) {
  161. return ((startDurability - newDurability) / (float) totalDurability);
  162. }
  163. /**
  164. * Check if the player has tried to use an Anvil before.
  165. *
  166. * @return true if the player has confirmed using an Anvil
  167. */
  168. public boolean checkConfirmation(boolean actualize) {
  169. Player player = getPlayer();
  170. long lastUse = getLastAnvilUse();
  171. if (!pluginRef.getSkillTools().cooldownExpired(lastUse, 3) || !pluginRef.getConfigManager().getConfigRepair().getRepairGeneral().isEnchantedItemsRequireConfirm()) {
  172. return true;
  173. }
  174. if (!actualize) {
  175. return false;
  176. }
  177. actualizeLastAnvilUse();
  178. pluginRef.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Skills.ConfirmOrCancel", pluginRef.getLocaleManager().getString("Repair.Pretty.Name"));
  179. return false;
  180. }
  181. /**
  182. * Gets the Arcane Forging rank
  183. *
  184. * @return the current Arcane Forging rank
  185. */
  186. public int getArcaneForgingRank() {
  187. return pluginRef.getRankTools().getRank(getPlayer(), SubSkillType.REPAIR_ARCANE_FORGING);
  188. }
  189. /**
  190. * Gets chance of keeping enchantment during repair.
  191. *
  192. * @return The chance of keeping the enchantment
  193. */
  194. public double getKeepEnchantChance() {
  195. return pluginRef.getConfigManager().getConfigRepair().getArcaneForging().getKeepEnchantChanceMap().get(getArcaneForgingRank());
  196. }
  197. /**
  198. * Gets chance of enchantment being downgraded during repair.
  199. *
  200. * @return The chance of the enchantment being downgraded
  201. */
  202. public double getDowngradeEnchantChance() {
  203. return pluginRef.getConfigManager().getConfigRepair().getArcaneForging().getDowngradeChanceMap().get(getArcaneForgingRank());
  204. }
  205. /**
  206. * Computes repair bonuses.
  207. *
  208. * @param durability The durability of the item being repaired
  209. * @param repairAmount The base amount of durability repaired to the item
  210. * @return The final amount of durability repaired to the item
  211. */
  212. private short repairCalculate(short durability, int repairAmount) {
  213. Player player = getPlayer();
  214. if (Permissions.isSubSkillEnabled(player, SubSkillType.REPAIR_REPAIR_MASTERY)
  215. && pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.REPAIR_REPAIR_MASTERY)) {
  216. double maxBonusCalc = pluginRef.getDynamicSettingsManager().getSkillPropertiesManager().getMaxBonus(SubSkillType.REPAIR_REPAIR_MASTERY) / 100.0D;
  217. double skillLevelBonusCalc = (maxBonusCalc / pluginRef.getDynamicSettingsManager().getSkillPropertiesManager().getMaxBonusLevel(SubSkillType.REPAIR_REPAIR_MASTERY)) * (getSkillLevel() / 100.0D);
  218. double bonus = repairAmount * Math.min(skillLevelBonusCalc, maxBonusCalc);
  219. repairAmount += bonus;
  220. }
  221. if (Permissions.isSubSkillEnabled(player, SubSkillType.REPAIR_SUPER_REPAIR) && checkPlayerProcRepair()) {
  222. repairAmount *= 2.0D;
  223. }
  224. if (repairAmount <= 0 || repairAmount > Short.MAX_VALUE) {
  225. repairAmount = Short.MAX_VALUE;
  226. }
  227. return (short) Math.max(durability - repairAmount, 0);
  228. }
  229. /**
  230. * Checks for Super Repair bonus.
  231. *
  232. * @return true if bonus granted, false otherwise
  233. */
  234. private boolean checkPlayerProcRepair() {
  235. if (!pluginRef.getRankTools().hasUnlockedSubskill(getPlayer(), SubSkillType.REPAIR_SUPER_REPAIR))
  236. return false;
  237. if (pluginRef.getRandomChanceTools().isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.REPAIR_SUPER_REPAIR, getPlayer())) {
  238. pluginRef.getNotificationManager().sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Repair.Skills.FeltEasy");
  239. return true;
  240. }
  241. return false;
  242. }
  243. /**
  244. * Handles removing & downgrading enchants.
  245. *
  246. * @param item Item being repaired
  247. */
  248. private void addEnchants(ItemStack item) {
  249. Player player = getPlayer();
  250. Map<Enchantment, Integer> enchants = item.getEnchantments();
  251. if (enchants.isEmpty()) {
  252. return;
  253. }
  254. if (Permissions.arcaneBypass(player)) {
  255. pluginRef.getNotificationManager().sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Repair.Arcane.Perfect");
  256. return;
  257. }
  258. if (getArcaneForgingRank() == 0 || !Permissions.isSubSkillEnabled(player, SubSkillType.REPAIR_ARCANE_FORGING)) {
  259. for (Enchantment enchant : enchants.keySet()) {
  260. item.removeEnchantment(enchant);
  261. }
  262. pluginRef.getNotificationManager().sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE_FAILED, "Repair.Arcane.Lost");
  263. return;
  264. }
  265. boolean downgraded = false;
  266. for (Entry<Enchantment, Integer> enchant : enchants.entrySet()) {
  267. int enchantLevel = enchant.getValue();
  268. if(!pluginRef.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitRepair().isAllowUnsafeEnchants()) {
  269. if(enchantLevel > enchant.getKey().getMaxLevel()) {
  270. enchantLevel = enchant.getKey().getMaxLevel();
  271. item.addEnchantment(enchant.getKey(), enchantLevel);
  272. }
  273. }
  274. Enchantment enchantment = enchant.getKey();
  275. if (pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(getKeepEnchantChance(), getPlayer(), SubSkillType.REPAIR_ARCANE_FORGING))) {
  276. if (pluginRef.getConfigManager().getConfigRepair().getArcaneForging().isDowngradesEnabled() && enchantLevel > 1
  277. && (!pluginRef.getRandomChanceTools().checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(100 - getDowngradeEnchantChance(), getPlayer(), SubSkillType.REPAIR_ARCANE_FORGING)))) {
  278. item.addUnsafeEnchantment(enchantment, enchantLevel - 1);
  279. downgraded = true;
  280. }
  281. } else {
  282. item.removeEnchantment(enchantment);
  283. }
  284. }
  285. Map<Enchantment, Integer> newEnchants = item.getEnchantments();
  286. if (newEnchants.isEmpty()) {
  287. pluginRef.getNotificationManager().sendPlayerInformationChatOnly(getPlayer(), "Repair.Arcane.Fail");
  288. }
  289. else if (downgraded || newEnchants.size() < enchants.size()) {
  290. pluginRef.getNotificationManager().sendPlayerInformationChatOnly(getPlayer(), "Repair.Arcane.Downgrade");
  291. }
  292. else {
  293. pluginRef.getNotificationManager().sendPlayerInformationChatOnly(getPlayer(), "Repair.Arcane.Perfect");
  294. }
  295. }
  296. /*
  297. * Repair Anvil Placement
  298. */
  299. public boolean getPlacedAnvil() {
  300. return placedAnvil;
  301. }
  302. public void togglePlacedAnvil() {
  303. placedAnvil = !placedAnvil;
  304. }
  305. /*
  306. * Repair Anvil Usage
  307. */
  308. public int getLastAnvilUse() {
  309. return lastClick;
  310. }
  311. public void setLastAnvilUse(int value) {
  312. lastClick = value;
  313. }
  314. public void actualizeLastAnvilUse() {
  315. lastClick = (int) (System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR);
  316. }
  317. }