From b41a30fa26d88fab76161d9aeae432ed115a5a79 Mon Sep 17 00:00:00 2001 From: nossr50 Date: Wed, 19 Jun 2019 23:28:11 -0700 Subject: [PATCH] Repair rewrite continues --- pom.xml | 11 +++- .../com/gmail/nossr50/api/ExperienceAPI.java | 1 - .../gmail/nossr50/bukkit/BukkitFactory.java | 19 ++++++ .../gmail/nossr50/config/ConfigManager.java | 4 +- .../serializers/RepairWildcardSerializer.java | 12 ++-- .../serializers/RepairableSerializer.java | 6 +- .../hocon/skills/repair/ConfigRepair.java | 12 ++-- .../datatypes/items/BukkitMMOItem.java | 61 +++++++++++++++++ .../datatypes/items/CustomItemMatching.java | 13 ++++ .../datatypes/items/CustomItemTarget.java | 62 +++++++++++++++++ .../datatypes/items/ItemMatchProperty.java | 33 ++++++++++ .../datatypes/items/ItemWildcards.java | 61 +++++++++++++++++ .../nossr50/datatypes/items/MMOItem.java | 40 +++++++++++ .../nossr50/datatypes/nbt/MMOEntity.java | 13 ++++ .../nossr50/datatypes/nbt/NBTHolder.java | 26 ++++++++ .../nossr50/skills/repair/RepairCost.java | 10 ++- .../nossr50/skills/repair/RepairCostItem.java | 51 -------------- .../skills/repair/RepairCostWildcard.java | 36 +++++----- .../skills/repair/RepairTransaction.java | 16 +++-- .../nossr50/skills/repair/RepairWildcard.java | 43 ------------ .../skills/repair/SimpleRepairCost.java | 66 +++++++++++++++++++ .../skills/repair/repairables/Repairable.java | 20 +++--- .../repair/repairables/RepairableBuilder.java | 12 ++-- .../com/gmail/nossr50/util/nbt/NBTUtils.java | 20 ++++++ .../com/gmail/nossr50/util/nbt/RawNBT.java | 18 ++++- 25 files changed, 511 insertions(+), 155 deletions(-) create mode 100644 src/main/java/com/gmail/nossr50/bukkit/BukkitFactory.java create mode 100644 src/main/java/com/gmail/nossr50/datatypes/items/BukkitMMOItem.java create mode 100644 src/main/java/com/gmail/nossr50/datatypes/items/CustomItemMatching.java create mode 100644 src/main/java/com/gmail/nossr50/datatypes/items/CustomItemTarget.java create mode 100644 src/main/java/com/gmail/nossr50/datatypes/items/ItemMatchProperty.java create mode 100644 src/main/java/com/gmail/nossr50/datatypes/items/ItemWildcards.java create mode 100644 src/main/java/com/gmail/nossr50/datatypes/items/MMOItem.java create mode 100644 src/main/java/com/gmail/nossr50/datatypes/nbt/MMOEntity.java create mode 100644 src/main/java/com/gmail/nossr50/datatypes/nbt/NBTHolder.java delete mode 100644 src/main/java/com/gmail/nossr50/skills/repair/RepairCostItem.java delete mode 100644 src/main/java/com/gmail/nossr50/skills/repair/RepairWildcard.java create mode 100644 src/main/java/com/gmail/nossr50/skills/repair/SimpleRepairCost.java diff --git a/pom.xml b/pom.xml index f1190a920..47051dfcc 100755 --- a/pom.xml +++ b/pom.xml @@ -216,10 +216,15 @@ org.spigotmc - spigot-api - 1.14.2-R0.1-SNAPSHOT - provided + spigot + 1.13.2-R0.1-SNAPSHOT + + + + + + com.sk89q.worldguard worldguard-core diff --git a/src/main/java/com/gmail/nossr50/api/ExperienceAPI.java b/src/main/java/com/gmail/nossr50/api/ExperienceAPI.java index 9174e56fb..1dda0b349 100644 --- a/src/main/java/com/gmail/nossr50/api/ExperienceAPI.java +++ b/src/main/java/com/gmail/nossr50/api/ExperienceAPI.java @@ -629,7 +629,6 @@ public final class ExperienceAPI { * @param skillType The skill to get the level for * @return the level of a given skill * @throws InvalidSkillException if the given skill is not valid - * @deprecated Use getLevel(Player player, PrimarySkillType skillType) instead */ @Deprecated public static int getLevel(Player player, String skillType) { diff --git a/src/main/java/com/gmail/nossr50/bukkit/BukkitFactory.java b/src/main/java/com/gmail/nossr50/bukkit/BukkitFactory.java new file mode 100644 index 000000000..c7a14586e --- /dev/null +++ b/src/main/java/com/gmail/nossr50/bukkit/BukkitFactory.java @@ -0,0 +1,19 @@ +package com.gmail.nossr50.bukkit; + +import com.gmail.nossr50.datatypes.items.BukkitMMOItem; +import com.gmail.nossr50.util.nbt.RawNBT; + +/** + * Used to convert or construct platform independent types into Bukkit types + */ +public class BukkitFactory { + + /** + * Creates a BukkitMMOItem which contains Bukkit implementations for the type MMOItem + * @return a new BukkitMMOItem + */ + public static BukkitMMOItem createBukkitMMOItem(String namespaceKey, int amount, RawNBT rawNBT) { + return new BukkitMMOItem(namespaceKey, amount, rawNBT); + } + +} diff --git a/src/main/java/com/gmail/nossr50/config/ConfigManager.java b/src/main/java/com/gmail/nossr50/config/ConfigManager.java index b2ef4d934..14f682fcb 100644 --- a/src/main/java/com/gmail/nossr50/config/ConfigManager.java +++ b/src/main/java/com/gmail/nossr50/config/ConfigManager.java @@ -39,7 +39,7 @@ import com.gmail.nossr50.config.hocon.skills.ranks.SkillRankProperty; import com.gmail.nossr50.config.hocon.skills.repair.ConfigRepair; import com.gmail.nossr50.skills.repair.RepairCost; import com.gmail.nossr50.skills.repair.RepairTransaction; -import com.gmail.nossr50.skills.repair.RepairWildcard; +import com.gmail.nossr50.datatypes.items.ItemWildcards; import com.gmail.nossr50.config.hocon.skills.salvage.ConfigSalvage; import com.gmail.nossr50.config.hocon.skills.smelting.ConfigSmelting; import com.gmail.nossr50.config.hocon.skills.swords.ConfigSwords; @@ -280,7 +280,7 @@ public final class ConfigManager { customSerializers.registerType(TypeToken.of(PlayerNotificationSettings.class), new PlayerNotificationSerializer()); customSerializers.registerType(TypeToken.of(SoundSetting.class), new SoundSettingSerializer()); customSerializers.registerType(TypeToken.of(ItemStack.class), new ItemStackSerializer()); - customSerializers.registerType(TypeToken.of(RepairWildcard.class), new RepairWildcardSerializer()); + customSerializers.registerType(TypeToken.of(ItemWildcards.class), new RepairWildcardSerializer()); customSerializers.registerType(TypeToken.of(RepairCost.class), new RepairCostSerializer()); customSerializers.registerType(TypeToken.of(RepairTransaction.class), new RepairTransactionSerializer()); } diff --git a/src/main/java/com/gmail/nossr50/config/hocon/serializers/RepairWildcardSerializer.java b/src/main/java/com/gmail/nossr50/config/hocon/serializers/RepairWildcardSerializer.java index 6d3219d40..af6e14a12 100644 --- a/src/main/java/com/gmail/nossr50/config/hocon/serializers/RepairWildcardSerializer.java +++ b/src/main/java/com/gmail/nossr50/config/hocon/serializers/RepairWildcardSerializer.java @@ -1,6 +1,6 @@ package com.gmail.nossr50.config.hocon.serializers; -import com.gmail.nossr50.skills.repair.RepairWildcard; +import com.gmail.nossr50.datatypes.items.ItemWildcards; import com.google.common.reflect.TypeToken; import ninja.leaping.configurate.ConfigurationNode; import ninja.leaping.configurate.ValueType; @@ -12,30 +12,30 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.util.Set; -public class RepairWildcardSerializer implements TypeSerializer { +public class RepairWildcardSerializer implements TypeSerializer { private static final String WILDCARD_IDENTIFIER_NAME = "Wildcard-Identifier-Name"; private static final String MATCHING_ITEMS = "Matching-Items"; @Nullable @Override - public RepairWildcard deserialize(@NonNull TypeToken type, @NonNull ConfigurationNode value) throws ObjectMappingException { + public ItemWildcards deserialize(@NonNull TypeToken type, @NonNull ConfigurationNode value) throws ObjectMappingException { String wildCardName = value.getNode(WILDCARD_IDENTIFIER_NAME).getValue(TypeToken.of(String.class)); if(value.getNode(WILDCARD_IDENTIFIER_NAME).getNode(MATCHING_ITEMS).getValueType() != ValueType.NULL) { Set matchCandidates = value.getNode(WILDCARD_IDENTIFIER_NAME).getNode(MATCHING_ITEMS).getValue(new TypeToken>() {}); - return new RepairWildcard(wildCardName, matchCandidates); + return new ItemWildcards(wildCardName, matchCandidates); } return null; } @Override - public void serialize(@NonNull TypeToken type, @Nullable RepairWildcard obj, @NonNull ConfigurationNode value) throws ObjectMappingException { + public void serialize(@NonNull TypeToken type, @Nullable ItemWildcards obj, @NonNull ConfigurationNode value) throws ObjectMappingException { value.getNode(WILDCARD_IDENTIFIER_NAME).setValue(obj.getWildcardName()); - value.getNode(WILDCARD_IDENTIFIER_NAME).getNode(MATCHING_ITEMS).setValue(obj.getMatchingItems()); + value.getNode(WILDCARD_IDENTIFIER_NAME).getNode(MATCHING_ITEMS).setValue(obj.getItemTargets()); } } diff --git a/src/main/java/com/gmail/nossr50/config/hocon/serializers/RepairableSerializer.java b/src/main/java/com/gmail/nossr50/config/hocon/serializers/RepairableSerializer.java index a6c1ef385..948d5fbb4 100644 --- a/src/main/java/com/gmail/nossr50/config/hocon/serializers/RepairableSerializer.java +++ b/src/main/java/com/gmail/nossr50/config/hocon/serializers/RepairableSerializer.java @@ -24,7 +24,7 @@ public class RepairableSerializer implements TypeSerializer { private static final String STRICT_MATCH_ITEM = "Strict-Match-Item"; private static final String STRICT_MATCHING_REPAIR_TRANSACTION = "Strict-Matching-Repair-Transaction"; private static final String REPAIR_COUNT = "Repair-Count"; - private static final String NBT = "NBT"; +// private static final String NBT = "NBT"; private static final String PERMISSION = "Permission"; private static final String MINIMUM_LEVEL = "Minimum-Level"; @@ -34,7 +34,7 @@ public class RepairableSerializer implements TypeSerializer { RepairableBuilder builder = new RepairableBuilder(itemStack) .repairTransaction(value.getNode(REPAIR_TRANSACTION).getValue(TypeToken.of(RepairTransaction.class))) .strictMatchingItem(value.getNode(STRICT_MATCH_ITEM).getValue(TypeToken.of(Boolean.class))) - .strictMatchingRepairTransaction(value.getNode(STRICT_MATCHING_REPAIR_TRANSACTION).getValue(TypeToken.of(Boolean.class))) +// .strictMatchingRepairTransaction(value.getNode(STRICT_MATCHING_REPAIR_TRANSACTION).getValue(TypeToken.of(Boolean.class))) .baseXP(value.getNode(BASE_XP).getValue(TypeToken.of(Integer.class))) .repairCount(value.getNode(REPAIR_COUNT).getValue(TypeToken.of(Integer.class))); @@ -58,7 +58,7 @@ public class RepairableSerializer implements TypeSerializer { value.getNode(ITEM).setValue(obj.getItem()); value.getNode(REPAIR_TRANSACTION).setValue(obj.getRepairTransaction()); value.getNode(STRICT_MATCH_ITEM).setValue(obj.isStrictMatchingItem()); - value.getNode(STRICT_MATCHING_REPAIR_TRANSACTION).setValue(obj.isStrictMatchingRepairTransaction()); +// value.getNode(STRICT_MATCHING_REPAIR_TRANSACTION).setValue(obj.isStrictMatchingRepairTransaction()); value.getNode(BASE_XP).setValue(obj.getBaseXP()); value.getNode(REPAIR_COUNT).setValue(obj.getRepairCount()); diff --git a/src/main/java/com/gmail/nossr50/config/hocon/skills/repair/ConfigRepair.java b/src/main/java/com/gmail/nossr50/config/hocon/skills/repair/ConfigRepair.java index 3bc5d2770..04a7b1940 100644 --- a/src/main/java/com/gmail/nossr50/config/hocon/skills/repair/ConfigRepair.java +++ b/src/main/java/com/gmail/nossr50/config/hocon/skills/repair/ConfigRepair.java @@ -4,7 +4,7 @@ import com.gmail.nossr50.config.ConfigConstants; import com.gmail.nossr50.config.hocon.skills.repair.general.ConfigRepairGeneral; import com.gmail.nossr50.config.hocon.skills.repair.repairmastery.ConfigRepairRepairMastery; import com.gmail.nossr50.config.hocon.skills.repair.subskills.ConfigRepairSubSkills; -import com.gmail.nossr50.skills.repair.RepairWildcard; +import com.gmail.nossr50.datatypes.items.ItemWildcards; import com.gmail.nossr50.skills.repair.repairables.Repairable; import ninja.leaping.configurate.objectmapping.Setting; import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable; @@ -18,7 +18,7 @@ import static org.bukkit.Material.*; public class ConfigRepair { public static final ArrayList CONFIG_REPAIRABLES_DEFAULTS; - public static final HashSet REPAIR_WILDCARDS_DEFAULTS; + public static final HashSet REPAIR_WILDCARDS_DEFAULTS; // public static final Material[] PLANKS = new Material[]{OAK_PLANKS, BIRCH_PLANKS, DARK_OAK_PLANKS, ACACIA_PLANKS, JUNGLE_PLANKS, SPRUCE_PLANKS}; static { @@ -28,7 +28,7 @@ public class ConfigRepair { new ItemStack(BIRCH_PLANKS, 1), new ItemStack(DARK_OAK_PLANKS, 1), new ItemStack(ACACIA_PLANKS, 1), new ItemStack(JUNGLE_PLANKS, 1), new ItemStack(SPRUCE_PLANKS, 1)}); - RepairWildcard planksWildCard = new RepairWildcard("Planks", new HashSet<>(planksList)); + ItemWildcards planksWildCard = new ItemWildcards("Planks", new HashSet<>(planksList)); REPAIR_WILDCARDS_DEFAULTS.add(planksWildCard); CONFIG_REPAIRABLES_DEFAULTS = new ArrayList<>(); @@ -102,7 +102,7 @@ public class ConfigRepair { private ArrayList configRepairablesList = CONFIG_REPAIRABLES_DEFAULTS; @Setting(value = "Z-Repairables-Wildcards", comment = "Used to define an alias that can be matched to several materials.") - private HashSet repairWildcards = new HashSet<>(); + private HashSet itemWildcards = new HashSet<>(); public ConfigRepairGeneral getRepairGeneral() { return repairGeneral; @@ -128,7 +128,7 @@ public class ConfigRepair { return configRepairablesList; } - public HashSet getRepairWildcards() { - return repairWildcards; + public HashSet getItemWildcards() { + return itemWildcards; } } \ No newline at end of file diff --git a/src/main/java/com/gmail/nossr50/datatypes/items/BukkitMMOItem.java b/src/main/java/com/gmail/nossr50/datatypes/items/BukkitMMOItem.java new file mode 100644 index 000000000..af73759cb --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/items/BukkitMMOItem.java @@ -0,0 +1,61 @@ +package com.gmail.nossr50.datatypes.items; + +import com.gmail.nossr50.util.nbt.RawNBT; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +public class BukkitMMOItem implements MMOItem { + + private ItemStack itemImplementation; + private RawNBT rawNBT; + + public BukkitMMOItem(String namespaceKey, int amount, RawNBT rawNBT) throws NullPointerException { + ItemStack itemStack; + Material material = Material.matchMaterial(namespaceKey); + + if(material == null) { + throw new NullPointerException("Material for user defined item could not be found in the server software."); + } + + itemStack = new ItemStack(material); + + //Get default item meta + ItemMeta itemMeta = Bukkit.getItemFactory().getItemMeta(itemStack.getType()); + + //Set default item meta + itemStack.setItemMeta(itemMeta); + + //Set amount + itemStack.setAmount(amount); + + //Set item implementation + this.itemImplementation = itemStack; + + //Set raw NBT + if(rawNBT != null) + this.rawNBT = rawNBT; + } + + @Override + public ItemStack getItemImplementation() { + return itemImplementation; + } + + @Override + public String getNamespaceKey() { + return itemImplementation.getType().getKey().toString(); + } + + @Override + public int getItemAmount() { + return itemImplementation.getAmount(); + } + + @Override + public RawNBT getRawNBT() { + return rawNBT; + } + +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/items/CustomItemMatching.java b/src/main/java/com/gmail/nossr50/datatypes/items/CustomItemMatching.java new file mode 100644 index 000000000..827894b89 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/items/CustomItemMatching.java @@ -0,0 +1,13 @@ +package com.gmail.nossr50.datatypes.items; + +public interface CustomItemMatching { + + /** + * Determines whether or not an item matches this one + * Behaviours for matching can vary based on the implementation + * @param otherItem target item to compare itself to + * @return true if this item matches the target item + */ + boolean isMatch(MMOItem otherItem); + +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/items/CustomItemTarget.java b/src/main/java/com/gmail/nossr50/datatypes/items/CustomItemTarget.java new file mode 100644 index 000000000..e8c4eb2ac --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/items/CustomItemTarget.java @@ -0,0 +1,62 @@ +package com.gmail.nossr50.datatypes.items; + +import java.util.HashSet; + +/** + * This type contains data and rules which govern equating equivalency between one item and another in Minecraft. + * + * In mcMMO it is sometimes needed to match one item to another, but items contain a lot of metadata + * Some of this metadata is important, some of it isn't, and whether something is important or not when + * considering two items to be similar enough to be considered matching items is not strictly defined and is in fact different from server to server. + * + * mcMMO employs a flexible system where users can define which properties of an items metadata (often its NBT) + * are important for matching and mcMMO will respect those properties when comparing one item to another. + * + * If a user does not define a property as being important for matching mcMMO will ignore that property when matching + * two or more items, even if that property is not equivalent between the items. This type will contain information + * on which properties are to be considered important for matching purposes. + * + * The main goal of this system is accommodate for the vast majority of custom item modifications a server can employ, + * these custom items are often defined in irregular ways server to server, thus why this type was made. + * + * In summary, this type serves several purposes... + * 1) Abstract away platform specific implementations of MC Items + * 2) Contain information about an item and which properties of said item that are considered important and thus will be used to equate equivalency to another item when doing comparisons + */ +public class CustomItemTarget implements CustomItemMatching { + + private MMOItem item; //Abstract representation of the item + private HashSet itemMatchProperties; //Item properties used for matching + + public CustomItemTarget(MMOItem item) { + this.item = item; + itemMatchProperties = new HashSet<>(); + } + + public CustomItemTarget(MMOItem item, HashSet itemMatchProperties) { + this.item = item; + this.itemMatchProperties = itemMatchProperties; + } + + public MMOItem getItem() { + return item; + } + + public HashSet getItemMatchProperties() { + return itemMatchProperties; + } + + /** + * Determines whether or not an item matches this one + * Behaviours for matching can vary based on the implementation + * @param otherItem target item to compare itself to + * @return true if this item matches the target item + */ + @Override + public boolean isMatch(MMOItem otherItem) { + //First compare the basic things that need to match between each item + if(item.equals(otherItem)) { + + } + } +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/items/ItemMatchProperty.java b/src/main/java/com/gmail/nossr50/datatypes/items/ItemMatchProperty.java new file mode 100644 index 000000000..b7061dfbf --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/items/ItemMatchProperty.java @@ -0,0 +1,33 @@ +package com.gmail.nossr50.datatypes.items; + +/** + * Represents a property of an item which is used in strict matching + * Typically this represents and NBT field and its value + * All NBT entries have an ID and a value, this value can be one of many types + */ +public class ItemMatchProperty { + + final private Object propertyValue; + final private String nbtID; + + public ItemMatchProperty(Object propertyValue, String nbtID) { + this.propertyValue = propertyValue; + this.nbtID = nbtID; + } + + /** + * The expected value for this NBT entry + * @return the expected value for this NBT entry + */ + public Object getPropertyValue() { + return propertyValue; + } + + /** + * The ID (name) of this NBT entry + * @return the ID (name) of this NBT entry + */ + public String getID() { + return nbtID; + } +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/items/ItemWildcards.java b/src/main/java/com/gmail/nossr50/datatypes/items/ItemWildcards.java new file mode 100644 index 000000000..2c37b5d08 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/items/ItemWildcards.java @@ -0,0 +1,61 @@ +package com.gmail.nossr50.datatypes.items; + +import org.bukkit.inventory.ItemStack; + +import java.util.HashSet; +import java.util.Objects; + +/** + * Represents a series of items that are all acceptable inputs for a behaviour + * Wildcards have a unique name that defines them, no two wildcards should share the same name. + * The name is important as it is used to identify the wildcard to the player. + * + * One example of the purpose of this Datatype: + * + * As an example, in Repair users are allowed to define a repair cost that can specify wildcards + * One such example is wood planks, many variants exist in Minecraft and they can all be used to repair Wooden tools + * + * ItemWildcards is a flexible datatype and won't be used just for Repair, but at the time of writing it was created + * to solve a problem with Repair. Given its flexible nature it can be used for many purposes. + * + */ +public class ItemWildcards { + + private String wildcardName; + private HashSet itemTargets; + + public ItemWildcards(String wildcardName, HashSet itemTargets) { + this.wildcardName = wildcardName; + this.itemTargets = itemTargets; + } + + public int getItemCount() { + return itemTargets.size(); + } + + public HashSet getItemTargets() { + return itemTargets; + } + + public void setItemTargets(HashSet itemTargets) { + this.itemTargets = itemTargets; + } + + public String getWildcardName() { + return wildcardName; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ItemWildcards)) return false; + ItemWildcards that = (ItemWildcards) o; + return getWildcardName().equals(that.getWildcardName()) && + getItemTargets().equals(that.getItemTargets()); + } + + @Override + public int hashCode() { + return Objects.hash(getWildcardName(), getItemTargets()); + } +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/items/MMOItem.java b/src/main/java/com/gmail/nossr50/datatypes/items/MMOItem.java new file mode 100644 index 000000000..62d00cf16 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/items/MMOItem.java @@ -0,0 +1,40 @@ +package com.gmail.nossr50.datatypes.items; + +import com.gmail.nossr50.util.nbt.RawNBT; + +/** + * Represents the abstracted form of an item in Minecraft which can be used to construct an item implementation per platform + * Return types of this object are not platform specific + * Only requires a namespace key to be defined, all other properties will be default initialized + */ +public interface MMOItem { + + /** + * Gets the item implementation of this type for this object + * @return the item implementation + */ + T getItemImplementation(); + + /** + * Get the Minecraft fully qualified namespace (FQN) key for this item + * Typically the FQN will read like this 'minecraft:name_here' + * @return the fully qualified namespace key for this item + */ + String getNamespaceKey(); + + /** + * Get the amount of this Item + * Items in Minecraft are technically stacks of items with the minimum amount being 1 in most cases + * The amount is used for matching purposes, and should default to 1 if undefined + * @return the amount for this Item + */ + int getItemAmount(); + + /** + * Get the RawNBT for this item if it has any + * This can be null + * @return the raw NBT if it exists, null otherwise + */ + RawNBT getRawNBT(); + +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/nbt/MMOEntity.java b/src/main/java/com/gmail/nossr50/datatypes/nbt/MMOEntity.java new file mode 100644 index 000000000..869807a6b --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/nbt/MMOEntity.java @@ -0,0 +1,13 @@ +package com.gmail.nossr50.datatypes.nbt; + +/** + * Platform independent representation of a Entity in Minecraft + * @param the platform specific type of this Entity + */ +public interface MMOEntity { + /** + * Get the platform specific implementation of this entity + * @return the platform specific implementation of this entity + */ + T getImplementation(); +} diff --git a/src/main/java/com/gmail/nossr50/datatypes/nbt/NBTHolder.java b/src/main/java/com/gmail/nossr50/datatypes/nbt/NBTHolder.java new file mode 100644 index 000000000..5aba7ae30 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/datatypes/nbt/NBTHolder.java @@ -0,0 +1,26 @@ +package com.gmail.nossr50.datatypes.nbt; + +import com.gmail.nossr50.util.nbt.RawNBT; + +/** + * Many things in Minecraft make use of the NBT System + * You can read about the NBT System here - https://wiki.vg/NBT + * + * Types that support NBT will implement this interface + */ +public interface NBTHolder { + + /** + * Get the RawNBT for this object + * @return the RawNBT for this object + */ + RawNBT getRawNBT(); + + /** + * Determine whether or not this object has the specific NBT entry and matching value + * @param id the ID fof the NBT entry + * @param value the value of the NBT entry + * @return returns true if the NBT of id exists and its value matches + */ + boolean hasNBTValue(String id, Object value); +} diff --git a/src/main/java/com/gmail/nossr50/skills/repair/RepairCost.java b/src/main/java/com/gmail/nossr50/skills/repair/RepairCost.java index 1b8ea0836..d2392e78c 100644 --- a/src/main/java/com/gmail/nossr50/skills/repair/RepairCost.java +++ b/src/main/java/com/gmail/nossr50/skills/repair/RepairCost.java @@ -11,9 +11,15 @@ public interface RepairCost { /** * Searches a player inventory for a matching ItemStack that can be used to pay for the repair transaction * @param playerInventory inventory of player attempting to pay the cost - * @param strictMatching whether or not to match repair cost items strictly with items in a players inventory * @return any compatible payment items if found */ - ItemStack findPayment(PlayerInventory playerInventory, boolean strictMatching); + ItemStack findPayment(PlayerInventory playerInventory); + + /** + * Whether or not this repair cost is strictly matched + * Strict matching compares Items by using metadata and material type + * @return true if the RepairCost uses strict matching + */ + boolean hasStrictMatching(); } diff --git a/src/main/java/com/gmail/nossr50/skills/repair/RepairCostItem.java b/src/main/java/com/gmail/nossr50/skills/repair/RepairCostItem.java deleted file mode 100644 index 963eb4e12..000000000 --- a/src/main/java/com/gmail/nossr50/skills/repair/RepairCostItem.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.gmail.nossr50.skills.repair; - -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; - -import java.util.Objects; - -public class RepairCostItem implements RepairCost { - - private ItemStack repairCostItem; - - public RepairCostItem(ItemStack repairCostItem) { - this.repairCostItem = repairCostItem; - } - - @Override - public ItemStack findPayment(PlayerInventory playerInventory, boolean strictMatching) { - for(ItemStack itemStack : playerInventory.getContents()) { - if(itemStack == null || itemStack.getType() == Material.AIR) { - continue; - } - - //Attempt to match the item in the inventory to any of the compatible repair items - if(strictMatching) { - //TODO: Replace with strict matching code - if(itemStack.isSimilar(repairCostItem)) - return itemStack; - } else { - if(itemStack.getType() == repairCostItem.getType()) { - return itemStack; - } - } - } - - return null; - } - - @Override - public int hashCode() { - return Objects.hash(repairCostItem); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof RepairCostItem)) return false; - RepairCostItem that = (RepairCostItem) o; - return repairCostItem.equals(that.repairCostItem); - } -} diff --git a/src/main/java/com/gmail/nossr50/skills/repair/RepairCostWildcard.java b/src/main/java/com/gmail/nossr50/skills/repair/RepairCostWildcard.java index 27b834bdb..04d4c6ad3 100644 --- a/src/main/java/com/gmail/nossr50/skills/repair/RepairCostWildcard.java +++ b/src/main/java/com/gmail/nossr50/skills/repair/RepairCostWildcard.java @@ -1,9 +1,12 @@ package com.gmail.nossr50.skills.repair; +import com.gmail.nossr50.datatypes.items.ItemWildcards; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; +import java.util.HashSet; + /** * Represents a piece of a RepairTransaction * Multiple RepairCost pieces are used to pay for a RepairTransaction @@ -12,25 +15,28 @@ import org.bukkit.inventory.PlayerInventory; */ public class RepairCostWildcard implements RepairCost { - private RepairWildcard repairWildcard; + private HashSet simpleRepairCosts; + private ItemWildcards itemWildcards; + + + public RepairCostWildcard(ItemWildcards itemWildcards) { + this.itemWildcards = itemWildcards; + simpleRepairCosts = new HashSet<>(); + + for(ItemStack itemStack : ) + } @Override - public ItemStack findPayment(PlayerInventory playerInventory, boolean strictMatching) { + public ItemStack findPayment(PlayerInventory playerInventory) { for(ItemStack itemStack : playerInventory.getContents()) { if(itemStack == null || itemStack.getType() == Material.AIR) { continue; } - for(ItemStack wildCardItem : repairWildcard.getMatchingItems()) { + for(SimpleRepairCost simpleRepairCost : simpleRepairCosts) { //Attempt to match the item in the inventory to any of the compatible repair items - if(strictMatching) { - //TODO: Replace with strict matching code - if(itemStack.isSimilar(wildCardItem)) - return itemStack; - } else { - if(itemStack.getType() == wildCardItem.getType()) { - return itemStack; - } + if(simpleRepairCost.findPayment(playerInventory) != null) { + return simpleRepairCost.findPayment(playerInventory); } } } @@ -38,12 +44,12 @@ public class RepairCostWildcard implements RepairCost { return null; } - public RepairWildcard getRepairWildcard() { - return repairWildcard; + public ItemWildcards getItemWildcards() { + return itemWildcards; } - public void setRepairWildcard(RepairWildcard repairWildcard) { - this.repairWildcard = repairWildcard; + public void setItemWildcards(ItemWildcards itemWildcards) { + this.itemWildcards = itemWildcards; } } diff --git a/src/main/java/com/gmail/nossr50/skills/repair/RepairTransaction.java b/src/main/java/com/gmail/nossr50/skills/repair/RepairTransaction.java index 11b5d28eb..009122dd5 100644 --- a/src/main/java/com/gmail/nossr50/skills/repair/RepairTransaction.java +++ b/src/main/java/com/gmail/nossr50/skills/repair/RepairTransaction.java @@ -4,10 +4,18 @@ package com.gmail.nossr50.skills.repair; import java.util.HashSet; /** - * Represents a complete repair transaction - * A repair transaction is made up of a multiple RepairCost objects - * A RepairCost object is used to find a matching ItemStack in a players inventory if one exists - * A RepairCost object can be a single item or it can be multiple items representing a range of compatible items to pay that part of the RepairTransaction + * Represents a complete "repair transaction" + * + * I will define a "repair transaction" as such + * - The items used to pay the cost of repairing an item in mcMMO via the Repair Skill + * + * A single "RepairTransaction" is made up of a multiple RepairCost objects + * No two RepairCosts contained within this type can be exact duplicates + * + * A RepairCost is used to find a matching ItemStack in a players inventory if one exists to pay its cost + * + * A RepairCost can be a single item or it can be multiple items representing a range of compatible items + * to pay that part of the RepairTransaction */ public class RepairTransaction { private HashSet repairItems; diff --git a/src/main/java/com/gmail/nossr50/skills/repair/RepairWildcard.java b/src/main/java/com/gmail/nossr50/skills/repair/RepairWildcard.java deleted file mode 100644 index 34244353d..000000000 --- a/src/main/java/com/gmail/nossr50/skills/repair/RepairWildcard.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.gmail.nossr50.skills.repair; - -import org.bukkit.inventory.ItemStack; - -import java.util.Objects; -import java.util.Set; - -public class RepairWildcard { - - private String wildcardName; - private Set matchingItems; - - public RepairWildcard(String wildcardName, Set matchingItems) { - this.wildcardName = wildcardName; - this.matchingItems = matchingItems; - } - - public Set getMatchingItems() { - return matchingItems; - } - - public void setMatchingItems(Set matchingItems) { - this.matchingItems = matchingItems; - } - - public String getWildcardName() { - return wildcardName; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof RepairWildcard)) return false; - RepairWildcard that = (RepairWildcard) o; - return getWildcardName().equals(that.getWildcardName()) && - getMatchingItems().equals(that.getMatchingItems()); - } - - @Override - public int hashCode() { - return Objects.hash(getWildcardName(), getMatchingItems()); - } -} diff --git a/src/main/java/com/gmail/nossr50/skills/repair/SimpleRepairCost.java b/src/main/java/com/gmail/nossr50/skills/repair/SimpleRepairCost.java new file mode 100644 index 000000000..232c30807 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/skills/repair/SimpleRepairCost.java @@ -0,0 +1,66 @@ +package com.gmail.nossr50.skills.repair; + +import com.gmail.nossr50.datatypes.items.ItemMatchProperty; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +import java.util.Objects; + +/** + * Implementation of RepairCost + *

+ * A SimpleRepairCost can be one or more items, any one of which can be used to pay for a RepairTransaction + * If a SimpleRepairCost is more than one item, then only one of the items are required to represent its cost. + * + * This type is strictly for use with RepairTransaction, which represents the full cost of a Repair. + * @see com.gmail.nossr50.skills.repair.RepairTransaction for more details + */ +public class SimpleRepairCost implements RepairCost { + + private ItemMatchProperty itemMatchProperty; + + public SimpleRepairCost(ItemMatchProperty itemMatchProperty) { + this.itemMatchProperty = itemMatchProperty; + } + + @Override + public ItemStack findPayment(PlayerInventory playerInventory) { + for(ItemStack itemStack : playerInventory.getContents()) { + if(itemStack == null || itemStack.getType() == Material.AIR) { + continue; + } + + //Attempt to match the item in the inventory to any of the compatible repair items + if(hasStrictMatching()) { + //TODO: Replace with strict matching code + if(item) + return itemStack; + } else { + if(itemStack.getType() == itemMatchProperty.getType()) { + return itemStack; + } + } + } + + return null; + } + + @Override + public int hashCode() { + return Objects.hash(itemMatchProperty); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof SimpleRepairCost)) return false; + SimpleRepairCost that = (SimpleRepairCost) o; + return itemMatchProperty.equals(that.itemMatchProperty); + } + + @Override + public boolean hasStrictMatching() { + return strictMatching; + } +} diff --git a/src/main/java/com/gmail/nossr50/skills/repair/repairables/Repairable.java b/src/main/java/com/gmail/nossr50/skills/repair/repairables/Repairable.java index f70287509..acf4dff93 100644 --- a/src/main/java/com/gmail/nossr50/skills/repair/repairables/Repairable.java +++ b/src/main/java/com/gmail/nossr50/skills/repair/repairables/Repairable.java @@ -12,7 +12,7 @@ public class Repairable { private short maximumDurability; private RepairTransaction repairTransaction; private boolean strictMatchingItem = false; - private boolean strictMatchingRepairTransaction = false; +// private boolean strictMatchingRepairTransaction = false; private int baseXP = 0; private RawNBT rawNBT; private int repairCount = 1; @@ -20,13 +20,13 @@ public class Repairable { private boolean hasPermission = false; private boolean hasNBT = false; - public Repairable(ItemStack item, int minimumLevel, short maximumDurability, RepairTransaction repairTransaction, boolean strictMatchingItem, boolean strictMatchingRepairTransaction, int baseXP, int repairCount) { + public Repairable(ItemStack item, int minimumLevel, short maximumDurability, RepairTransaction repairTransaction, boolean strictMatchingItem, int baseXP, int repairCount) { this.item = item; this.minimumLevel = minimumLevel; this.maximumDurability = maximumDurability; this.repairTransaction = repairTransaction; this.strictMatchingItem = strictMatchingItem; - this.strictMatchingRepairTransaction = strictMatchingRepairTransaction; +// this.strictMatchingRepairTransaction = strictMatchingRepairTransaction; this.baseXP = baseXP; this.repairCount = repairCount; } @@ -67,13 +67,13 @@ public class Repairable { this.strictMatchingItem = strictMatchingItem; } - public boolean isStrictMatchingRepairTransaction() { - return strictMatchingRepairTransaction; - } - - public void setStrictMatchingRepairTransaction(boolean strictMatchingRepairTransaction) { - this.strictMatchingRepairTransaction = strictMatchingRepairTransaction; - } +// public boolean isStrictMatchingRepairTransaction() { +// return strictMatchingRepairTransaction; +// } +// +// public void setStrictMatchingRepairTransaction(boolean strictMatchingRepairTransaction) { +// this.strictMatchingRepairTransaction = strictMatchingRepairTransaction; +// } public int getBaseXP() { return baseXP; diff --git a/src/main/java/com/gmail/nossr50/skills/repair/repairables/RepairableBuilder.java b/src/main/java/com/gmail/nossr50/skills/repair/repairables/RepairableBuilder.java index 38c8835a0..7699a03b1 100644 --- a/src/main/java/com/gmail/nossr50/skills/repair/repairables/RepairableBuilder.java +++ b/src/main/java/com/gmail/nossr50/skills/repair/repairables/RepairableBuilder.java @@ -12,7 +12,7 @@ public class RepairableBuilder { private short maximumDurability; private RepairTransaction repairTransaction; private boolean strictMatchingItem = false; - private boolean strictMatchingRepairTransaction = false; +// private boolean strictMatchingRepairTransaction = false; private int baseXP = 0; private RawNBT rawNBT; private int repairCount = 1; @@ -43,10 +43,10 @@ public class RepairableBuilder { return this; } - public RepairableBuilder strictMatchingRepairTransaction(Boolean strictMatchingRepairTransaction) { - this.strictMatchingRepairTransaction = strictMatchingRepairTransaction; - return this; - } +// public RepairableBuilder strictMatchingRepairTransaction(Boolean strictMatchingRepairTransaction) { +// this.strictMatchingRepairTransaction = strictMatchingRepairTransaction; +// return this; +// } public RepairableBuilder baseXP(Integer baseXP) { this.baseXP = baseXP; @@ -74,7 +74,7 @@ public class RepairableBuilder { private Repairable makeRepairable() { Repairable repairable = new Repairable(item, minimumLevel, maximumDurability, repairTransaction, - strictMatchingItem, strictMatchingRepairTransaction, baseXP, repairCount); + strictMatchingItem, baseXP, repairCount); if(permissionWrapper != null) { repairable.setPermissionWrapper(permissionWrapper); diff --git a/src/main/java/com/gmail/nossr50/util/nbt/NBTUtils.java b/src/main/java/com/gmail/nossr50/util/nbt/NBTUtils.java index 3659a75f4..29d2e7c23 100644 --- a/src/main/java/com/gmail/nossr50/util/nbt/NBTUtils.java +++ b/src/main/java/com/gmail/nossr50/util/nbt/NBTUtils.java @@ -1,6 +1,26 @@ package com.gmail.nossr50.util.nbt; +import com.gmail.nossr50.mcMMO; +import net.minecraft.server.v1_13_R2.NBTBase; +import org.bukkit.craftbukkit.v1_13_R2.entity.CraftItem; +import org.bukkit.craftbukkit.v1_13_R2.util.CraftNBTTagConfigSerializer; +import org.bukkit.inventory.ItemStack; + public class NBTUtils { + public RawNBT constructNBT(String nbtString) { + try { + return new RawNBT(nbtString, CraftNBTTagConfigSerializer.deserialize(nbtString)); + } catch (Exception e) { + e.printStackTrace(); + mcMMO.p.getLogger().severe("mcMMO was unable parse the NBT string from your config! Double check that it is proper NBT!"); + return null; + } + } + + public boolean hasNBT(ItemStack itemStack) { + if(CraftItem) + } + } diff --git a/src/main/java/com/gmail/nossr50/util/nbt/RawNBT.java b/src/main/java/com/gmail/nossr50/util/nbt/RawNBT.java index 22cee492b..2f5754e5a 100644 --- a/src/main/java/com/gmail/nossr50/util/nbt/RawNBT.java +++ b/src/main/java/com/gmail/nossr50/util/nbt/RawNBT.java @@ -1,10 +1,22 @@ package com.gmail.nossr50.util.nbt; -public class RawNBT { - String nbtContents; +/** + * A simple class that acts as a container for raw NBT data + * NBT data will be constructed from the raw NBT string using server internals + * This type is mostly used to take a raw string of NBT and transform it into the NBT data type used by internals + * the transformed data can then be used to check NBT data of entities in Minecraft + * + * One use of this type is as follows + * 1) Read partial or complete NBT from the config file for an item + * 2) Check an items NBT tree for this NBT data during runtime once transformed + */ +public class RawNBT { + private String nbtContents; + private T nbtTree; //Will be constructed using server internals to make matching NBT easier - public RawNBT(String nbtContents) { + public RawNBT(String nbtContents, T nbtTree) { this.nbtContents = nbtContents; + NBTUtils } public String getNbtContents() {