2012-05-17 15:38:16 +02:00
|
|
|
package com.gmail.nossr50.skills.repair;
|
|
|
|
|
|
|
|
import java.util.HashMap;
|
2012-05-18 02:01:37 +02:00
|
|
|
import java.util.List;
|
2012-05-17 15:38:16 +02:00
|
|
|
|
2012-05-22 10:22:29 +02:00
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.ChatColor;
|
2013-01-09 00:52:50 +01:00
|
|
|
import org.bukkit.Material;
|
2012-05-17 15:38:16 +02:00
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
import org.bukkit.inventory.ItemStack;
|
2012-05-22 10:22:29 +02:00
|
|
|
import org.bukkit.inventory.PlayerInventory;
|
|
|
|
|
|
|
|
import com.gmail.nossr50.config.Config;
|
|
|
|
import com.gmail.nossr50.datatypes.PlayerProfile;
|
|
|
|
import com.gmail.nossr50.datatypes.SkillType;
|
|
|
|
import com.gmail.nossr50.events.skills.McMMOPlayerRepairCheckEvent;
|
|
|
|
import com.gmail.nossr50.locale.LocaleLoader;
|
|
|
|
import com.gmail.nossr50.util.Misc;
|
|
|
|
import com.gmail.nossr50.util.Permissions;
|
|
|
|
import com.gmail.nossr50.util.Users;
|
2012-05-17 15:38:16 +02:00
|
|
|
|
|
|
|
public class SimpleRepairManager implements RepairManager {
|
|
|
|
private HashMap<Integer, Repairable> repairables;
|
|
|
|
|
|
|
|
protected SimpleRepairManager() {
|
|
|
|
this(55);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected SimpleRepairManager(int repairablesSize) {
|
|
|
|
this.repairables = new HashMap<Integer, Repairable>(repairablesSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void registerRepairable(Repairable repairable) {
|
2012-05-18 02:01:37 +02:00
|
|
|
Integer itemId = repairable.getItemId();
|
|
|
|
repairables.put(itemId, repairable);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void registerRepairables(List<Repairable> repairables) {
|
2012-05-23 15:35:16 +02:00
|
|
|
for (Repairable repairable : repairables) {
|
2012-05-18 02:01:37 +02:00
|
|
|
registerRepairable(repairable);
|
|
|
|
}
|
2012-05-17 15:38:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isRepairable(int itemId) {
|
2012-05-18 02:01:37 +02:00
|
|
|
return repairables.containsKey(itemId);
|
2012-05-17 15:38:16 +02:00
|
|
|
}
|
|
|
|
|
2012-05-22 08:58:55 +02:00
|
|
|
@Override
|
|
|
|
public boolean isRepairable(ItemStack itemStack) {
|
|
|
|
return isRepairable(itemStack.getTypeId());
|
|
|
|
}
|
|
|
|
|
2012-05-22 11:27:08 +02:00
|
|
|
@Override
|
|
|
|
public Repairable getRepairable(int id) {
|
|
|
|
return repairables.get(id);
|
|
|
|
}
|
|
|
|
|
2012-05-17 15:38:16 +02:00
|
|
|
@Override
|
|
|
|
public void handleRepair(Player player, ItemStack item) {
|
2012-05-22 10:22:29 +02:00
|
|
|
// Load some variables for use
|
2012-07-03 16:04:04 +02:00
|
|
|
PlayerProfile profile = Users.getProfile(player);
|
2012-05-22 10:22:29 +02:00
|
|
|
short startDurability = item.getDurability();
|
|
|
|
PlayerInventory inventory = player.getInventory();
|
2012-07-03 16:04:04 +02:00
|
|
|
int skillLevel = profile.getSkillLevel(SkillType.REPAIR);
|
2012-05-22 10:22:29 +02:00
|
|
|
Repairable repairable = repairables.get(item.getTypeId());
|
|
|
|
|
|
|
|
// Permissions checks on material and item types
|
2012-05-23 15:35:16 +02:00
|
|
|
if (!repairable.getRepairItemType().getPermissions(player)) {
|
2012-05-22 10:22:29 +02:00
|
|
|
player.sendMessage(LocaleLoader.getString("mcMMO.NoPermission"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-05-23 15:35:16 +02:00
|
|
|
if (!repairable.getRepairMaterialType().getPermissions(player)) {
|
2012-05-22 10:22:29 +02:00
|
|
|
player.sendMessage(LocaleLoader.getString("mcMMO.NoPermission"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-05-22 11:10:43 +02:00
|
|
|
// Level check
|
2012-05-23 15:35:16 +02:00
|
|
|
if (skillLevel < repairable.getMinimumLevel()) {
|
2012-05-22 11:10:43 +02:00
|
|
|
player.sendMessage(LocaleLoader.getString("Repair.Skills.Adept", new Object[] { String.valueOf(repairable.getMinimumLevel()), Misc.prettyItemString(item.getTypeId()) } ));
|
|
|
|
return;
|
|
|
|
}
|
2012-05-22 10:22:29 +02:00
|
|
|
|
|
|
|
// Check if they have the proper material to repair with
|
2012-05-23 15:35:16 +02:00
|
|
|
if (!inventory.contains(repairable.getRepairMaterialId())) {
|
2012-05-22 10:22:29 +02:00
|
|
|
String message = LocaleLoader.getString("Skills.NeedMore") + " " + ChatColor.YELLOW + Misc.prettyItemString(repairable.getRepairMaterialId());
|
2012-05-23 15:35:16 +02:00
|
|
|
if (repairable.getRepairMaterialMetadata() != (byte) -1) {
|
2012-05-22 10:22:29 +02:00
|
|
|
// TODO: Do something nicer than append the metadata as a :# ?
|
2012-05-23 15:35:16 +02:00
|
|
|
if (findInInventory(inventory, repairable.getRepairMaterialId(), repairable.getRepairMaterialMetadata()) == -1) {
|
2012-05-22 10:22:29 +02:00
|
|
|
message += ":" + repairable.getRepairMaterialMetadata();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
player.sendMessage(message);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do not repair if at full durability
|
2012-05-23 15:35:16 +02:00
|
|
|
if (startDurability <= 0) {
|
2012-05-22 10:22:29 +02:00
|
|
|
player.sendMessage(LocaleLoader.getString("Repair.Skills.FullDurability"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do not repair stacked items
|
2012-05-23 15:35:16 +02:00
|
|
|
if (item.getAmount() != 1) {
|
2012-05-22 10:22:29 +02:00
|
|
|
player.sendMessage(LocaleLoader.getString("Repair.Skills.StackedItems"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Lets get down to business,
|
|
|
|
// To defeat, the huns.
|
2012-05-23 15:35:16 +02:00
|
|
|
int baseRepairAmount = repairable.getBaseRepairDurability(); // Did they send me daughters?
|
|
|
|
short newDurability = Repair.repairCalculate(player, skillLevel, startDurability, baseRepairAmount); // When I asked for sons?
|
2012-05-22 10:22:29 +02:00
|
|
|
|
|
|
|
// We're going to hold onto our repair item location
|
|
|
|
int repairItemLocation;
|
2012-05-23 15:35:16 +02:00
|
|
|
if (repairable.getRepairMaterialMetadata() == (byte) -1) {
|
2012-05-22 10:22:29 +02:00
|
|
|
repairItemLocation = findInInventory(inventory, repairable.getRepairMaterialId());
|
2012-05-23 15:35:16 +02:00
|
|
|
}
|
|
|
|
else {
|
2012-05-22 10:22:29 +02:00
|
|
|
// Special case for when the repairable has metadata that must be addressed
|
|
|
|
repairItemLocation = findInInventory(inventory, repairable.getRepairMaterialId(), repairable.getRepairMaterialMetadata());
|
|
|
|
}
|
|
|
|
|
|
|
|
// This should never happen, but if it does we need to complain loudly about it.
|
2012-05-23 15:35:16 +02:00
|
|
|
if (repairItemLocation == -1) {
|
2012-05-22 10:22:29 +02:00
|
|
|
player.sendMessage("mcMMO encountered an error attempting to repair this item!"); // TODO: Locale ?
|
2012-05-22 10:37:41 +02:00
|
|
|
return;
|
2012-05-22 10:22:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Call event
|
|
|
|
McMMOPlayerRepairCheckEvent event = new McMMOPlayerRepairCheckEvent(player, (short) (startDurability - newDurability), inventory.getItem(repairItemLocation), item);
|
|
|
|
Bukkit.getServer().getPluginManager().callEvent(event);
|
|
|
|
|
|
|
|
if (event.isCancelled()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle the enchants
|
2013-01-07 02:52:31 +01:00
|
|
|
if (Config.getInstance().getArcaneForgingEnchantLossEnabled() && !Permissions.arcaneBypass(player)) {
|
2012-05-22 10:22:29 +02:00
|
|
|
// Generalize away enchantment work
|
|
|
|
Repair.addEnchants(player, item);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove the item
|
|
|
|
removeOneFrom(inventory, repairItemLocation);
|
|
|
|
|
2012-05-22 11:19:17 +02:00
|
|
|
// Give out XP like candy
|
2012-07-03 16:04:04 +02:00
|
|
|
Repair.xpHandler(player, profile, startDurability, newDurability, repairable.getXpMultiplier());
|
2012-05-22 11:19:17 +02:00
|
|
|
|
2012-05-22 10:22:29 +02:00
|
|
|
// Repair the item!
|
|
|
|
item.setDurability(newDurability);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Decrease the amount of items in this slot by one
|
|
|
|
*
|
|
|
|
* @param inventory PlayerInventory to work in
|
|
|
|
* @param index Item index to decrement
|
|
|
|
*/
|
|
|
|
private void removeOneFrom(PlayerInventory inventory, int index) {
|
|
|
|
ItemStack item = inventory.getItem(index);
|
2012-05-23 15:35:16 +02:00
|
|
|
if (item.getAmount() > 1) {
|
2012-05-22 10:22:29 +02:00
|
|
|
item.setAmount(item.getAmount() - 1);
|
2012-05-23 15:35:16 +02:00
|
|
|
}
|
|
|
|
else {
|
2013-01-09 00:52:50 +01:00
|
|
|
item = new ItemStack(Material.AIR);
|
2012-05-22 10:22:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// I suspect this may not be needed, but I don't think it hurts
|
|
|
|
inventory.setItem(index, item);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Search the inventory for an item and return the index.
|
|
|
|
*
|
|
|
|
* @param inventory PlayerInventory to scan
|
|
|
|
* @param itemId Item id to look for
|
|
|
|
* @return index location where the item was found, or -1 if not found
|
|
|
|
*/
|
|
|
|
private int findInInventory(PlayerInventory inventory, int itemId) {
|
|
|
|
int location = inventory.first(itemId);
|
2012-05-23 15:35:16 +02:00
|
|
|
|
2012-05-22 10:22:29 +02:00
|
|
|
// VALIDATE
|
2012-05-23 15:35:16 +02:00
|
|
|
if (inventory.getItem(location).getTypeId() == itemId) {
|
2012-05-22 10:22:29 +02:00
|
|
|
return location;
|
2012-05-23 15:35:16 +02:00
|
|
|
}
|
|
|
|
else {
|
2012-05-22 10:22:29 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Search the inventory for an item and return the index.
|
|
|
|
*
|
|
|
|
* @param inventory PlayerInventory to scan
|
|
|
|
* @param itemId Item id to look for
|
|
|
|
* @param metadata Metadata to look for
|
|
|
|
* @return index location where the item was found, or -1 if not found
|
|
|
|
*/
|
|
|
|
private int findInInventory(PlayerInventory inventory, int itemId, byte metadata) {
|
|
|
|
int location = -1;
|
|
|
|
|
|
|
|
ItemStack[] contents = inventory.getContents();
|
2012-05-23 15:35:16 +02:00
|
|
|
for (int i = 0; i < contents.length; i++) {
|
2012-05-22 10:22:29 +02:00
|
|
|
ItemStack item = contents[i];
|
2012-06-07 00:27:52 +02:00
|
|
|
|
2012-06-07 00:02:22 +02:00
|
|
|
if (item == null) {
|
2012-06-07 00:27:52 +02:00
|
|
|
continue;
|
2012-06-07 00:02:22 +02:00
|
|
|
}
|
|
|
|
|
2012-05-23 15:35:16 +02:00
|
|
|
if (item.getTypeId() == itemId) {
|
|
|
|
if (item.getData().getData() == metadata) {
|
2012-05-22 10:22:29 +02:00
|
|
|
location = i;
|
|
|
|
}
|
|
|
|
}
|
2012-06-07 00:27:52 +02:00
|
|
|
|
2012-05-23 15:35:16 +02:00
|
|
|
if (location != -1) {
|
|
|
|
break;
|
|
|
|
}
|
2012-05-22 10:22:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return location;
|
2012-05-17 15:38:16 +02:00
|
|
|
}
|
|
|
|
}
|