From c13cd3893f2b44390882ebac36fdf0179461e4f0 Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Fri, 30 Dec 2022 20:57:38 -0500 Subject: [PATCH] Should replace repairMaterials in ItemMapping --- .../updater/AnvilInventoryUpdater.java | 22 ++-- .../geysermc/geyser/item/ArmorMaterial.java | 48 ++++++++ .../java/org/geysermc/geyser/item/Items.java | 115 +++++++++--------- .../geyser/item/components/ToolTier.java | 27 ++-- .../geysermc/geyser/item/type/ArmorItem.java | 42 +++++++ .../geysermc/geyser/item/type/ElytraItem.java | 39 ++++++ .../org/geysermc/geyser/item/type/Item.java | 27 ++-- .../geysermc/geyser/item/type/ShieldItem.java | 40 ++++++ .../geysermc/geyser/item/type/TieredItem.java | 19 ++- .../CustomItemRegistryPopulator.java | 16 ++- .../populator/ItemRegistryPopulator.java | 4 - .../geyser/registry/type/ItemMapping.java | 8 +- 12 files changed, 292 insertions(+), 115 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/item/ArmorMaterial.java create mode 100644 core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java create mode 100644 core/src/main/java/org/geysermc/geyser/item/type/ElytraItem.java create mode 100644 core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java diff --git a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java index f8709406b..c92724100 100644 --- a/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java +++ b/core/src/main/java/org/geysermc/geyser/inventory/updater/AnvilInventoryUpdater.java @@ -31,14 +31,14 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.ListTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.github.steveice10.opennbt.tag.builtin.Tag; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntMaps; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.cloudburstmc.nbt.NbtMap; import org.cloudburstmc.nbt.NbtMapBuilder; import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId; import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData; import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntMaps; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.geysermc.geyser.GeyserImpl; import org.geysermc.geyser.inventory.AnvilContainer; import org.geysermc.geyser.inventory.GeyserItemStack; @@ -53,7 +53,6 @@ import org.geysermc.geyser.translator.text.MessageTranslator; import org.geysermc.geyser.util.ItemUtils; import java.util.Objects; -import java.util.Set; public class AnvilInventoryUpdater extends InventoryUpdater { public static final AnvilInventoryUpdater INSTANCE = new AnvilInventoryUpdater(); @@ -142,7 +141,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater { GeyserItemStack material = anvilContainer.getMaterial(); if (!material.isEmpty()) { - if (!input.isEmpty() && isRepairing(session, input, material)) { + if (!input.isEmpty() && isRepairing(input, material)) { // Changing the repair cost on the material item makes it non-stackable return 0; } @@ -235,7 +234,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater { // Can't repair or merge enchantments return -1; } - } else if (hasDurability(input) && isRepairing(session, input, material)) { + } else if (hasDurability(input) && isRepairing(input, material)) { cost = calcRepairLevelCost(input, material); if (cost == -1) { // No damage to repair @@ -308,9 +307,9 @@ public class AnvilInventoryUpdater extends InventoryUpdater { */ private int calcMergeEnchantmentCost(GeyserSession session, GeyserItemStack input, GeyserItemStack material, boolean bedrock) { boolean hasCompatible = false; - Object2IntMap combinedEnchantments = getEnchantments(session, input, bedrock); + Object2IntMap combinedEnchantments = getEnchantments(input, bedrock); int cost = 0; - for (Object2IntMap.Entry entry : getEnchantments(session, material, bedrock).object2IntEntrySet()) { + for (Object2IntMap.Entry entry : getEnchantments(material, bedrock).object2IntEntrySet()) { JavaEnchantment enchantment = entry.getKey(); EnchantmentData data = Registries.ENCHANTMENTS.get(enchantment); if (data == null) { @@ -369,7 +368,7 @@ public class AnvilInventoryUpdater extends InventoryUpdater { return cost; } - private Object2IntMap getEnchantments(GeyserSession session, GeyserItemStack itemStack, boolean bedrock) { + private Object2IntMap getEnchantments(GeyserItemStack itemStack, boolean bedrock) { if (itemStack.getNbt() == null) { return Object2IntMaps.emptyMap(); } @@ -415,9 +414,8 @@ public class AnvilInventoryUpdater extends InventoryUpdater { return isEnchantedBook(material) || (input.getJavaId() == material.getJavaId() && hasDurability(input)); } - private boolean isRepairing(GeyserSession session, GeyserItemStack input, GeyserItemStack material) { - Set repairMaterials = input.getMapping(session).getRepairMaterials(); - return repairMaterials != null && repairMaterials.contains(material.asItem().javaIdentifier()); + private boolean isRepairing(GeyserItemStack input, GeyserItemStack material) { + return input.asItem().isValidRepairItem(material.asItem()); } private boolean isRenaming(GeyserSession session, AnvilContainer anvilContainer, boolean bedrock) { diff --git a/core/src/main/java/org/geysermc/geyser/item/ArmorMaterial.java b/core/src/main/java/org/geysermc/geyser/item/ArmorMaterial.java new file mode 100644 index 000000000..adb72350d --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/item/ArmorMaterial.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.item; + +import org.geysermc.geyser.item.type.Item; + +public enum ArmorMaterial { + LEATHER(Items.LEATHER), + CHAIN(Items.IRON_INGOT), + IRON(Items.IRON_INGOT), + GOLD(Items.GOLD_INGOT), + DIAMOND(Items.DIAMOND), + TURTLE(Items.SCUTE), + NETHERITE(Items.NETHERITE_INGOT); + + private final Item repairIngredient; + + ArmorMaterial(Item repairIngredient) { + this.repairIngredient = repairIngredient; + } + + public Item getRepairIngredient() { + return repairIngredient; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/item/Items.java b/core/src/main/java/org/geysermc/geyser/item/Items.java index fa74c8aca..8c7a43223 100644 --- a/core/src/main/java/org/geysermc/geyser/item/Items.java +++ b/core/src/main/java/org/geysermc/geyser/item/Items.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.item; +import org.geysermc.geyser.item.components.ToolTier; import org.geysermc.geyser.item.type.*; import org.geysermc.geyser.registry.Registries; @@ -746,7 +747,7 @@ public final class Items { public static final Item HOPPER_MINECART = register(new Item("hopper_minecart", builder().stackSize(1))); public static final Item CARROT_ON_A_STICK = register(new Item("carrot_on_a_stick", builder().stackSize(1).maxDamage(25))); public static final Item WARPED_FUNGUS_ON_A_STICK = register(new Item("warped_fungus_on_a_stick", builder().stackSize(1).maxDamage(100))); - public static final Item ELYTRA = register(new Item("elytra", builder().stackSize(1).maxDamage(432))); + public static final ElytraItem ELYTRA = register(new ElytraItem("elytra", builder().stackSize(1).maxDamage(432))); public static final Item OAK_BOAT = register(new Item("oak_boat", builder().stackSize(1))); public static final Item OAK_CHEST_BOAT = register(new Item("oak_chest_boat", builder().stackSize(1))); public static final Item SPRUCE_BOAT = register(new Item("spruce_boat", builder().stackSize(1))); @@ -765,7 +766,7 @@ public final class Items { public static final Item BAMBOO_CHEST_RAFT = register(new Item("bamboo_chest_raft", builder().stackSize(1))); public static final Item STRUCTURE_BLOCK = register(new Item("structure_block", builder())); public static final Item JIGSAW = register(new Item("jigsaw", builder())); - public static final Item TURTLE_HELMET = register(new Item("turtle_helmet", builder().stackSize(1).maxDamage(275))); + public static final ArmorItem TURTLE_HELMET = register(new ArmorItem("turtle_helmet", ArmorMaterial.TURTLE, builder().stackSize(1).maxDamage(275))); public static final Item SCUTE = register(new Item("scute", builder())); public static final Item FLINT_AND_STEEL = register(new Item("flint_and_steel", builder().stackSize(1).maxDamage(64))); public static final Item APPLE = register(new Item("apple", builder())); @@ -786,36 +787,36 @@ public final class Items { public static final Item GOLD_INGOT = register(new Item("gold_ingot", builder())); public static final Item NETHERITE_INGOT = register(new Item("netherite_ingot", builder())); public static final Item NETHERITE_SCRAP = register(new Item("netherite_scrap", builder())); - public static final TieredItem WOODEN_SWORD = register(new TieredItem("wooden_sword", builder().stackSize(1).maxDamage(59))); - public static final TieredItem WOODEN_SHOVEL = register(new TieredItem("wooden_shovel", builder().stackSize(1).maxDamage(59))); - public static final TieredItem WOODEN_PICKAXE = register(new TieredItem("wooden_pickaxe", builder().stackSize(1).maxDamage(59))); - public static final TieredItem WOODEN_AXE = register(new TieredItem("wooden_axe", builder().stackSize(1).maxDamage(59))); - public static final TieredItem WOODEN_HOE = register(new TieredItem("wooden_hoe", builder().stackSize(1).maxDamage(59))); - public static final TieredItem STONE_SWORD = register(new TieredItem("stone_sword", builder().stackSize(1).maxDamage(131))); - public static final TieredItem STONE_SHOVEL = register(new TieredItem("stone_shovel", builder().stackSize(1).maxDamage(131))); - public static final TieredItem STONE_PICKAXE = register(new TieredItem("stone_pickaxe", builder().stackSize(1).maxDamage(131))); - public static final TieredItem STONE_AXE = register(new TieredItem("stone_axe", builder().stackSize(1).maxDamage(131))); - public static final TieredItem STONE_HOE = register(new TieredItem("stone_hoe", builder().stackSize(1).maxDamage(131))); - public static final TieredItem GOLDEN_SWORD = register(new TieredItem("golden_sword", builder().stackSize(1).maxDamage(32))); - public static final TieredItem GOLDEN_SHOVEL = register(new TieredItem("golden_shovel", builder().stackSize(1).maxDamage(32))); - public static final TieredItem GOLDEN_PICKAXE = register(new TieredItem("golden_pickaxe", builder().stackSize(1).maxDamage(32))); - public static final TieredItem GOLDEN_AXE = register(new TieredItem("golden_axe", builder().stackSize(1).maxDamage(32))); - public static final TieredItem GOLDEN_HOE = register(new TieredItem("golden_hoe", builder().stackSize(1).maxDamage(32))); - public static final TieredItem IRON_SWORD = register(new TieredItem("iron_sword", builder().stackSize(1).maxDamage(250))); - public static final TieredItem IRON_SHOVEL = register(new TieredItem("iron_shovel", builder().stackSize(1).maxDamage(250))); - public static final TieredItem IRON_PICKAXE = register(new TieredItem("iron_pickaxe", builder().stackSize(1).maxDamage(250))); - public static final TieredItem IRON_AXE = register(new TieredItem("iron_axe", builder().stackSize(1).maxDamage(250))); - public static final TieredItem IRON_HOE = register(new TieredItem("iron_hoe", builder().stackSize(1).maxDamage(250))); - public static final TieredItem DIAMOND_SWORD = register(new TieredItem("diamond_sword", builder().stackSize(1).maxDamage(1561))); - public static final TieredItem DIAMOND_SHOVEL = register(new TieredItem("diamond_shovel", builder().stackSize(1).maxDamage(1561))); - public static final TieredItem DIAMOND_PICKAXE = register(new TieredItem("diamond_pickaxe", builder().stackSize(1).maxDamage(1561))); - public static final TieredItem DIAMOND_AXE = register(new TieredItem("diamond_axe", builder().stackSize(1).maxDamage(1561))); - public static final TieredItem DIAMOND_HOE = register(new TieredItem("diamond_hoe", builder().stackSize(1).maxDamage(1561))); - public static final TieredItem NETHERITE_SWORD = register(new TieredItem("netherite_sword", builder().stackSize(1).maxDamage(2031))); - public static final TieredItem NETHERITE_SHOVEL = register(new TieredItem("netherite_shovel", builder().stackSize(1).maxDamage(2031))); - public static final TieredItem NETHERITE_PICKAXE = register(new TieredItem("netherite_pickaxe", builder().stackSize(1).maxDamage(2031))); - public static final TieredItem NETHERITE_AXE = register(new TieredItem("netherite_axe", builder().stackSize(1).maxDamage(2031))); - public static final TieredItem NETHERITE_HOE = register(new TieredItem("netherite_hoe", builder().stackSize(1).maxDamage(2031))); + public static final TieredItem WOODEN_SWORD = register(new TieredItem("wooden_sword", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); + public static final TieredItem WOODEN_SHOVEL = register(new TieredItem("wooden_shovel", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); + public static final TieredItem WOODEN_PICKAXE = register(new TieredItem("wooden_pickaxe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); + public static final TieredItem WOODEN_AXE = register(new TieredItem("wooden_axe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); + public static final TieredItem WOODEN_HOE = register(new TieredItem("wooden_hoe", ToolTier.WOODEN, builder().stackSize(1).maxDamage(59))); + public static final TieredItem STONE_SWORD = register(new TieredItem("stone_sword", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); + public static final TieredItem STONE_SHOVEL = register(new TieredItem("stone_shovel", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); + public static final TieredItem STONE_PICKAXE = register(new TieredItem("stone_pickaxe", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); + public static final TieredItem STONE_AXE = register(new TieredItem("stone_axe", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); + public static final TieredItem STONE_HOE = register(new TieredItem("stone_hoe", ToolTier.STONE, builder().stackSize(1).maxDamage(131))); + public static final TieredItem GOLDEN_SWORD = register(new TieredItem("golden_sword", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); + public static final TieredItem GOLDEN_SHOVEL = register(new TieredItem("golden_shovel", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); + public static final TieredItem GOLDEN_PICKAXE = register(new TieredItem("golden_pickaxe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); + public static final TieredItem GOLDEN_AXE = register(new TieredItem("golden_axe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); + public static final TieredItem GOLDEN_HOE = register(new TieredItem("golden_hoe", ToolTier.GOLDEN, builder().stackSize(1).maxDamage(32))); + public static final TieredItem IRON_SWORD = register(new TieredItem("iron_sword", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); + public static final TieredItem IRON_SHOVEL = register(new TieredItem("iron_shovel", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); + public static final TieredItem IRON_PICKAXE = register(new TieredItem("iron_pickaxe", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); + public static final TieredItem IRON_AXE = register(new TieredItem("iron_axe", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); + public static final TieredItem IRON_HOE = register(new TieredItem("iron_hoe", ToolTier.IRON, builder().stackSize(1).maxDamage(250))); + public static final TieredItem DIAMOND_SWORD = register(new TieredItem("diamond_sword", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); + public static final TieredItem DIAMOND_SHOVEL = register(new TieredItem("diamond_shovel", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); + public static final TieredItem DIAMOND_PICKAXE = register(new TieredItem("diamond_pickaxe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); + public static final TieredItem DIAMOND_AXE = register(new TieredItem("diamond_axe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); + public static final TieredItem DIAMOND_HOE = register(new TieredItem("diamond_hoe", ToolTier.DIAMOND, builder().stackSize(1).maxDamage(1561))); + public static final TieredItem NETHERITE_SWORD = register(new TieredItem("netherite_sword", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); + public static final TieredItem NETHERITE_SHOVEL = register(new TieredItem("netherite_shovel", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); + public static final TieredItem NETHERITE_PICKAXE = register(new TieredItem("netherite_pickaxe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); + public static final TieredItem NETHERITE_AXE = register(new TieredItem("netherite_axe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); + public static final TieredItem NETHERITE_HOE = register(new TieredItem("netherite_hoe", ToolTier.NETHERITE, builder().stackSize(1).maxDamage(2031))); public static final Item STICK = register(new Item("stick", builder())); public static final Item BOWL = register(new Item("bowl", builder())); public static final Item MUSHROOM_STEW = register(new Item("mushroom_stew", builder().stackSize(1))); @@ -825,30 +826,30 @@ public final class Items { public static final Item WHEAT_SEEDS = register(new Item("wheat_seeds", builder())); public static final Item WHEAT = register(new Item("wheat", builder())); public static final Item BREAD = register(new Item("bread", builder())); - public static final Item LEATHER_HELMET = register(new Item("leather_helmet", builder().stackSize(1).maxDamage(55))); - public static final Item LEATHER_CHESTPLATE = register(new Item("leather_chestplate", builder().stackSize(1).maxDamage(80))); - public static final Item LEATHER_LEGGINGS = register(new Item("leather_leggings", builder().stackSize(1).maxDamage(75))); - public static final Item LEATHER_BOOTS = register(new Item("leather_boots", builder().stackSize(1).maxDamage(65))); - public static final Item CHAINMAIL_HELMET = register(new Item("chainmail_helmet", builder().stackSize(1).maxDamage(165))); - public static final Item CHAINMAIL_CHESTPLATE = register(new Item("chainmail_chestplate", builder().stackSize(1).maxDamage(240))); - public static final Item CHAINMAIL_LEGGINGS = register(new Item("chainmail_leggings", builder().stackSize(1).maxDamage(225))); - public static final Item CHAINMAIL_BOOTS = register(new Item("chainmail_boots", builder().stackSize(1).maxDamage(195))); - public static final Item IRON_HELMET = register(new Item("iron_helmet", builder().stackSize(1).maxDamage(165))); - public static final Item IRON_CHESTPLATE = register(new Item("iron_chestplate", builder().stackSize(1).maxDamage(240))); - public static final Item IRON_LEGGINGS = register(new Item("iron_leggings", builder().stackSize(1).maxDamage(225))); - public static final Item IRON_BOOTS = register(new Item("iron_boots", builder().stackSize(1).maxDamage(195))); - public static final Item DIAMOND_HELMET = register(new Item("diamond_helmet", builder().stackSize(1).maxDamage(363))); - public static final Item DIAMOND_CHESTPLATE = register(new Item("diamond_chestplate", builder().stackSize(1).maxDamage(528))); - public static final Item DIAMOND_LEGGINGS = register(new Item("diamond_leggings", builder().stackSize(1).maxDamage(495))); - public static final Item DIAMOND_BOOTS = register(new Item("diamond_boots", builder().stackSize(1).maxDamage(429))); - public static final Item GOLDEN_HELMET = register(new Item("golden_helmet", builder().stackSize(1).maxDamage(77))); - public static final Item GOLDEN_CHESTPLATE = register(new Item("golden_chestplate", builder().stackSize(1).maxDamage(112))); - public static final Item GOLDEN_LEGGINGS = register(new Item("golden_leggings", builder().stackSize(1).maxDamage(105))); - public static final Item GOLDEN_BOOTS = register(new Item("golden_boots", builder().stackSize(1).maxDamage(91))); - public static final Item NETHERITE_HELMET = register(new Item("netherite_helmet", builder().stackSize(1).maxDamage(407))); - public static final Item NETHERITE_CHESTPLATE = register(new Item("netherite_chestplate", builder().stackSize(1).maxDamage(592))); - public static final Item NETHERITE_LEGGINGS = register(new Item("netherite_leggings", builder().stackSize(1).maxDamage(555))); - public static final Item NETHERITE_BOOTS = register(new Item("netherite_boots", builder().stackSize(1).maxDamage(481))); + public static final ArmorItem LEATHER_HELMET = register(new ArmorItem("leather_helmet", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(55))); + public static final ArmorItem LEATHER_CHESTPLATE = register(new ArmorItem("leather_chestplate", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(80))); + public static final ArmorItem LEATHER_LEGGINGS = register(new ArmorItem("leather_leggings", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(75))); + public static final ArmorItem LEATHER_BOOTS = register(new ArmorItem("leather_boots", ArmorMaterial.LEATHER, builder().stackSize(1).maxDamage(65))); + public static final ArmorItem CHAINMAIL_HELMET = register(new ArmorItem("chainmail_helmet", ArmorMaterial.CHAIN, builder().stackSize(1).maxDamage(165))); + public static final ArmorItem CHAINMAIL_CHESTPLATE = register(new ArmorItem("chainmail_chestplate", ArmorMaterial.CHAIN, builder().stackSize(1).maxDamage(240))); + public static final ArmorItem CHAINMAIL_LEGGINGS = register(new ArmorItem("chainmail_leggings", ArmorMaterial.CHAIN, builder().stackSize(1).maxDamage(225))); + public static final ArmorItem CHAINMAIL_BOOTS = register(new ArmorItem("chainmail_boots", ArmorMaterial.CHAIN, builder().stackSize(1).maxDamage(195))); + public static final ArmorItem IRON_HELMET = register(new ArmorItem("iron_helmet", ArmorMaterial.IRON, builder().stackSize(1).maxDamage(165))); + public static final ArmorItem IRON_CHESTPLATE = register(new ArmorItem("iron_chestplate", ArmorMaterial.IRON, builder().stackSize(1).maxDamage(240))); + public static final ArmorItem IRON_LEGGINGS = register(new ArmorItem("iron_leggings", ArmorMaterial.IRON, builder().stackSize(1).maxDamage(225))); + public static final ArmorItem IRON_BOOTS = register(new ArmorItem("iron_boots", ArmorMaterial.IRON, builder().stackSize(1).maxDamage(195))); + public static final ArmorItem DIAMOND_HELMET = register(new ArmorItem("diamond_helmet", ArmorMaterial.DIAMOND, builder().stackSize(1).maxDamage(363))); + public static final ArmorItem DIAMOND_CHESTPLATE = register(new ArmorItem("diamond_chestplate", ArmorMaterial.DIAMOND, builder().stackSize(1).maxDamage(528))); + public static final ArmorItem DIAMOND_LEGGINGS = register(new ArmorItem("diamond_leggings", ArmorMaterial.DIAMOND, builder().stackSize(1).maxDamage(495))); + public static final ArmorItem DIAMOND_BOOTS = register(new ArmorItem("diamond_boots", ArmorMaterial.DIAMOND, builder().stackSize(1).maxDamage(429))); + public static final ArmorItem GOLDEN_HELMET = register(new ArmorItem("golden_helmet", ArmorMaterial.GOLD, builder().stackSize(1).maxDamage(77))); + public static final ArmorItem GOLDEN_CHESTPLATE = register(new ArmorItem("golden_chestplate", ArmorMaterial.GOLD, builder().stackSize(1).maxDamage(112))); + public static final ArmorItem GOLDEN_LEGGINGS = register(new ArmorItem("golden_leggings", ArmorMaterial.GOLD, builder().stackSize(1).maxDamage(105))); + public static final ArmorItem GOLDEN_BOOTS = register(new ArmorItem("golden_boots", ArmorMaterial.GOLD, builder().stackSize(1).maxDamage(91))); + public static final ArmorItem NETHERITE_HELMET = register(new ArmorItem("netherite_helmet", ArmorMaterial.NETHERITE, builder().stackSize(1).maxDamage(407))); + public static final ArmorItem NETHERITE_CHESTPLATE = register(new ArmorItem("netherite_chestplate", ArmorMaterial.NETHERITE, builder().stackSize(1).maxDamage(592))); + public static final ArmorItem NETHERITE_LEGGINGS = register(new ArmorItem("netherite_leggings", ArmorMaterial.NETHERITE, builder().stackSize(1).maxDamage(555))); + public static final ArmorItem NETHERITE_BOOTS = register(new ArmorItem("netherite_boots", ArmorMaterial.NETHERITE, builder().stackSize(1).maxDamage(481))); public static final Item FLINT = register(new Item("flint", builder())); public static final Item PORKCHOP = register(new Item("porkchop", builder())); public static final Item COOKED_PORKCHOP = register(new Item("cooked_porkchop", builder())); @@ -1120,7 +1121,7 @@ public final class Items { public static final Item SPECTRAL_ARROW = register(new Item("spectral_arrow", builder())); public static final TippedArrowItem TIPPED_ARROW = register(new TippedArrowItem("tipped_arrow", builder())); public static final PotionItem LINGERING_POTION = register(new PotionItem("lingering_potion", builder().stackSize(1))); - public static final Item SHIELD = register(new Item("shield", builder().stackSize(1).maxDamage(336))); + public static final ShieldItem SHIELD = register(new ShieldItem("shield", builder().stackSize(1).maxDamage(336))); public static final Item TOTEM_OF_UNDYING = register(new Item("totem_of_undying", builder().stackSize(1))); public static final Item SHULKER_SHELL = register(new Item("shulker_shell", builder())); public static final Item IRON_NUGGET = register(new Item("iron_nugget", builder())); diff --git a/core/src/main/java/org/geysermc/geyser/item/components/ToolTier.java b/core/src/main/java/org/geysermc/geyser/item/components/ToolTier.java index 37e581682..674e8c3f4 100644 --- a/core/src/main/java/org/geysermc/geyser/item/components/ToolTier.java +++ b/core/src/main/java/org/geysermc/geyser/item/components/ToolTier.java @@ -25,30 +25,43 @@ package org.geysermc.geyser.item.components; +import com.google.common.base.Suppliers; import org.checkerframework.checker.nullness.qual.NonNull; +import org.geysermc.geyser.item.Items; +import org.geysermc.geyser.item.type.Item; +import java.util.Collections; import java.util.Locale; +import java.util.Set; +import java.util.function.Supplier; public enum ToolTier { - WOODEN(2), - STONE(4), - IRON(6), - GOLDEN(12), - DIAMOND(8), - NETHERITE(9); + WOODEN(2, () -> Set.of(Items.OAK_PLANKS, Items.SPRUCE_PLANKS, Items.BIRCH_PLANKS, Items.JUNGLE_PLANKS, Items.ACACIA_PLANKS, Items.DARK_OAK_PLANKS, Items.CRIMSON_PLANKS, Items.WARPED_PLANKS, Items.MANGROVE_PLANKS)), // PLANKS tag // TODO ? + STONE(4, () -> Set.of(Items.COBBLESTONE, Items.BLACKSTONE, Items.COBBLED_DEEPSLATE)), // STONE_TOOL_MATERIALS tag + IRON(6, () -> Collections.singleton(Items.IRON_INGOT)), + GOLDEN(12, () -> Collections.singleton(Items.GOLD_INGOT)), + DIAMOND(8, () -> Collections.singleton(Items.DIAMOND)), + NETHERITE(9, () -> Collections.singleton(Items.NETHERITE_INGOT)); public static final ToolTier[] VALUES = values(); private final int speed; + private final Supplier> repairIngredients; - ToolTier(int speed) { + ToolTier(int speed, Supplier> repairIngredients) { this.speed = speed; + // Lazily initialize as this will likely be called as items are loading + this.repairIngredients = Suppliers.memoize(repairIngredients::get); } public int getSpeed() { return speed; } + public Set getRepairIngredients() { + return repairIngredients.get(); + } + @Override public String toString() { return this.name().toLowerCase(Locale.ROOT); diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java new file mode 100644 index 000000000..fc48c9f34 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/item/type/ArmorItem.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.item.type; + +import org.geysermc.geyser.item.ArmorMaterial; + +public class ArmorItem extends Item { + private final ArmorMaterial material; + + public ArmorItem(String javaIdentifier, ArmorMaterial material, Builder builder) { + super(javaIdentifier, builder); + this.material = material; + } + + @Override + public boolean isValidRepairItem(Item other) { + return material.getRepairIngredient() == other; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ElytraItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ElytraItem.java new file mode 100644 index 000000000..e5d94eb8b --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/item/type/ElytraItem.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.item.type; + +import org.geysermc.geyser.item.Items; + +public class ElytraItem extends Item { + public ElytraItem(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + public boolean isValidRepairItem(Item other) { + return other == Items.PHANTOM_MEMBRANE; + } +} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/Item.java b/core/src/main/java/org/geysermc/geyser/item/type/Item.java index af96d6094..7d3c70435 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/Item.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/Item.java @@ -33,26 +33,19 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.ItemMappings; import org.geysermc.geyser.translator.inventory.item.ItemTranslator; -import javax.annotation.Nullable; -import java.util.Set; - public class Item { private final String javaIdentifier; private int javaId = -1; private final int stackSize; private final String toolType; - private final String toolTier; private final int maxDamage; - private final Set repairMaterials; private final boolean hasSuspiciousStewEffect; public Item(String javaIdentifier, Builder builder) { this.javaIdentifier = Identifier.formalize(javaIdentifier).intern(); this.stackSize = builder.stackSize; this.toolType = builder.toolType; - this.toolTier = builder.toolTier; this.maxDamage = builder.maxDamage; - this.repairMaterials = builder.repairMaterials; this.hasSuspiciousStewEffect = builder.hasSuspiciousStewEffect; } @@ -72,6 +65,12 @@ public class Item { return stackSize; } + public boolean isValidRepairItem(Item other) { + return false; + } + + /* Translation methods to Bedrock and back */ + public ItemData.Builder translateToBedrock(ItemStack itemStack, ItemMapping mapping, ItemMappings mappings) { if (itemStack == null) { // Return, essentially, air @@ -91,7 +90,7 @@ public class Item { return builder; } - public ItemStack translateToJava(@Nullable ItemData itemData, ItemMapping mapping, ItemMappings mappings) { + public ItemStack translateToJava(ItemData itemData, ItemMapping mapping, ItemMappings mappings) { if (itemData == null) return null; if (itemData.getTag() == null) { return new ItemStack(javaId, itemData.getCount(), new CompoundTag("")); @@ -129,9 +128,7 @@ public class Item { public static final class Builder { private int stackSize = 64; private String toolType; - private String toolTier; private int maxDamage; - private Set repairMaterials; private boolean hasSuspiciousStewEffect; public Builder stackSize(int stackSize) { @@ -144,21 +141,11 @@ public class Item { return this; } - public Builder setToolTier(String toolTier) { - this.toolTier = toolTier; - return this; - } - public Builder maxDamage(int maxDamage) { this.maxDamage = maxDamage; return this; } - public Builder setRepairMaterials(Set repairMaterials) { - this.repairMaterials = repairMaterials; - return this; - } - public Builder setHasSuspiciousStewEffect(boolean hasSuspiciousStewEffect) { this.hasSuspiciousStewEffect = hasSuspiciousStewEffect; return this; diff --git a/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java new file mode 100644 index 000000000..fc28e1f50 --- /dev/null +++ b/core/src/main/java/org/geysermc/geyser/item/type/ShieldItem.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019-2022 GeyserMC. http://geysermc.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * @author GeyserMC + * @link https://github.com/GeyserMC/Geyser + */ + +package org.geysermc.geyser.item.type; + +import org.geysermc.geyser.item.components.ToolTier; + +public class ShieldItem extends Item { + public ShieldItem(String javaIdentifier, Builder builder) { + super(javaIdentifier, builder); + } + + @Override + public boolean isValidRepairItem(Item other) { + // Java Edition 1.19.3 checks the tag, but TODO check to see if we want it or are simulating what Bedrock is doing + return ToolTier.WOODEN.getRepairIngredients().contains(other); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/item/type/TieredItem.java b/core/src/main/java/org/geysermc/geyser/item/type/TieredItem.java index 14db36bf3..d998eb0d4 100644 --- a/core/src/main/java/org/geysermc/geyser/item/type/TieredItem.java +++ b/core/src/main/java/org/geysermc/geyser/item/type/TieredItem.java @@ -25,11 +25,22 @@ package org.geysermc.geyser.item.type; -/** - * May not represent all tiered items - just the ones we care about. :) - */ +import org.geysermc.geyser.item.components.ToolTier; + public class TieredItem extends Item { - public TieredItem(String javaIdentifier, Builder builder) { + private final ToolTier tier; + + public TieredItem(String javaIdentifier, ToolTier tier, Builder builder) { super(javaIdentifier, builder); + this.tier = tier; + } + + public ToolTier tier() { + return tier; + } + + @Override + public boolean isValidRepairItem(Item other) { + return tier.getRepairIngredients().contains(other); } } diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java index 84c0905db..f32366ef2 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomItemRegistryPopulator.java @@ -50,10 +50,7 @@ import org.geysermc.geyser.registry.type.ItemMapping; import org.geysermc.geyser.registry.type.NonVanillaItemRegistration; import javax.annotation.Nullable; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.OptionalInt; +import java.util.*; public class CustomItemRegistryPopulator { public static void populate(Map items, Multimap customItems, List nonVanillaCustomItems) { @@ -131,10 +128,18 @@ public class CustomItemRegistryPopulator { public static NonVanillaItemRegistration registerCustomItem(NonVanillaCustomItemData customItemData, int customItemId) { String customIdentifier = customItemData.identifier(); + Set repairMaterials = customItemData.repairMaterials(); + Item.Builder itemBuilder = Item.builder() .stackSize(customItemData.stackSize()) .maxDamage(customItemData.maxDamage()); - Item item = new Item(customIdentifier, itemBuilder); + Item item = new Item(customIdentifier, itemBuilder) { + // TODO ? + @Override + public boolean isValidRepairItem(Item other) { + return repairMaterials != null && repairMaterials.contains(other.javaIdentifier()); + } + }; Items.register(item, customItemData.javaId()); ItemMapping customItemMapping = ItemMapping.builder() @@ -144,7 +149,6 @@ public class CustomItemRegistryPopulator { .toolType(customItemData.toolType()) .toolTier(customItemData.toolTier()) .translationString(customItemData.translationString()) - .repairMaterials(customItemData.repairMaterials()) .hasSuspiciousStewEffect(false) .customItemOptions(Collections.emptyList()) .javaItem(item) diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java index bf2c07a04..1b757e95f 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/ItemRegistryPopulator.java @@ -331,10 +331,6 @@ public class ItemRegistryPopulator { .hasSuspiciousStewEffect(mappingItem.isHasSuspiciousStewEffect()) .javaItem(javaItem); - if (mappingItem.getRepairMaterials() != null) { - mappingBuilder = mappingBuilder.repairMaterials(new ObjectOpenHashSet<>(mappingItem.getRepairMaterials())); - } - if (mappingItem.getToolType() != null) { if (mappingItem.getToolTier() != null) { mappingBuilder = mappingBuilder.toolType(mappingItem.getToolType().intern()) diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMapping.java b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMapping.java index 278e0aca9..f14b2112e 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/ItemMapping.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/ItemMapping.java @@ -26,7 +26,9 @@ package org.geysermc.geyser.registry.type; import it.unimi.dsi.fastutil.Pair; -import lombok.*; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Value; import org.checkerframework.checker.nullness.qual.NonNull; import org.cloudburstmc.protocol.bedrock.data.defintions.BlockDefinition; import org.cloudburstmc.protocol.bedrock.data.defintions.ItemDefinition; @@ -36,7 +38,6 @@ import org.geysermc.geyser.item.type.Item; import java.util.Collections; import java.util.List; -import java.util.Set; @Value @Builder @@ -51,7 +52,6 @@ public class ItemMapping { null, null, Collections.emptyList(), - null, false, Items.AIR ); @@ -74,8 +74,6 @@ public class ItemMapping { @NonNull List> customItemOptions; - Set repairMaterials; - boolean hasSuspiciousStewEffect; @NonNull