RepairManager.java 15 KB

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