SimpleRepairManager.java 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. package com.gmail.nossr50.skills.repair;
  2. import java.util.HashMap;
  3. import java.util.List;
  4. import org.bukkit.Bukkit;
  5. import org.bukkit.ChatColor;
  6. import org.bukkit.entity.Player;
  7. import org.bukkit.inventory.ItemStack;
  8. import org.bukkit.inventory.PlayerInventory;
  9. import com.gmail.nossr50.config.Config;
  10. import com.gmail.nossr50.datatypes.PlayerProfile;
  11. import com.gmail.nossr50.datatypes.SkillType;
  12. import com.gmail.nossr50.events.skills.McMMOPlayerRepairCheckEvent;
  13. import com.gmail.nossr50.locale.LocaleLoader;
  14. import com.gmail.nossr50.util.Misc;
  15. import com.gmail.nossr50.util.Permissions;
  16. import com.gmail.nossr50.util.Users;
  17. public class SimpleRepairManager implements RepairManager {
  18. private HashMap<Integer, Repairable> repairables;
  19. protected SimpleRepairManager() {
  20. this(55);
  21. }
  22. protected SimpleRepairManager(int repairablesSize) {
  23. this.repairables = new HashMap<Integer, Repairable>(repairablesSize);
  24. }
  25. @Override
  26. public void registerRepairable(Repairable repairable) {
  27. Integer itemId = repairable.getItemId();
  28. repairables.put(itemId, repairable);
  29. }
  30. @Override
  31. public void registerRepairables(List<Repairable> repairables) {
  32. for (Repairable repairable : repairables) {
  33. registerRepairable(repairable);
  34. }
  35. }
  36. @Override
  37. public boolean isRepairable(int itemId) {
  38. return repairables.containsKey(itemId);
  39. }
  40. @Override
  41. public boolean isRepairable(ItemStack itemStack) {
  42. return isRepairable(itemStack.getTypeId());
  43. }
  44. @Override
  45. public Repairable getRepairable(int id) {
  46. return repairables.get(id);
  47. }
  48. @Override
  49. public void handleRepair(Player player, ItemStack item) {
  50. // Load some variables for use
  51. PlayerProfile profile = Users.getProfile(player);
  52. short startDurability = item.getDurability();
  53. PlayerInventory inventory = player.getInventory();
  54. int skillLevel = profile.getSkillLevel(SkillType.REPAIR);
  55. Repairable repairable = repairables.get(item.getTypeId());
  56. // Permissions checks on material and item types
  57. if (!repairable.getRepairItemType().getPermissions(player)) {
  58. player.sendMessage(LocaleLoader.getString("mcMMO.NoPermission"));
  59. return;
  60. }
  61. if (!repairable.getRepairMaterialType().getPermissions(player)) {
  62. player.sendMessage(LocaleLoader.getString("mcMMO.NoPermission"));
  63. return;
  64. }
  65. // Level check
  66. if (skillLevel < repairable.getMinimumLevel()) {
  67. player.sendMessage(LocaleLoader.getString("Repair.Skills.Adept", new Object[] { String.valueOf(repairable.getMinimumLevel()), Misc.prettyItemString(item.getTypeId()) } ));
  68. return;
  69. }
  70. // Check if they have the proper material to repair with
  71. if (!inventory.contains(repairable.getRepairMaterialId())) {
  72. String message = LocaleLoader.getString("Skills.NeedMore") + " " + ChatColor.YELLOW + Misc.prettyItemString(repairable.getRepairMaterialId());
  73. if (repairable.getRepairMaterialMetadata() != (byte) -1) {
  74. // TODO: Do something nicer than append the metadata as a :# ?
  75. if (findInInventory(inventory, repairable.getRepairMaterialId(), repairable.getRepairMaterialMetadata()) == -1) {
  76. message += ":" + repairable.getRepairMaterialMetadata();
  77. }
  78. }
  79. player.sendMessage(message);
  80. return;
  81. }
  82. // Do not repair if at full durability
  83. if (startDurability <= 0) {
  84. player.sendMessage(LocaleLoader.getString("Repair.Skills.FullDurability"));
  85. return;
  86. }
  87. // Do not repair stacked items
  88. if (item.getAmount() != 1) {
  89. player.sendMessage(LocaleLoader.getString("Repair.Skills.StackedItems"));
  90. return;
  91. }
  92. // Lets get down to business,
  93. // To defeat, the huns.
  94. int baseRepairAmount = repairable.getBaseRepairDurability(); // Did they send me daughters?
  95. short newDurability = Repair.repairCalculate(player, skillLevel, startDurability, baseRepairAmount); // When I asked for sons?
  96. // We're going to hold onto our repair item location
  97. int repairItemLocation;
  98. if (repairable.getRepairMaterialMetadata() == (byte) -1) {
  99. repairItemLocation = findInInventory(inventory, repairable.getRepairMaterialId());
  100. }
  101. else {
  102. // Special case for when the repairable has metadata that must be addressed
  103. repairItemLocation = findInInventory(inventory, repairable.getRepairMaterialId(), repairable.getRepairMaterialMetadata());
  104. }
  105. // This should never happen, but if it does we need to complain loudly about it.
  106. if (repairItemLocation == -1) {
  107. player.sendMessage("mcMMO encountered an error attempting to repair this item!"); // TODO: Locale ?
  108. return;
  109. }
  110. // Call event
  111. McMMOPlayerRepairCheckEvent event = new McMMOPlayerRepairCheckEvent(player, (short) (startDurability - newDurability), inventory.getItem(repairItemLocation), item);
  112. Bukkit.getServer().getPluginManager().callEvent(event);
  113. if (event.isCancelled()) {
  114. return;
  115. }
  116. // Handle the enchants
  117. if (Config.getInstance().getArcaneForgingEnchantLossEnabled() && !Permissions.arcaneBypass(player)) {
  118. // Generalize away enchantment work
  119. Repair.addEnchants(player, item);
  120. }
  121. // Remove the item
  122. removeOneFrom(inventory, repairItemLocation);
  123. // Give out XP like candy
  124. Repair.xpHandler(player, profile, startDurability, newDurability, repairable.getXpMultiplier());
  125. // Repair the item!
  126. item.setDurability(newDurability);
  127. }
  128. /**
  129. * Decrease the amount of items in this slot by one
  130. *
  131. * @param inventory PlayerInventory to work in
  132. * @param index Item index to decrement
  133. */
  134. private void removeOneFrom(PlayerInventory inventory, int index) {
  135. ItemStack item = inventory.getItem(index);
  136. if (item.getAmount() > 1) {
  137. item.setAmount(item.getAmount() - 1);
  138. }
  139. else {
  140. item = new ItemStack(0);
  141. }
  142. // I suspect this may not be needed, but I don't think it hurts
  143. inventory.setItem(index, item);
  144. }
  145. /**
  146. * Search the inventory for an item and return the index.
  147. *
  148. * @param inventory PlayerInventory to scan
  149. * @param itemId Item id to look for
  150. * @return index location where the item was found, or -1 if not found
  151. */
  152. private int findInInventory(PlayerInventory inventory, int itemId) {
  153. int location = inventory.first(itemId);
  154. // VALIDATE
  155. if (inventory.getItem(location).getTypeId() == itemId) {
  156. return location;
  157. }
  158. else {
  159. return -1;
  160. }
  161. }
  162. /**
  163. * Search the inventory for an item and return the index.
  164. *
  165. * @param inventory PlayerInventory to scan
  166. * @param itemId Item id to look for
  167. * @param metadata Metadata to look for
  168. * @return index location where the item was found, or -1 if not found
  169. */
  170. private int findInInventory(PlayerInventory inventory, int itemId, byte metadata) {
  171. int location = -1;
  172. ItemStack[] contents = inventory.getContents();
  173. for (int i = 0; i < contents.length; i++) {
  174. ItemStack item = contents[i];
  175. if (item == null) {
  176. continue;
  177. }
  178. if (item.getTypeId() == itemId) {
  179. if (item.getData().getData() == metadata) {
  180. location = i;
  181. }
  182. }
  183. if (location != -1) {
  184. break;
  185. }
  186. }
  187. return location;
  188. }
  189. }