From dcd895edbc9aab61f9d9823b0796ca8979a5270d Mon Sep 17 00:00:00 2001 From: SirEdvin Date: Sun, 18 Jun 2023 18:16:31 +0300 Subject: [PATCH] Introduce UpgradeData as main record for passing upgrade with data here and there --- .../api/turtle/ITurtleAccess.java | 20 ++++++ .../api/upgrades/UpgradeBase.java | 35 +++++++++- .../api/upgrades/UpgradeData.java | 64 +++++++++++++++++++ .../client/model/turtle/TurtleModelParts.java | 4 +- .../computercraft/data/RecipeProvider.java | 9 +-- .../computercraft/impl/UpgradeManager.java | 8 ++- .../computercraft/shared/ModRegistry.java | 7 +- .../shared/integration/RecipeModHelpers.java | 5 +- .../integration/UpgradeRecipeGenerator.java | 32 ++++++---- .../shared/pocket/apis/PocketAPI.java | 14 ++-- .../pocket/core/PocketServerComputer.java | 15 ++++- .../pocket/items/PocketComputerItem.java | 43 ++++++++----- .../recipes/PocketComputerUpgradeRecipe.java | 3 +- .../shared/turtle/blocks/TurtleBlock.java | 11 ++-- .../shared/turtle/core/TurtleBrain.java | 22 +++++++ .../turtle/core/TurtleEquipCommand.java | 12 ++-- .../shared/turtle/items/TurtleItem.java | 64 ++++++++----------- .../turtle/recipes/TurtleOverlayRecipe.java | 4 +- .../shared/turtle/recipes/TurtleRecipe.java | 2 +- .../turtle/recipes/TurtleUpgradeRecipe.java | 9 ++- .../shared/turtle/upgrades/TurtleModem.java | 8 +++ 21 files changed, 277 insertions(+), 114 deletions(-) create mode 100644 projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeData.java diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java index 3ef11c7ab..a46432951 100644 --- a/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java +++ b/projects/common-api/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java @@ -8,6 +8,7 @@ import com.mojang.authlib.GameProfile; import dan200.computercraft.api.lua.ILuaCallback; import dan200.computercraft.api.lua.MethodResult; import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.api.upgrades.UpgradeData; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -254,6 +255,16 @@ public interface ITurtleAccess { @Nullable ITurtleUpgrade getUpgrade(TurtleSide side); + default @Nullable UpgradeData getUpgradeData(TurtleSide side) { + var upgrade = getUpgrade(side); + if (upgrade == null) { + return null; + } + return new UpgradeData<>( + upgrade, getUpgradeNBTData(side) + ); + } + /** * Set the upgrade for a given side, resetting peripherals and clearing upgrade specific data. * @@ -263,6 +274,15 @@ public interface ITurtleAccess { */ void setUpgrade(TurtleSide side, @Nullable ITurtleUpgrade upgrade); + /** + * Set the upgrade for a given side, resetting peripherals and clearing upgrade specific data. + * + * @param side The side to set the upgrade on. + * @param upgrade The upgrade to set, may be {@code null} to clear. + * @see #getUpgrade(TurtleSide) + */ + void setUpgrade(TurtleSide side, @Nullable UpgradeData upgrade); + /** * Returns the peripheral created by the upgrade on the specified side of the turtle, if there is one. * diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeBase.java b/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeBase.java index 5e16c281d..073fc2c0e 100644 --- a/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeBase.java +++ b/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeBase.java @@ -52,14 +52,45 @@ public interface UpgradeBase { */ ItemStack getCraftingItem(); - default @Nonnull ItemStack produceCraftingItem(@Nonnull CompoundTag upgradeData) { + /** + * Return an item stack representing the instance of upgrade with passed upgrade data. + * By default, this method output equals to {@link #getCraftingItem()} because default behavior of + * upgrades is ignored any upgrade data. + *

+ * But if your upgrade required this, you can redefine this behavior and pass some information from upgrade data + * to item stack. Please, use this method with cautions. + *

+ * This method will be used by {@code turtle.unequipLeft()} and {@code pocket.unequipBack()} to determine item stack + * that should be placed inside inventory + * + * @param upgradeData NBT information that was stored inside turtle/pocket by upgrade + * @return The item stack, that should be stored inside inventory + */ + default @Nonnull ItemStack getUpgradeItem(@Nonnull CompoundTag upgradeData) { return getCraftingItem(); } - default @Nonnull CompoundTag produceUpgradeData(@Nonnull ItemStack stack) { + /** + * Returns initial upgrade data, that should be set for turtle/pocket, that uses this upgrade, based on item stack + * that used for installing upgrade right now. + * @param stack Item Stack that used for upgrade + * @return Upgrade NBT data that should be set in time of adding this upgrade to turtle/pocket + */ + default @Nonnull CompoundTag getUpgradeData(@Nonnull ItemStack stack) { return new CompoundTag(); } + /** + * Specific hook, that allow you to filter data, that should be stored when turtle was broken. + * Use this in cases when you don't need to store all upgrade data by default, and you want to change this + * behavior, for example, as modem do. + * @param upgradeData NBT data that currently stored for this upgrade + * @return filtered version of this data, by default just all of it + */ + default @Nonnull CompoundTag getPersistedData(CompoundTag upgradeData) { + return upgradeData; + } + /** * Determine if an item is suitable for being used for this upgrade. *

diff --git a/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeData.java b/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeData.java new file mode 100644 index 000000000..14343e13c --- /dev/null +++ b/projects/common-api/src/main/java/dan200/computercraft/api/upgrades/UpgradeData.java @@ -0,0 +1,64 @@ +package dan200.computercraft.api.upgrades; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; + +import javax.annotation.Nullable; + +public record UpgradeData(T upgrade, CompoundTag data) { + /** Utility function, that provide ability to build default version of upgrade data + * based only on upgrade object. + * @param upgrade any upgrade + * @param Upgrade class + * @return default instance of upgrade data + */ + public static UpgradeData wrap(T upgrade) { + return new UpgradeData<>(upgrade, upgrade.getUpgradeData(upgrade.getCraftingItem())); + } + + /** Transform UpgradeData to it persistent variant that should be stored, when turtle or pocket items stop functioning. + * @see UpgradeBase#getPersistedData(CompoundTag) + * @param upgrade UpgradeData that should be persisted or null + * @return UpgradeData instance with only persistent upgrade information or null + */ + public static @Nullable UpgradeData persist(@Nullable UpgradeData upgrade) { + if (upgrade == null) { + return null; + } + return new UpgradeData<>( + upgrade.upgrade, upgrade.upgrade.getPersistedData(upgrade.data) + ); + } + + /** Utility functions, that allows to compare two upgrade data and check if they have same upgrades. + * + * @param first first upgrade data + * @param second second upgrade data + * @param UpgradeBase class + * @return true if upgrades data have same upgrades or both null + */ + public static boolean isSame(@Nullable UpgradeData first, @Nullable UpgradeData second) { + if (first == null) { + return second == null; + } + if (second == null) { + return false; + } + return first.upgrade == second.upgrade; + } + + /** Build ItemStack from upgrade and data pair. + * @return ItemStack that correspond current upgrade + data pair + */ + public ItemStack getUpgradeItem() { + return upgrade.getUpgradeItem(data); + } + + /** Wrapper that just pass upgrade ID. + * @return upgrade id + */ + public ResourceLocation getUpgradeID() { + return upgrade.getUpgradeID(); + } +} diff --git a/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java b/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java index e5a2b7365..5693e8706 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java +++ b/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java @@ -82,7 +82,9 @@ public final class TurtleModelParts { var label = turtle.getLabel(stack); var flip = label != null && (label.equals("Dinnerbone") || label.equals("Grumm")); - return new Combination(colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip); + return new Combination( + colour != -1, leftUpgrade == null ? null : leftUpgrade.upgrade(), + rightUpgrade == null ? null : rightUpgrade.upgrade(), overlay, christmas, flip); } public List buildModel(Combination combo) { diff --git a/projects/common/src/main/java/dan200/computercraft/data/RecipeProvider.java b/projects/common/src/main/java/dan200/computercraft/data/RecipeProvider.java index 5ddb14470..4e8db1d44 100644 --- a/projects/common/src/main/java/dan200/computercraft/data/RecipeProvider.java +++ b/projects/common/src/main/java/dan200/computercraft/data/RecipeProvider.java @@ -8,6 +8,7 @@ import com.google.gson.JsonObject; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.pocket.PocketUpgradeDataProvider; import dan200.computercraft.api.turtle.TurtleUpgradeDataProvider; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.core.util.Colour; import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.common.IColouredItem; @@ -105,12 +106,12 @@ class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider { */ private void turtleUpgrades(Consumer add) { for (var turtleItem : turtleItems()) { - var base = turtleItem.create(-1, null, -1, null, null, 0, null, null, null); + var base = turtleItem.create(-1, null, -1, null, null, 0, null); var nameId = turtleItem.getFamily().name().toLowerCase(Locale.ROOT); for (var upgrade : turtleUpgrades.getGeneratedUpgrades()) { - var result = turtleItem.create(-1, null, -1, null, upgrade, -1, null, null, null); + var result = turtleItem.create(-1, null, -1, null, UpgradeData.wrap(upgrade), -1, null); ShapedRecipeBuilder .shaped(RecipeCategory.REDSTONE, result.getItem()) .group(String.format("%s:turtle_%s", ComputerCraftAPI.MOD_ID, nameId)) @@ -146,7 +147,7 @@ class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider { var nameId = pocket.getFamily().name().toLowerCase(Locale.ROOT); for (var upgrade : pocketUpgrades.getGeneratedUpgrades()) { - var result = pocket.create(-1, null, -1, upgrade); + var result = pocket.create(-1, null, -1, UpgradeData.wrap(upgrade)); ShapedRecipeBuilder .shaped(RecipeCategory.REDSTONE, result.getItem()) .group(String.format("%s:pocket_%s", ComputerCraftAPI.MOD_ID, nameId)) @@ -189,7 +190,7 @@ class RecipeProvider extends net.minecraft.data.recipes.RecipeProvider { private void turtleOverlay(Consumer add, String overlay, Consumer build) { for (var turtleItem : turtleItems()) { - var base = turtleItem.create(-1, null, -1, null, null, 0, null, null, null); + var base = turtleItem.create(-1, null, -1, null, null, 0, null); var nameId = turtleItem.getFamily().name().toLowerCase(Locale.ROOT); var group = "%s:turtle_%s_overlay".formatted(ComputerCraftAPI.MOD_ID, nameId); diff --git a/projects/common/src/main/java/dan200/computercraft/impl/UpgradeManager.java b/projects/common/src/main/java/dan200/computercraft/impl/UpgradeManager.java index 440d4bd2b..e7c4c85e0 100644 --- a/projects/common/src/main/java/dan200/computercraft/impl/UpgradeManager.java +++ b/projects/common/src/main/java/dan200/computercraft/impl/UpgradeManager.java @@ -7,6 +7,7 @@ package dan200.computercraft.impl; import com.google.gson.*; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.upgrades.UpgradeBase; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.api.upgrades.UpgradeSerialiser; import dan200.computercraft.shared.platform.PlatformHelper; import net.minecraft.core.Registry; @@ -74,13 +75,16 @@ public class UpgradeManager, T extends } @Nullable - public T get(ItemStack stack) { + public UpgradeData get(ItemStack stack) { if (stack.isEmpty()) return null; for (var wrapper : current.values()) { var craftingStack = wrapper.upgrade().getCraftingItem(); if (!craftingStack.isEmpty() && craftingStack.getItem() == stack.getItem() && wrapper.upgrade().isItemSuitable(stack)) { - return wrapper.upgrade(); + return new UpgradeData<>( + wrapper.upgrade, + wrapper.upgrade.getUpgradeData(stack) + ); } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java b/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java index a893dd338..64d3d635a 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/ModRegistry.java @@ -11,6 +11,7 @@ import dan200.computercraft.api.detail.VanillaDetailRegistries; import dan200.computercraft.api.media.IMedia; import dan200.computercraft.api.pocket.PocketUpgradeSerialiser; import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.core.util.Colour; import dan200.computercraft.impl.PocketUpgrades; import dan200.computercraft.impl.TurtleUpgrades; @@ -444,14 +445,14 @@ public final class ModRegistry { } private static void addTurtle(CreativeModeTab.Output out, TurtleItem turtle) { - out.accept(turtle.create(-1, null, -1, null, null, 0, null, null, null)); + out.accept(turtle.create(-1, null, -1, null, null, 0, null)); TurtleUpgrades.getVanillaUpgrades() - .map(x -> turtle.create(-1, null, -1, null, x, 0, null, null, null)) + .map(x -> turtle.create(-1, null, -1, null, UpgradeData.wrap(x), 0, null)) .forEach(out::accept); } private static void addPocket(CreativeModeTab.Output out, PocketComputerItem pocket) { out.accept(pocket.create(-1, null, -1, null)); - PocketUpgrades.getVanillaUpgrades().map(x -> pocket.create(-1, null, -1, x)).forEach(out::accept); + PocketUpgrades.getVanillaUpgrades().map(x -> pocket.create(-1, null, -1, UpgradeData.wrap(x))).forEach(out::accept); } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/integration/RecipeModHelpers.java b/projects/common/src/main/java/dan200/computercraft/shared/integration/RecipeModHelpers.java index e8ead0af4..270f080ee 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/integration/RecipeModHelpers.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/integration/RecipeModHelpers.java @@ -5,6 +5,7 @@ package dan200.computercraft.shared.integration; import dan200.computercraft.api.ComputerCraftAPI; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.impl.PocketUpgrades; import dan200.computercraft.impl.TurtleUpgrades; import dan200.computercraft.shared.ModRegistry; @@ -56,14 +57,14 @@ public final class RecipeModHelpers { for (var turtleSupplier : TURTLES) { var turtle = turtleSupplier.get(); for (var upgrade : TurtleUpgrades.instance().getUpgrades()) { - upgradeItems.add(turtle.create(-1, null, -1, null, upgrade, 0, null, null, null)); + upgradeItems.add(turtle.create(-1, null, -1, null, UpgradeData.wrap(upgrade), 0, null)); } } for (var pocketSupplier : POCKET_COMPUTERS) { var pocket = pocketSupplier.get(); for (var upgrade : PocketUpgrades.instance().getUpgrades()) { - upgradeItems.add(pocket.create(-1, null, -1, upgrade)); + upgradeItems.add(pocket.create(-1, null, -1, UpgradeData.wrap(upgrade))); } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/integration/UpgradeRecipeGenerator.java b/projects/common/src/main/java/dan200/computercraft/shared/integration/UpgradeRecipeGenerator.java index c2728034e..97484ff66 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/integration/UpgradeRecipeGenerator.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/integration/UpgradeRecipeGenerator.java @@ -9,6 +9,7 @@ import dan200.computercraft.api.pocket.IPocketUpgrade; import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleSide; import dan200.computercraft.api.upgrades.UpgradeBase; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.impl.PocketUpgrades; import dan200.computercraft.impl.TurtleUpgrades; import dan200.computercraft.shared.pocket.items.PocketComputerItem; @@ -118,13 +119,16 @@ public class UpgradeRecipeGenerator { List recipes = new ArrayList<>(); var ingredient = Ingredient.of(stack); for (var upgrade : turtleUpgrades) { + if (upgrade.turtle == null) { + continue; + } // The turtle is facing towards us, so upgrades on the left are actually crafted on the right. if (left == null) { - recipes.add(turtle(ingredient, upgrade.ingredient, turtleWith(stack, upgrade.turtle, right))); + recipes.add(turtle(ingredient, upgrade.ingredient, turtleWith(stack, UpgradeData.wrap(upgrade.turtle), right))); } if (right == null) { - recipes.add(turtle(upgrade.ingredient, ingredient, turtleWith(stack, left, upgrade.turtle))); + recipes.add(turtle(upgrade.ingredient, ingredient, turtleWith(stack, left, UpgradeData.wrap(upgrade.turtle)))); } } @@ -137,7 +141,10 @@ public class UpgradeRecipeGenerator { List recipes = new ArrayList<>(); var ingredient = Ingredient.of(stack); for (var upgrade : pocketUpgrades) { - recipes.add(pocket(upgrade.ingredient, ingredient, pocketWith(stack, upgrade.pocket))); + if (upgrade.pocket == null) { + continue; + } + recipes.add(pocket(upgrade.ingredient, ingredient, pocketWith(stack, UpgradeData.wrap(upgrade.pocket)))); } return Collections.unmodifiableList(recipes); @@ -187,14 +194,14 @@ public class UpgradeRecipeGenerator { if (left != null) { recipes.add(turtle( Ingredient.of(turtleWith(stack, null, right)), - Ingredient.of(left.getCraftingItem()), + Ingredient.of(left.upgrade().getCraftingItem()), stack )); } if (right != null) { recipes.add(turtle( - Ingredient.of(right.getCraftingItem()), + Ingredient.of(right.upgrade().getCraftingItem()), Ingredient.of(turtleWith(stack, left, null)), stack )); @@ -206,7 +213,7 @@ public class UpgradeRecipeGenerator { var back = PocketComputerItem.getUpgrade(stack); if (back != null) { - recipes.add(pocket(Ingredient.of(back.getCraftingItem()), Ingredient.of(pocketWith(stack, null)), stack)); + recipes.add(pocket(Ingredient.of(back.upgrade().getCraftingItem()), Ingredient.of(pocketWith(stack, null)), stack)); } return Collections.unmodifiableList(recipes); @@ -215,16 +222,15 @@ public class UpgradeRecipeGenerator { } } - private static ItemStack turtleWith(ItemStack stack, @Nullable ITurtleUpgrade left, @Nullable ITurtleUpgrade right) { + private static ItemStack turtleWith(ItemStack stack, @Nullable UpgradeData left, @Nullable UpgradeData right) { var item = (TurtleItem) stack.getItem(); return item.create( item.getComputerID(stack), item.getLabel(stack), item.getColour(stack), - left, right, item.getFuelLevel(stack), item.getOverlay(stack), - null, null + left, right, item.getFuelLevel(stack), item.getOverlay(stack) ); } - private static ItemStack pocketWith(ItemStack stack, @Nullable IPocketUpgrade back) { + private static ItemStack pocketWith(ItemStack stack, @Nullable UpgradeData back) { var item = (PocketComputerItem) stack.getItem(); return item.create( item.getComputerID(stack), item.getLabel(stack), item.getColour(stack), back @@ -272,8 +278,8 @@ public class UpgradeRecipeGenerator { var turtleItem = turtleSupplier.get(); recipes.add(turtle( ingredient, // Right upgrade, recipe on left - Ingredient.of(turtleItem.create(-1, null, -1, null, null, 0, null, null, null)), - turtleItem.create(-1, null, -1, null, turtle, 0, null, null, null) + Ingredient.of(turtleItem.create(-1, null, -1, null, null, 0, null)), + turtleItem.create(-1, null, -1, null, UpgradeData.wrap(turtle), 0, null) )); } } @@ -284,7 +290,7 @@ public class UpgradeRecipeGenerator { recipes.add(pocket( ingredient, Ingredient.of(pocketItem.create(-1, null, -1, null)), - pocketItem.create(-1, null, -1, pocket) + pocketItem.create(-1, null, -1, UpgradeData.wrap(pocket)) )); } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java index 091d97407..3d6a8d6ad 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/apis/PocketAPI.java @@ -7,6 +7,7 @@ package dan200.computercraft.shared.pocket.apis; import dan200.computercraft.api.lua.ILuaAPI; import dan200.computercraft.api.lua.LuaFunction; import dan200.computercraft.api.pocket.IPocketUpgrade; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.impl.PocketUpgrades; import dan200.computercraft.shared.pocket.core.PocketServerComputer; import net.minecraft.core.NonNullList; @@ -57,7 +58,7 @@ public class PocketAPI implements ILuaAPI { var entity = computer.getEntity(); if (!(entity instanceof Player player)) return new Object[]{ false, "Cannot find player" }; var inventory = player.getInventory(); - var previousUpgrade = computer.getUpgrade(); + var previousUpgrade = computer.getUpgradeData(); // Attempt to find the upgrade, starting in the main segment, and then looking in the opposite // one. We start from the position the item is currently in and loop round to the start. @@ -71,11 +72,10 @@ public class PocketAPI implements ILuaAPI { if (newUpgrade == null) return new Object[]{ false, "Cannot find a valid upgrade" }; // Remove the current upgrade - if (previousUpgrade != null) storeItem(player, previousUpgrade.produceCraftingItem(computer.getUpgradeNBTData()).copy()); + if (previousUpgrade != null) storeItem(player, previousUpgrade.getUpgradeItem().copy()); // Set the new upgrade computer.setUpgrade(newUpgrade); - computer.getUpgradeNBTData().merge(newUpgrade.produceUpgradeData(newUpgradeItem)); return new Object[]{ true }; } @@ -91,13 +91,13 @@ public class PocketAPI implements ILuaAPI { public final Object[] unequipBack() { var entity = computer.getEntity(); if (!(entity instanceof Player player)) return new Object[]{ false, "Cannot find player" }; - var previousUpgrade = computer.getUpgrade(); + var previousUpgrade = computer.getUpgradeData(); if (previousUpgrade == null) return new Object[]{ false, "Nothing to unequip" }; computer.setUpgrade(null); - storeItem(player, previousUpgrade.getCraftingItem().copy()); + storeItem(player, previousUpgrade.getUpgradeItem().copy()); return new Object[]{ true }; } @@ -109,13 +109,13 @@ public class PocketAPI implements ILuaAPI { } } - private static @Nullable ItemStack findUpgrade(NonNullList inv, int start, @Nullable IPocketUpgrade previous) { + private static @Nullable ItemStack findUpgrade(NonNullList inv, int start, @Nullable UpgradeData previous) { for (var i = 0; i < inv.size(); i++) { var invStack = inv.get((i + start) % inv.size()); if (!invStack.isEmpty()) { var newUpgrade = PocketUpgrades.instance().get(invStack); - if (newUpgrade != null && newUpgrade != previous) { + if (newUpgrade != null && !UpgradeData.isSame(newUpgrade, previous)) { // Consume an item from this stack and exit the loop invStack = invStack.copy(); invStack.shrink(1); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java index 6ac22f3dd..2559a90f0 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/core/PocketServerComputer.java @@ -7,6 +7,7 @@ package dan200.computercraft.shared.pocket.core; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.pocket.IPocketAccess; import dan200.computercraft.api.pocket.IPocketUpgrade; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.core.computer.ComputerSide; import dan200.computercraft.shared.common.IColouredItem; import dan200.computercraft.shared.computer.core.ComputerFamily; @@ -112,6 +113,13 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces return upgrade; } + public @Nullable UpgradeData getUpgradeData() { + if (upgrade == null) return null; + return new UpgradeData<>( + upgrade, getUpgradeNBTData() + ); + } + /** * Set the upgrade for this pocket computer, also updating the item stack. *

@@ -119,13 +127,14 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces * * @param upgrade The new upgrade to set it to, may be {@code null}. */ - public void setUpgrade(@Nullable IPocketUpgrade upgrade) { - if (this.upgrade == upgrade) return; + public void setUpgrade(@Nullable UpgradeData upgrade) { + var upgradeInstance = upgrade == null ? null : upgrade.upgrade(); + if (this.upgrade == upgradeInstance) return; synchronized (this) { PocketComputerItem.setUpgrade(stack, upgrade); updateUpgradeNBTData(); - this.upgrade = upgrade; + this.upgrade = upgradeInstance; invalidatePeripheral(); } } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java index a3648ba0c..4f6139644 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/items/PocketComputerItem.java @@ -10,6 +10,7 @@ import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.filesystem.Mount; import dan200.computercraft.api.media.IMedia; import dan200.computercraft.api.pocket.IPocketUpgrade; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.core.computer.ComputerSide; import dan200.computercraft.impl.PocketUpgrades; import dan200.computercraft.shared.ModRegistry; @@ -58,7 +59,7 @@ public class PocketComputerItem extends Item implements IComputerItem, IMedia, I this.family = family; } - public static ItemStack create(int id, @Nullable String label, int colour, ComputerFamily family, @Nullable IPocketUpgrade upgrade) { + public static ItemStack create(int id, @Nullable String label, int colour, ComputerFamily family, @Nullable UpgradeData upgrade) { return switch (family) { case NORMAL -> ModRegistry.Items.POCKET_COMPUTER_NORMAL.get().create(id, label, colour, upgrade); case ADVANCED -> ModRegistry.Items.POCKET_COMPUTER_ADVANCED.get().create(id, label, colour, upgrade); @@ -66,11 +67,14 @@ public class PocketComputerItem extends Item implements IComputerItem, IMedia, I }; } - public ItemStack create(int id, @Nullable String label, int colour, @Nullable IPocketUpgrade upgrade) { + public ItemStack create(int id, @Nullable String label, int colour, @Nullable UpgradeData upgrade) { var result = new ItemStack(this); if (id >= 0) result.getOrCreateTag().putInt(NBT_ID, id); if (label != null) result.setHoverName(Component.literal(label)); - if (upgrade != null) result.getOrCreateTag().putString(NBT_UPGRADE, upgrade.getUpgradeID().toString()); + if (upgrade != null) { + result.getOrCreateTag().putString(NBT_UPGRADE, upgrade.getUpgradeID().toString()); + if (!upgrade.data().isEmpty()) result.getOrCreateTag().put(NBT_UPGRADE_INFO, upgrade.data()); + } if (colour != -1) result.getOrCreateTag().putInt(NBT_COLOUR, colour); return result; } @@ -79,7 +83,7 @@ public class PocketComputerItem extends Item implements IComputerItem, IMedia, I var upgrade = getUpgrade(stack); computer.setLevel((ServerLevel) world); - computer.updateValues(entity, stack, upgrade); + computer.updateValues(entity, stack, upgrade != null ? upgrade.upgrade() : null); var changed = false; @@ -104,7 +108,7 @@ public class PocketComputerItem extends Item implements IComputerItem, IMedia, I } // Update pocket upgrade - if (upgrade != null) upgrade.update(computer, computer.getPeripheral(ComputerSide.BACK)); + if (upgrade != null) upgrade.upgrade().update(computer, computer.getPeripheral(ComputerSide.BACK)); return changed; } @@ -139,8 +143,8 @@ public class PocketComputerItem extends Item implements IComputerItem, IMedia, I var stop = false; var upgrade = getUpgrade(stack); if (upgrade != null) { - computer.updateValues(player, stack, upgrade); - stop = upgrade.onRightClick(world, computer, computer.getPeripheral(ComputerSide.BACK)); + computer.updateValues(player, stack, upgrade.upgrade()); + stop = upgrade.upgrade().onRightClick(world, computer, computer.getPeripheral(ComputerSide.BACK)); } if (!stop) { @@ -157,7 +161,7 @@ public class PocketComputerItem extends Item implements IComputerItem, IMedia, I var upgrade = getUpgrade(stack); if (upgrade != null) { return Component.translatable(baseString + ".upgraded", - Component.translatable(upgrade.getUnlocalisedAdjective()) + Component.translatable(upgrade.upgrade().getUnlocalisedAdjective()) ); } else { return super.getName(stack); @@ -183,7 +187,7 @@ public class PocketComputerItem extends Item implements IComputerItem, IMedia, I if (upgrade != null) { // If we're a non-vanilla, non-CC upgrade then return whichever mod this upgrade // belongs to. - var mod = PocketUpgrades.instance().getOwner(upgrade); + var mod = PocketUpgrades.instance().getOwner(upgrade.upgrade()); if (mod != null && !mod.equals(ComputerCraftAPI.MOD_ID)) return mod; } @@ -207,7 +211,9 @@ public class PocketComputerItem extends Item implements IComputerItem, IMedia, I setInstanceID(stack, computer.register()); setSessionID(stack, registry.getSessionID()); - computer.updateValues(entity, stack, getUpgrade(stack)); + var upgrade = getUpgrade(stack); + + computer.updateValues(entity, stack, upgrade != null ? upgrade.upgrade() : null); computer.addAPI(new PocketAPI(computer)); // Only turn on when initially creating the computer, rather than each tick. @@ -292,22 +298,27 @@ public class PocketComputerItem extends Item implements IComputerItem, IMedia, I return nbt != null && nbt.getBoolean(NBT_ON); } - public static @Nullable IPocketUpgrade getUpgrade(ItemStack stack) { + public static @Nullable UpgradeData getUpgrade(ItemStack stack) { var compound = stack.getTag(); - return compound != null && compound.contains(NBT_UPGRADE) - ? PocketUpgrades.instance().get(compound.getString(NBT_UPGRADE)) : null; + if (compound == null || !compound.contains(NBT_UPGRADE)) return null; + var upgrade = PocketUpgrades.instance().get(compound.getString(NBT_UPGRADE)); + if (upgrade == null) return null; + return new UpgradeData<>( + upgrade, + compound.getCompound(NBT_UPGRADE_INFO) + ); } - public static void setUpgrade(ItemStack stack, @Nullable IPocketUpgrade upgrade) { + public static void setUpgrade(ItemStack stack, @Nullable UpgradeData upgrade) { var compound = stack.getOrCreateTag(); if (upgrade == null) { compound.remove(NBT_UPGRADE); + compound.remove(NBT_UPGRADE_INFO); } else { compound.putString(NBT_UPGRADE, upgrade.getUpgradeID().toString()); + compound.put(NBT_UPGRADE_INFO, upgrade.data()); } - - compound.remove(NBT_UPGRADE_INFO); } public static CompoundTag getUpgradeInfo(ItemStack stack) { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java b/projects/common/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java index 6c74ea7b6..b0b25bd87 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/pocket/recipes/PocketComputerUpgradeRecipe.java @@ -5,6 +5,7 @@ package dan200.computercraft.shared.pocket.recipes; import dan200.computercraft.api.pocket.IPocketUpgrade; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.impl.PocketUpgrades; import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.pocket.items.PocketComputerItem; @@ -62,7 +63,7 @@ public final class PocketComputerUpgradeRecipe extends CustomRecipe { if (PocketComputerItem.getUpgrade(computer) != null) return ItemStack.EMPTY; // Check for upgrades around the item - IPocketUpgrade upgrade = null; + UpgradeData upgrade = null; for (var y = 0; y < inventory.getHeight(); y++) { for (var x = 0; x < inventory.getWidth(); x++) { var item = inventory.getItem(x + y * inventory.getWidth()); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlock.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlock.java index 476c044e7..4267b723d 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlock.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/blocks/TurtleBlock.java @@ -6,6 +6,7 @@ package dan200.computercraft.shared.turtle.blocks; import dan200.computercraft.annotations.ForgeOverride; import dan200.computercraft.api.turtle.TurtleSide; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.shared.computer.blocks.AbstractComputerBlock; import dan200.computercraft.shared.computer.blocks.AbstractComputerBlockEntity; import dan200.computercraft.shared.computer.core.ComputerFamily; @@ -129,10 +130,6 @@ public class TurtleBlock extends AbstractComputerBlock implem // Set Upgrades for (var side : TurtleSide.values()) { turtle.getAccess().setUpgrade(side, item.getUpgrade(stack, side)); - var updateData = item.getUpgradeData(stack, side); - if (updateData != null && !updateData.isEmpty()) { - turtle.getAccess().getUpgradeNBTData(side).merge(updateData); - } } turtle.getAccess().setFuelLevel(item.getFuelLevel(stack)); @@ -165,9 +162,9 @@ public class TurtleBlock extends AbstractComputerBlock implem var access = turtle.getAccess(); return TurtleItem.create( turtle.getComputerID(), turtle.getLabel(), access.getColour(), turtle.getFamily(), - access.getUpgrade(TurtleSide.LEFT), access.getUpgrade(TurtleSide.RIGHT), - access.getFuelLevel(), turtle.getOverlay(), - access.getUpgradeNBTData(TurtleSide.LEFT), access.getUpgradeNBTData(TurtleSide.RIGHT) + UpgradeData.persist(access.getUpgradeData(TurtleSide.LEFT)), + UpgradeData.persist(access.getUpgradeData(TurtleSide.RIGHT)), + access.getFuelLevel(), turtle.getOverlay() ); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java index ecfc1f787..356f05184 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java @@ -13,6 +13,7 @@ import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleAnimation; import dan200.computercraft.api.turtle.TurtleCommand; import dan200.computercraft.api.turtle.TurtleSide; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.core.computer.ComputerSide; import dan200.computercraft.core.util.Colour; import dan200.computercraft.impl.TurtleUpgrades; @@ -529,6 +530,20 @@ public class TurtleBrain implements TurtleAccessInternal { owner.updateInputsImmediately(); } + @Override + public void setUpgrade(TurtleSide side, @Nullable UpgradeData upgrade) { + if (!setUpgradeDirect(side, upgrade) || owner.getLevel() == null) return; + + // This is a separate function to avoid updating the block when reading the NBT. We don't need to do this as + // either the block is newly placed (and so won't have changed) or is being updated with /data, which calls + // updateBlock for us. + BlockEntityHelpers.updateBlock(owner); + + // Recompute peripherals in case an upgrade being removed has exposed a new peripheral. + // TODO: Only update peripherals, or even only two sides? + owner.updateInputsImmediately(); + } + private boolean setUpgradeDirect(TurtleSide side, @Nullable ITurtleUpgrade upgrade) { // Remove old upgrade if (upgrades.containsKey(side)) { @@ -551,6 +566,13 @@ public class TurtleBrain implements TurtleAccessInternal { return true; } + private boolean setUpgradeDirect(TurtleSide side, @Nullable UpgradeData upgrade) { + if (upgrade == null) return setUpgradeDirect(side, (ITurtleUpgrade) null); + var result = setUpgradeDirect(side, upgrade.upgrade()); + if (result) upgradeNBTData.put(side, upgrade.data()); + return result; + } + @Override public @Nullable IPeripheral getPeripheral(TurtleSide side) { return peripherals.get(side); diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleEquipCommand.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleEquipCommand.java index 44d5e098d..fa88d92b1 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleEquipCommand.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/core/TurtleEquipCommand.java @@ -5,9 +5,9 @@ package dan200.computercraft.shared.turtle.core; import dan200.computercraft.api.turtle.*; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.impl.TurtleUpgrades; import dan200.computercraft.shared.turtle.TurtleUtil; -import net.minecraft.nbt.CompoundTag; public class TurtleEquipCommand implements TurtleCommand { private final TurtleSide side; @@ -22,7 +22,7 @@ public class TurtleEquipCommand implements TurtleCommand { var oldUpgrade = turtle.getUpgrade(side); // Determine the upgrade to equipLeft - ITurtleUpgrade newUpgrade; + UpgradeData newUpgrade; var selectedStack = turtle.getInventory().getItem(turtle.getSelectedSlot()); if (!selectedStack.isEmpty()) { newUpgrade = TurtleUpgrades.instance().get(selectedStack); @@ -31,16 +31,12 @@ public class TurtleEquipCommand implements TurtleCommand { newUpgrade = null; } - CompoundTag upgradeData = null; - // Do the swapping: if (newUpgrade != null) { - var upgradeItem = turtle.getInventory().removeItem(turtle.getSelectedSlot(), 1); - upgradeData = newUpgrade.produceUpgradeData(upgradeItem); + turtle.getInventory().removeItem(turtle.getSelectedSlot(), 1); } - if (oldUpgrade != null) TurtleUtil.storeItemOrDrop(turtle, oldUpgrade.produceCraftingItem(turtle.getUpgradeNBTData(side)).copy()); + if (oldUpgrade != null) TurtleUtil.storeItemOrDrop(turtle, oldUpgrade.getUpgradeItem(turtle.getUpgradeNBTData(side)).copy()); turtle.setUpgrade(side, newUpgrade); - if (upgradeData != null) turtle.getUpgradeNBTData(side).merge(upgradeData); // Animate if (newUpgrade != null || oldUpgrade != null) { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItem.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItem.java index 377fa9531..3940a3652 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItem.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/items/TurtleItem.java @@ -8,6 +8,7 @@ import dan200.computercraft.annotations.ForgeOverride; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleSide; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.impl.TurtleUpgrades; import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.common.IColouredItem; @@ -15,7 +16,6 @@ import dan200.computercraft.shared.computer.core.ComputerFamily; import dan200.computercraft.shared.computer.items.AbstractComputerItem; import dan200.computercraft.shared.turtle.blocks.TurtleBlock; import net.minecraft.core.cauldron.CauldronInteraction; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.InteractionResult; @@ -33,24 +33,22 @@ public class TurtleItem extends AbstractComputerItem implements IColouredItem { public static ItemStack create( int id, @Nullable String label, int colour, ComputerFamily family, - @Nullable ITurtleUpgrade leftUpgrade, @Nullable ITurtleUpgrade rightUpgrade, - int fuelLevel, @Nullable ResourceLocation overlay, - @Nullable CompoundTag leftUpgradeData, @Nullable CompoundTag rightUpdateData + @Nullable UpgradeData leftUpgrade, @Nullable UpgradeData rightUpgrade, + int fuelLevel, @Nullable ResourceLocation overlay ) { return switch (family) { case NORMAL -> - ModRegistry.Items.TURTLE_NORMAL.get().create(id, label, colour, leftUpgrade, rightUpgrade, fuelLevel, overlay, leftUpgradeData, rightUpdateData); + ModRegistry.Items.TURTLE_NORMAL.get().create(id, label, colour, leftUpgrade, rightUpgrade, fuelLevel, overlay); case ADVANCED -> - ModRegistry.Items.TURTLE_ADVANCED.get().create(id, label, colour, leftUpgrade, rightUpgrade, fuelLevel, overlay, leftUpgradeData, rightUpdateData); + ModRegistry.Items.TURTLE_ADVANCED.get().create(id, label, colour, leftUpgrade, rightUpgrade, fuelLevel, overlay); default -> ItemStack.EMPTY; }; } public ItemStack create( int id, @Nullable String label, int colour, - @Nullable ITurtleUpgrade leftUpgrade, @Nullable ITurtleUpgrade rightUpgrade, - int fuelLevel, @Nullable ResourceLocation overlay, - @Nullable CompoundTag leftUpgradeData, @Nullable CompoundTag rightUpdateData + @Nullable UpgradeData leftUpgrade, @Nullable UpgradeData rightUpgrade, + int fuelLevel, @Nullable ResourceLocation overlay ) { // Build the stack var stack = new ItemStack(this); @@ -62,20 +60,17 @@ public class TurtleItem extends AbstractComputerItem implements IColouredItem { if (leftUpgrade != null) { stack.getOrCreateTag().putString(NBT_LEFT_UPGRADE, leftUpgrade.getUpgradeID().toString()); - } - - if (leftUpgradeData != null && !leftUpgradeData.isEmpty()) { - stack.getOrCreateTag().put(NBT_LEFT_UPGRADE_DATA, leftUpgradeData); + if (!leftUpgrade.data().isEmpty()) { + stack.getOrCreateTag().put(NBT_LEFT_UPGRADE_DATA, leftUpgrade.data()); + } } if (rightUpgrade != null) { stack.getOrCreateTag().putString(NBT_RIGHT_UPGRADE, rightUpgrade.getUpgradeID().toString()); + if (!rightUpgrade.data().isEmpty()) { + stack.getOrCreateTag().put(NBT_RIGHT_UPGRADE_DATA, rightUpgrade.data()); + } } - - if (rightUpdateData != null && !rightUpdateData.isEmpty()) { - stack.getOrCreateTag().put(NBT_RIGHT_UPGRADE_DATA, rightUpdateData); - } - return stack; } @@ -86,16 +81,16 @@ public class TurtleItem extends AbstractComputerItem implements IColouredItem { var right = getUpgrade(stack, TurtleSide.RIGHT); if (left != null && right != null) { return Component.translatable(baseString + ".upgraded_twice", - Component.translatable(right.getUnlocalisedAdjective()), - Component.translatable(left.getUnlocalisedAdjective()) + Component.translatable(right.upgrade().getUnlocalisedAdjective()), + Component.translatable(left.upgrade().getUnlocalisedAdjective()) ); } else if (left != null) { return Component.translatable(baseString + ".upgraded", - Component.translatable(left.getUnlocalisedAdjective()) + Component.translatable(left.upgrade().getUnlocalisedAdjective()) ); } else if (right != null) { return Component.translatable(baseString + ".upgraded", - Component.translatable(right.getUnlocalisedAdjective()) + Component.translatable(right.upgrade().getUnlocalisedAdjective()) ); } else { return Component.translatable(baseString); @@ -110,13 +105,13 @@ public class TurtleItem extends AbstractComputerItem implements IColouredItem { var left = getUpgrade(stack, TurtleSide.LEFT); if (left != null) { - var mod = TurtleUpgrades.instance().getOwner(left); + var mod = TurtleUpgrades.instance().getOwner(left.upgrade()); if (mod != null && !mod.equals(ComputerCraftAPI.MOD_ID)) return mod; } var right = getUpgrade(stack, TurtleSide.RIGHT); if (right != null) { - var mod = TurtleUpgrades.instance().getOwner(right); + var mod = TurtleUpgrades.instance().getOwner(right.upgrade()); if (mod != null && !mod.equals(ComputerCraftAPI.MOD_ID)) return mod; } @@ -129,25 +124,22 @@ public class TurtleItem extends AbstractComputerItem implements IColouredItem { getComputerID(stack), getLabel(stack), getColour(stack), family, getUpgrade(stack, TurtleSide.LEFT), getUpgrade(stack, TurtleSide.RIGHT), - getFuelLevel(stack), getOverlay(stack), - getUpgradeData(stack, TurtleSide.LEFT), getUpgradeData(stack, TurtleSide.RIGHT) + getFuelLevel(stack), getOverlay(stack) ); } - public @Nullable ITurtleUpgrade getUpgrade(ItemStack stack, TurtleSide side) { + public @Nullable UpgradeData getUpgrade(ItemStack stack, TurtleSide side) { var tag = stack.getTag(); if (tag == null) return null; var key = side == TurtleSide.LEFT ? NBT_LEFT_UPGRADE : NBT_RIGHT_UPGRADE; - return tag.contains(key) ? TurtleUpgrades.instance().get(tag.getString(key)) : null; - } - - public @Nullable CompoundTag getUpgradeData(ItemStack stack, TurtleSide side) { - var tag = stack.getTag(); - if (tag == null) return null; - - var key = side == TurtleSide.LEFT ? NBT_LEFT_UPGRADE_DATA : NBT_RIGHT_UPGRADE_DATA; - return tag.contains(key) ? tag.getCompound(key) : null; + if (!tag.contains(key)) return null; + var upgrade = TurtleUpgrades.instance().get(tag.getString(key)); + if (upgrade == null) return null; + var dataKey = side == TurtleSide.LEFT ? NBT_LEFT_UPGRADE_DATA : NBT_RIGHT_UPGRADE_DATA; + return new UpgradeData<>( + upgrade, tag.getCompound(dataKey) + ); } public @Nullable ResourceLocation getOverlay(ItemStack stack) { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleOverlayRecipe.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleOverlayRecipe.java index 88e98c0b5..4076a3662 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleOverlayRecipe.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleOverlayRecipe.java @@ -41,9 +41,7 @@ public class TurtleOverlayRecipe extends ShapelessRecipe { turtle.getUpgrade(stack, TurtleSide.LEFT), turtle.getUpgrade(stack, TurtleSide.RIGHT), turtle.getFuelLevel(stack), - overlay, - turtle.getUpgradeData(stack, TurtleSide.LEFT), - turtle.getUpgradeData(stack, TurtleSide.RIGHT) + overlay ); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleRecipe.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleRecipe.java index 2e022665f..2b786a5db 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleRecipe.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleRecipe.java @@ -31,7 +31,7 @@ public final class TurtleRecipe extends ComputerFamilyRecipe { var computerID = item.getComputerID(stack); var label = item.getLabel(stack); - return TurtleItem.create(computerID, label, -1, getFamily(), null, null, 0, null, null, null); + return TurtleItem.create(computerID, label, -1, getFamily(), null, null, 0, null); } public static class Serializer extends ComputerFamilyRecipe.Serializer { diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleUpgradeRecipe.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleUpgradeRecipe.java index 0105cabcb..d072f36e2 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleUpgradeRecipe.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/recipes/TurtleUpgradeRecipe.java @@ -4,8 +4,8 @@ package dan200.computercraft.shared.turtle.recipes; -import dan200.computercraft.api.turtle.ITurtleUpgrade; import dan200.computercraft.api.turtle.TurtleSide; +import dan200.computercraft.api.upgrades.UpgradeData; import dan200.computercraft.impl.TurtleUpgrades; import dan200.computercraft.shared.ModRegistry; import dan200.computercraft.shared.turtle.items.TurtleItem; @@ -30,7 +30,7 @@ public final class TurtleUpgradeRecipe extends CustomRecipe { @Override public ItemStack getResultItem(RegistryAccess registryAccess) { - return ModRegistry.Items.TURTLE_NORMAL.get().create(-1, null, -1, null, null, 0, null, null, null); + return ModRegistry.Items.TURTLE_NORMAL.get().create(-1, null, -1, null, null, 0, null); } @Override @@ -104,7 +104,7 @@ public final class TurtleUpgradeRecipe extends CustomRecipe { // At this point we have a turtle + 1 or 2 items // Get the turtle we already have var itemTurtle = (TurtleItem) turtle.getItem(); - var upgrades = new ITurtleUpgrade[]{ + var upgrades = new UpgradeData[]{ itemTurtle.getUpgrade(turtle, TurtleSide.LEFT), itemTurtle.getUpgrade(turtle, TurtleSide.RIGHT), }; @@ -126,8 +126,7 @@ public final class TurtleUpgradeRecipe extends CustomRecipe { var colour = itemTurtle.getColour(turtle); var overlay = itemTurtle.getOverlay(turtle); return itemTurtle.create( - computerID, label, colour, upgrades[0], upgrades[1], fuelLevel, overlay, - itemTurtle.getUpgradeData(turtle, TurtleSide.LEFT), itemTurtle.getUpgradeData(turtle, TurtleSide.RIGHT) + computerID, label, colour, upgrades[0], upgrades[1], fuelLevel, overlay ); } diff --git a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java index 4c514de2d..531a3c0a6 100644 --- a/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java +++ b/projects/common/src/main/java/dan200/computercraft/shared/turtle/upgrades/TurtleModem.java @@ -9,11 +9,13 @@ import dan200.computercraft.api.turtle.*; import dan200.computercraft.shared.peripheral.modem.ModemState; import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemPeripheral; import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; +import javax.annotation.Nonnull; import javax.annotation.Nullable; public class TurtleModem extends AbstractTurtleUpgrade { @@ -77,4 +79,10 @@ public class TurtleModem extends AbstractTurtleUpgrade { } } } + + @Nonnull + @Override + public CompoundTag getPersistedData(CompoundTag upgradeData) { + return new CompoundTag(); + } }