diff --git a/lib/CitizensAPI.jar b/lib/CitizensAPI.jar index 7f4734eea..cc7cd37b9 100644 Binary files a/lib/CitizensAPI.jar and b/lib/CitizensAPI.jar differ diff --git a/src/net/citizensnpcs/Citizens.java b/src/net/citizensnpcs/Citizens.java index bcacb9cf7..d5a263add 100644 --- a/src/net/citizensnpcs/Citizens.java +++ b/src/net/citizensnpcs/Citizens.java @@ -33,6 +33,7 @@ import net.citizensnpcs.npc.CitizensNPCManager; import net.citizensnpcs.storage.DatabaseStorage; import net.citizensnpcs.storage.Storage; import net.citizensnpcs.storage.YamlStorage; +import net.citizensnpcs.trait.Inventory; import net.citizensnpcs.trait.LookClose; import net.citizensnpcs.util.Messaging; import net.citizensnpcs.util.StringHelper; @@ -55,7 +56,7 @@ public class Citizens extends JavaPlugin { @SuppressWarnings("unchecked") private static final List> defaultTraits = Lists.newArrayList(Owner.class, Spawned.class, - LookClose.class, SpawnLocation.class); + LookClose.class, SpawnLocation.class, Inventory.class); private volatile CitizensNPCManager npcManager; private final InstanceFactory characterManager = new DefaultInstanceFactory(); diff --git a/src/net/citizensnpcs/npc/CitizensNPC.java b/src/net/citizensnpcs/npc/CitizensNPC.java index b5d41c657..758d87092 100644 --- a/src/net/citizensnpcs/npc/CitizensNPC.java +++ b/src/net/citizensnpcs/npc/CitizensNPC.java @@ -7,11 +7,14 @@ import net.citizensnpcs.api.npc.trait.trait.SpawnLocation; import net.citizensnpcs.api.npc.trait.trait.Spawned; import net.citizensnpcs.npc.ai.CitizensAI; import net.citizensnpcs.util.Messaging; + import net.minecraft.server.EntityLiving; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.PlayerInventory; public abstract class CitizensNPC extends AbstractNPC { protected final CitizensNPCManager manager; @@ -88,6 +91,18 @@ public abstract class CitizensNPC extends AbstractNPC { return true; } + @Override + public PlayerInventory getInventory() { + throw new UnsupportedOperationException("not implemented yet"); + } + + @Override + public boolean openInventory(Player player) { + if (!isSpawned()) + return false; + throw new UnsupportedOperationException("not implemented yet"); + } + public void update() { ai.update(); } diff --git a/src/net/citizensnpcs/trait/Inventory.java b/src/net/citizensnpcs/trait/Inventory.java new file mode 100644 index 000000000..0c6e4325e --- /dev/null +++ b/src/net/citizensnpcs/trait/Inventory.java @@ -0,0 +1,112 @@ +package net.citizensnpcs.trait; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; + +import net.citizensnpcs.api.DataKey; +import net.citizensnpcs.api.exception.NPCLoadException; +import net.citizensnpcs.api.npc.trait.SaveId; +import net.citizensnpcs.api.npc.trait.Trait; + +@SaveId("inventory") +public class Inventory implements Trait { + private ItemStack[] contents; + private ItemStack helmet; + private ItemStack chestplate; + private ItemStack leggings; + private ItemStack boots; + + public Inventory() { + } + + public Inventory(org.bukkit.inventory.PlayerInventory inventory) { + contents = inventory.getContents(); + helmet = inventory.getHelmet(); + chestplate = inventory.getChestplate(); + leggings = inventory.getLeggings(); + boots = inventory.getBoots(); + } + + public ItemStack[] getContents() { + return contents; + } + + public ItemStack[] getArmorContents() { + ItemStack[] armor = new ItemStack[4]; + armor[0] = helmet; + armor[1] = chestplate; + armor[2] = leggings; + armor[3] = boots; + return armor; + } + + @Override + public void load(DataKey key) throws NPCLoadException { + contents = parseContents(key); + // Armor + helmet = getItemStack(key.getRelative("armor.helmet")); + chestplate = getItemStack(key.getRelative("armor.chestplate")); + leggings = getItemStack(key.getRelative("armor.leggings")); + boots = getItemStack(key.getRelative("armor.boots")); + } + + @Override + public void save(DataKey key) { + int index = 0; + for (ItemStack item : contents) + saveItem(item, key.getRelative(String.valueOf(index++))); + + DataKey armorKey = key.getRelative("armor"); + saveItem(helmet, armorKey.getRelative("helmet")); + saveItem(chestplate, armorKey.getRelative("chestplate")); + saveItem(leggings, armorKey.getRelative("leggings")); + saveItem(boots, armorKey.getRelative("boots")); + } + + private ItemStack[] parseContents(DataKey key) throws NPCLoadException { + ItemStack[] contents = new ItemStack[36]; + for (DataKey slotKey : key.getIntegerSubKeys()) { + contents[Integer.parseInt(slotKey.name())] = getItemStack(slotKey); + } + return contents; + } + + private ItemStack getItemStack(DataKey key) throws NPCLoadException { + try { + ItemStack item = new ItemStack(Material.getMaterial(key.getString("name")), key.getInt("amount"), + (short) key.getLong("data")); + if (key.keyExists("enchantments")) { + Map enchantments = new HashMap(); + for (DataKey subKey : key.getRelative("enchantments").getSubKeys()) { + Enchantment enchantment = Enchantment.getByName(subKey.name().toUpperCase().replace('-', '_')); + if (enchantment != null) + enchantments.put(enchantment, subKey.getInt("")); + } + item.addEnchantments(enchantments); + } + return item; + } catch (Exception ex) { + throw new NPCLoadException("Invalid item."); + } + } + + private void saveItem(ItemStack item, DataKey key) { + key.setString("name", item.getType().toString()); + key.setInt("amount", item.getAmount()); + key.setLong("data", item.getDurability()); + + for (Enchantment enchantment : item.getEnchantments().keySet()) + key.getRelative("enchantments").setInt(enchantment.getName().toLowerCase().replace('_', '-'), + item.getEnchantmentLevel(enchantment)); + } + + @Override + public String toString() { + return "Inventory{contents:" + contents + "; helmet:" + helmet + "; chestplate:" + chestplate + "; leggings:" + + leggings + "; boots:" + boots + "}"; + } +} \ No newline at end of file