From d8b971fca0df1223908f92c3d63be80617799248 Mon Sep 17 00:00:00 2001 From: agnor99 Date: Fri, 17 Sep 2021 10:19:13 +0200 Subject: [PATCH] Added better datasyncing --- .../client/tile/render/BotariumRenderer.java | 9 +- .../display/container/AutomaticContainer.java | 17 ++- .../display/screen/ExchangeStationScreen.java | 22 +++- .../display/screen/widget/ListWidget.java | 27 +++-- .../addon/energy/EnergyStorageAddon.java | 4 + .../machine/addon/fluid/FluidTankAddon.java | 1 - .../progressbar/MultiProgressBarAddon.java | 5 + .../addon/progressbar/ProgressBarAddon.java | 2 +- .../machine/controller/MachineController.java | 38 ++++-- .../techarium/network/NetworkConnection.java | 1 + .../ServerToClientContainerPacket.java | 56 +++++++++ .../container/SyncContainerPacket.java | 60 ++++++++++ .../tile/arboretum/ArboretumTile.java | 10 +- .../tile/base/MachineMasterTile.java | 33 ++---- .../techarium/tile/base/MachineSlaveTile.java | 10 -- .../techarium/tile/base/MachineTileBase.java | 112 ++++++++++++++++-- .../techarium/tile/botarium/BotariumTile.java | 10 +- .../techarium/tile/depot/DepotTileEntity.java | 11 +- .../exchangestation/ExchangeStationTile.java | 7 +- .../tile/sync/AdvancedTechariumDataSlot.java | 32 +++++ .../techarium/tile/sync/BooleanDataSlot.java | 27 +++++ .../tile/sync/FluidStackDataSlot.java | 38 ++++++ .../techarium/tile/sync/IntDataSlot.java | 27 +++++ .../tile/sync/ItemStackDataSlot.java | 37 ++++++ .../tile/sync/ResourceLocationDataSlot.java | 37 ++++++ .../tile/sync/TechariumDataSlot.java | 53 +++++++++ .../tile/sync/TechariumSerializable.java | 9 ++ .../resources/META-INF/accesstransformer.cfg | 3 +- 28 files changed, 611 insertions(+), 87 deletions(-) create mode 100644 src/main/java/software/bernie/techarium/network/container/ServerToClientContainerPacket.java create mode 100644 src/main/java/software/bernie/techarium/network/container/SyncContainerPacket.java create mode 100644 src/main/java/software/bernie/techarium/tile/sync/AdvancedTechariumDataSlot.java create mode 100644 src/main/java/software/bernie/techarium/tile/sync/BooleanDataSlot.java create mode 100644 src/main/java/software/bernie/techarium/tile/sync/FluidStackDataSlot.java create mode 100644 src/main/java/software/bernie/techarium/tile/sync/IntDataSlot.java create mode 100644 src/main/java/software/bernie/techarium/tile/sync/ItemStackDataSlot.java create mode 100644 src/main/java/software/bernie/techarium/tile/sync/ResourceLocationDataSlot.java create mode 100644 src/main/java/software/bernie/techarium/tile/sync/TechariumDataSlot.java create mode 100644 src/main/java/software/bernie/techarium/tile/sync/TechariumSerializable.java diff --git a/src/main/java/software/bernie/techarium/client/tile/render/BotariumRenderer.java b/src/main/java/software/bernie/techarium/client/tile/render/BotariumRenderer.java index a6a7c381..e27fd6b0 100644 --- a/src/main/java/software/bernie/techarium/client/tile/render/BotariumRenderer.java +++ b/src/main/java/software/bernie/techarium/client/tile/render/BotariumRenderer.java @@ -13,7 +13,6 @@ import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.Ingredient; import net.minecraft.state.IntegerProperty; import net.minecraft.state.Property; import net.minecraft.state.properties.BlockStateProperties; @@ -22,7 +21,6 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.vector.Quaternion; import net.minecraftforge.client.model.data.EmptyModelData; -import net.minecraftforge.common.Tags; import software.bernie.geckolib3.renderers.geo.GeoBlockRenderer; import software.bernie.techarium.client.RenderUtils; import software.bernie.techarium.client.tile.model.BotariumModel; @@ -216,12 +214,7 @@ private static float getMachineProgress(BotariumTile tile) { } private static ProgressBarAddon getMachineProgressBarAddon(BotariumTile tile) { - for (ProgressBarAddon progressBarAddon : tile.getController().getMultiProgressBar().getProgressBarAddons()) { - if (progressBarAddon.getName().equals("techarium.gui.mainprogress")) { - return progressBarAddon; - } - } - throw new NullPointerException("No progressbar found"); + return tile.getController().getMultiProgressBar().getBarByName("techarium.gui.mainprogress").orElseThrow(() -> new NullPointerException("No progressbar found")); } @Override diff --git a/src/main/java/software/bernie/techarium/display/container/AutomaticContainer.java b/src/main/java/software/bernie/techarium/display/container/AutomaticContainer.java index 3a8f0620..da81be36 100644 --- a/src/main/java/software/bernie/techarium/display/container/AutomaticContainer.java +++ b/src/main/java/software/bernie/techarium/display/container/AutomaticContainer.java @@ -4,16 +4,20 @@ import net.minecraft.block.Block; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.ContainerType; +import net.minecraft.inventory.container.IContainerListener; import net.minecraft.inventory.container.Slot; import net.minecraft.item.ItemStack; -import net.minecraft.item.crafting.IRecipe; import net.minecraft.network.PacketBuffer; import net.minecraft.util.IWorldPosCallable; import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fml.network.NetworkDirection; import software.bernie.techarium.machine.controller.MachineController; import software.bernie.techarium.machine.interfaces.recipe.IMachineRecipe; +import software.bernie.techarium.network.NetworkConnection; +import software.bernie.techarium.network.container.SyncContainerPacket; import software.bernie.techarium.tile.base.MachineMasterTile; import software.bernie.techarium.util.Vector2i; import software.bernie.techarium.util.inventory.ContainerUtil; @@ -76,6 +80,17 @@ public MachineController getMachineController() { return tile.getController(); } + @Override + public void broadcastChanges() { + super.broadcastChanges(); + for (IContainerListener containerListener : containerListeners) { + if (containerListener instanceof ServerPlayerEntity) { + NetworkConnection.INSTANCE.sendTo(new SyncContainerPacket(this), ((ServerPlayerEntity) containerListener).connection.connection, NetworkDirection.PLAY_TO_CLIENT); + + } + } + } + @Override public ItemStack quickMoveStack(PlayerEntity player, int index) { return ContainerUtil.handleShiftClick(this, player, index); diff --git a/src/main/java/software/bernie/techarium/display/screen/ExchangeStationScreen.java b/src/main/java/software/bernie/techarium/display/screen/ExchangeStationScreen.java index 9024e307..2a9305d0 100644 --- a/src/main/java/software/bernie/techarium/display/screen/ExchangeStationScreen.java +++ b/src/main/java/software/bernie/techarium/display/screen/ExchangeStationScreen.java @@ -1,13 +1,14 @@ package software.bernie.techarium.display.screen; +import com.mojang.blaze3d.matrix.MatrixStack; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.ITextComponent; import software.bernie.techarium.display.container.AutomaticContainer; import software.bernie.techarium.display.container.ExchangeStationContainer; -import software.bernie.techarium.display.screen.widget.SelectableWidget; import software.bernie.techarium.display.screen.widget.ListWidget; import software.bernie.techarium.display.screen.widget.exchange.RecipeWidget; +import software.bernie.techarium.machine.interfaces.recipe.IMachineRecipe; import software.bernie.techarium.network.NetworkConnection; import software.bernie.techarium.network.container.RecipeWidgetClickContainerPacket; import software.bernie.techarium.recipe.recipe.ExchangeStationRecipe; @@ -26,6 +27,7 @@ public class ExchangeStationScreen extends AutomaticContainerScreen { private List recipes; private final ExchangeStationContainer exchangeStationContainer; + ListWidget listWidget; //weird generic stuff, pls put only ExchangeStationStuff here public ExchangeStationScreen(AutomaticContainer container, PlayerInventory inv, ITextComponent containerName) { @@ -36,21 +38,29 @@ public ExchangeStationScreen(AutomaticContainer container, PlayerInventory inv, recipes = exchangeStationContainer.getMachineController().getRecipes().collect(Collectors.toList()); } + @Override + public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) { + super.render(matrixStack, mouseX, mouseY, partialTicks); + IMachineRecipe currentRecipe = exchangeStationContainer.getTile().getController().getCurrentRecipe(); + if (recipes.contains(currentRecipe)) { + listWidget.select(recipes.indexOf(currentRecipe)); + } + } + @Override protected void init() { super.init(); - List widgets = new ArrayList<>(); + List widgets = new ArrayList<>(); for (int i = 0; i < recipes.size(); i++) { ExchangeStationRecipe recipe = recipes.get(i); RecipeWidget recipeWidget = new RecipeWidget(new Vector2i(16 + leftPos, 24 + topPos + 18*i), recipe.getInput(), recipe.getOutput()); recipeWidget.onClick = Optional.of((widget, screen) -> NetworkConnection.INSTANCE.sendToServer(new RecipeWidgetClickContainerPacket(getMenu(), widget))); widgets.add(recipeWidget); } - ListWidget widget = new ListWidget(new Vector2i(15 + leftPos,23 + topPos), new Vector2i(62,110),new Vector2i(54,0), 110, widgets, 6, 1, 18, this); - addButton(widget); - widget.getRekursiveSubWidgets().forEach(this::addButton); + listWidget = new ListWidget(new Vector2i(15 + leftPos,23 + topPos), new Vector2i(62,110),new Vector2i(54,0), 110, widgets, 6, 1, 18, this); + addButton(listWidget); + listWidget.getRekursiveSubWidgets().forEach(this::addButton); } - @Override public ExchangeStationContainer getMenu() { return (ExchangeStationContainer) super.getMenu(); diff --git a/src/main/java/software/bernie/techarium/display/screen/widget/ListWidget.java b/src/main/java/software/bernie/techarium/display/screen/widget/ListWidget.java index c61f841f..92bba2d4 100644 --- a/src/main/java/software/bernie/techarium/display/screen/widget/ListWidget.java +++ b/src/main/java/software/bernie/techarium/display/screen/widget/ListWidget.java @@ -11,8 +11,8 @@ import java.util.ArrayList; import java.util.List; -public class ListWidget extends Widget { - final List widgets; +public class ListWidget extends Widget { + final List widgets; final int numWidgets; final ScrollBarWidget scrollBar; final int firstY; @@ -20,7 +20,7 @@ public class ListWidget extends Widget { private final Screen on; - public ListWidget(Vector2i pos, Vector2i size, Vector2i scrollBarPos, int scrollBarLength, List widgets, int numWidgets, int firstY, int yOff, Screen on) { + public ListWidget(Vector2i pos, Vector2i size, Vector2i scrollBarPos, int scrollBarLength, List widgets, int numWidgets, int firstY, int yOff, Screen on) { super(pos.getX(), pos.getY(), size.getX(), size.getY(), StringTextComponent.EMPTY); scrollBar = new ScrollBarWidget(scrollBarPos.add(pos), scrollBarLength, true, false); this.widgets = widgets; @@ -54,11 +54,11 @@ private int topVisibleWidget() { return Math.min((int)(scrollBar.getScrollPosition()/(1f/(widgets.size()-numWidgets+1))),widgets.size() - numWidgets); } - public void elementClicked(SelectableWidget widget) { + public void elementClicked(T widget) { if (!widgets.contains(widget)) return; for (int i = 0; i < widgets.size(); i++) { - SelectableWidget localWidget = widgets.get(i); + T localWidget = widgets.get(i); if (localWidget == widget) { localWidget.setSelected(true); int finalI = i; @@ -69,8 +69,21 @@ public void elementClicked(SelectableWidget widget) { } } - public SelectableWidget getSelected() { - for (SelectableWidget widget : widgets) { + public void select(int index) { + for (int i = 0; i < widgets.size(); i++) { + T localWidget = widgets.get(i); + if (i == index) { + localWidget.setSelected(true); + int finalI = i; + localWidget.onClick.ifPresent(onClick -> onClick.accept(finalI, on)); + } else { + localWidget.setSelected(false); + } + } + } + + public T getSelected() { + for (T widget : widgets) { if (widget.isSelected()) return widget; } diff --git a/src/main/java/software/bernie/techarium/machine/addon/energy/EnergyStorageAddon.java b/src/main/java/software/bernie/techarium/machine/addon/energy/EnergyStorageAddon.java index 843ba4d0..49f105de 100644 --- a/src/main/java/software/bernie/techarium/machine/addon/energy/EnergyStorageAddon.java +++ b/src/main/java/software/bernie/techarium/machine/addon/energy/EnergyStorageAddon.java @@ -37,6 +37,10 @@ public void forceSetEnergy(int energy) { this.energy = energy; } + public void setMaxEnergyStored(int maxEnergyStored) { + capacity = maxEnergyStored; + } + public EnergyStorageAddon(int totalEnergy, int maxIO, int posX, int posY) { this(totalEnergy, maxIO, maxIO, posX, posY); } diff --git a/src/main/java/software/bernie/techarium/machine/addon/fluid/FluidTankAddon.java b/src/main/java/software/bernie/techarium/machine/addon/fluid/FluidTankAddon.java index 5700b182..ddf6aa05 100644 --- a/src/main/java/software/bernie/techarium/machine/addon/fluid/FluidTankAddon.java +++ b/src/main/java/software/bernie/techarium/machine/addon/fluid/FluidTankAddon.java @@ -195,5 +195,4 @@ public List createToolTipMessage() { public static String getFluidName(FluidStack stack) { return new TranslationTextComponent(stack.getFluid().getAttributes().getTranslationKey(stack)).getString(); } - } diff --git a/src/main/java/software/bernie/techarium/machine/addon/progressbar/MultiProgressBarAddon.java b/src/main/java/software/bernie/techarium/machine/addon/progressbar/MultiProgressBarAddon.java index 93b4e10d..2712c640 100644 --- a/src/main/java/software/bernie/techarium/machine/addon/progressbar/MultiProgressBarAddon.java +++ b/src/main/java/software/bernie/techarium/machine/addon/progressbar/MultiProgressBarAddon.java @@ -1,11 +1,13 @@ package software.bernie.techarium.machine.addon.progressbar; import net.minecraft.inventory.container.Slot; +import software.bernie.techarium.machine.addon.fluid.FluidTankAddon; import software.bernie.techarium.machine.interfaces.IContainerComponentProvider; import software.bernie.techarium.machine.interfaces.IFactory; import java.util.ArrayList; import java.util.List; +import java.util.Optional; public class MultiProgressBarAddon implements IContainerComponentProvider { @@ -38,6 +40,9 @@ public void attemptTickAllBars() { } } + public Optional getBarByName(String name) { + return progressBarAddons.stream().filter(addon -> addon.getName().equals(name)).findFirst(); + } public List getProgressBarAddons() { return progressBarAddons; } diff --git a/src/main/java/software/bernie/techarium/machine/addon/progressbar/ProgressBarAddon.java b/src/main/java/software/bernie/techarium/machine/addon/progressbar/ProgressBarAddon.java index 535f5eeb..e7e8d6f8 100644 --- a/src/main/java/software/bernie/techarium/machine/addon/progressbar/ProgressBarAddon.java +++ b/src/main/java/software/bernie/techarium/machine/addon/progressbar/ProgressBarAddon.java @@ -211,7 +211,7 @@ public List> getContainerComponents() { @Override public List createToolTipMessage() { DecimalFormat decimalFormat = new DecimalFormat(); - int progress = (this.getMaxProgress() - this.getProgress()) / this.getProgressToAdd(); + int progress = (this.getMaxProgress() - this.getProgress()) / getProgressToAdd(); if (!this.canProgressUp()) { progress = this.getMaxProgress() - progress; } diff --git a/src/main/java/software/bernie/techarium/machine/controller/MachineController.java b/src/main/java/software/bernie/techarium/machine/controller/MachineController.java index c697d075..61bdebf9 100644 --- a/src/main/java/software/bernie/techarium/machine/controller/MachineController.java +++ b/src/main/java/software/bernie/techarium/machine/controller/MachineController.java @@ -21,6 +21,7 @@ import software.bernie.techarium.machine.interfaces.IFactory; import software.bernie.techarium.machine.interfaces.recipe.IMachineRecipe; import software.bernie.techarium.tile.base.MachineMasterTile; +import software.bernie.techarium.tile.sync.*; import software.bernie.techarium.util.Vector2i; import java.util.ArrayList; import java.util.HashMap; @@ -50,7 +51,7 @@ public class MachineController implements IContainerCo private Map playerHotbarSlotsXY = new HashMap<>(); private boolean isPowered; private EnergyStorageAddon energyStorage; - private final LazyOptional lazyEnergyStorage = LazyOptional.of(this::getEnergyStorage); + private final LazyOptional lazyEnergyStorage = LazyOptional.of(this::getEnergyStorage); private MultiInventoryAddon multiInventory = new MultiInventoryAddon(); private MultiFluidTankAddon multiTank = new MultiFluidTankAddon(); @@ -160,7 +161,7 @@ public MultiFluidTankAddon getMultiTank() { return multiTank; } - public LazyOptional getLazyEnergyStorage() { + public LazyOptional getLazyEnergyStorage() { return lazyEnergyStorage; } @@ -191,18 +192,18 @@ public List> getContainerComponents() { return components; } - public void tick() { + public void tick(boolean isServer) { + if (currentRecipeLocation != null) { + this.currentRecipe = (T) this.tile.getLevel().getRecipeManager().byKey(currentRecipeLocation).orElse(null); + currentRecipeLocation = null; + } + if (!isServer) + return; int lastEnergy = getEnergyStorage() != null ? getEnergyStorage().getEnergyStored() : 0; if (multiProgressBar != null) { this.multiProgressBar.attemptTickAllBars(); } - if(currentRecipeLocation != null) - { - this.currentRecipe = (T) this.tile.getLevel().getRecipeManager().byKey(currentRecipeLocation).orElse(null); - currentRecipeLocation = null; - } - if (currentRecipe == null) { handleRecipeNull(shouldCheckRecipe); } @@ -240,6 +241,25 @@ public Stream getRecipes() { .map(tile::castRecipe); } + public List> createDataSlots() { + List> dataSlots = new ArrayList<>(); + dataSlots.add(new ResourceLocationDataSlot( + () -> currentRecipe != null ? currentRecipe.getId() : currentRecipeLocation, + recipe -> currentRecipeLocation = recipe)); + getLazyEnergyStorage().ifPresent(energyStorage -> { + dataSlots.add(new IntDataSlot(energyStorage::getEnergyStored, energyStorage::forceSetEnergy)); + dataSlots.add(new IntDataSlot(energyStorage::getLastDrained, energyStorage::setLastDrained)); + }); + for (FluidTankAddon fluidTank : getMultiTank().getFluidTanks()) { + dataSlots.add(new FluidStackDataSlot(fluidTank::getFluid, fluidTank::setFluid)); + } + for (ProgressBarAddon progressBar : getMultiProgressBar().getProgressBarAddons()) { + dataSlots.add(new IntDataSlot(progressBar::getProgress, progressBar::setProgress)); + dataSlots.add(new IntDataSlot(progressBar::getProgressToAdd, progressBar::setProgressToAdd)); + } + return dataSlots; + } + @Override public CompoundNBT serializeNBT() { CompoundNBT nbt = new CompoundNBT(); diff --git a/src/main/java/software/bernie/techarium/network/NetworkConnection.java b/src/main/java/software/bernie/techarium/network/NetworkConnection.java index 79194bce..fc7e5017 100644 --- a/src/main/java/software/bernie/techarium/network/NetworkConnection.java +++ b/src/main/java/software/bernie/techarium/network/NetworkConnection.java @@ -24,6 +24,7 @@ public static void registerMessages() { registerMessage(new ChangedMainConfigContainerPacket()); registerMessage(new RecipeWidgetClickContainerPacket()); registerMessage(new UpdateCoilTypePacket()); + registerMessage(new SyncContainerPacket()); } public static > void registerMessage(MSG dummyPacket) { INSTANCE.registerMessage(getAndUpdateIndex(), diff --git a/src/main/java/software/bernie/techarium/network/container/ServerToClientContainerPacket.java b/src/main/java/software/bernie/techarium/network/container/ServerToClientContainerPacket.java new file mode 100644 index 00000000..393c53c7 --- /dev/null +++ b/src/main/java/software/bernie/techarium/network/container/ServerToClientContainerPacket.java @@ -0,0 +1,56 @@ +package software.bernie.techarium.network.container; + +import net.minecraft.client.Minecraft; +import net.minecraft.inventory.container.Container; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.network.NetworkDirection; +import net.minecraftforge.fml.network.NetworkEvent; +import software.bernie.techarium.network.Packet; + +import java.util.Optional; +import java.util.function.Function; + +public abstract class ServerToClientContainerPacket> extends Packet { + + private int containerID = 0; + private Function packetCreator; + + protected ServerToClientContainerPacket(Function packetCreator) { + this.packetCreator = packetCreator; + } + + protected ServerToClientContainerPacket(Container container) { + this.containerID = container.containerId; + } + + protected ServerToClientContainerPacket(PacketBuffer buffer) { + containerID = buffer.readInt(); + } + @Override + public boolean isValid(NetworkEvent.Context context) { + return true; + } + + @Override + public Optional getDirection() { + return Optional.of(NetworkDirection.PLAY_TO_CLIENT); + } + + @Override + public void write(PacketBuffer writeInto) { + writeInto.writeInt(containerID); + } + + @Override + public MSG create(PacketBuffer readFrom) { + return packetCreator.apply(readFrom); + } + + public Optional getContainer(NetworkEvent.Context context) { + Container container = Minecraft.getInstance().player.containerMenu; + if (container.containerId == containerID) { + return Optional.of(container); + } + return Optional.empty(); + } +} diff --git a/src/main/java/software/bernie/techarium/network/container/SyncContainerPacket.java b/src/main/java/software/bernie/techarium/network/container/SyncContainerPacket.java new file mode 100644 index 00000000..39296d64 --- /dev/null +++ b/src/main/java/software/bernie/techarium/network/container/SyncContainerPacket.java @@ -0,0 +1,60 @@ +package software.bernie.techarium.network.container; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.ListNBT; +import net.minecraft.network.PacketBuffer; +import net.minecraft.network.play.server.SUpdateTileEntityPacket; +import net.minecraftforge.fml.network.NetworkEvent; +import software.bernie.techarium.display.container.AutomaticContainer; +import software.bernie.techarium.tile.sync.TechariumDataSlot; + +import java.util.List; +import java.util.Optional; + +public class SyncContainerPacket extends ServerToClientContainerPacket { + CompoundNBT syncNBT = new CompoundNBT(); + public SyncContainerPacket() { + super(SyncContainerPacket::new); + } + + public SyncContainerPacket(AutomaticContainer container) { + super(container); + ListNBT listNBT = new ListNBT(); + List> dataSlots = container.getTile().getDataSlots(); + for (int i = 0; i < dataSlots.size(); i++) { + TechariumDataSlot dataSlot = dataSlots.get(i); + if (dataSlot.getMode() == TechariumDataSlot.SyncMode.RENDER) + continue; + Optional optionalNBT = dataSlot.toOptionalNBT(); + if (optionalNBT.isPresent()) { + CompoundNBT data = optionalNBT.get(); + data.putInt("dataSlotIndex", i); + listNBT.add(data); + dataSlots.get(i).updatePrevValue(); + } + } + syncNBT.put("data", listNBT); + } + + public SyncContainerPacket(PacketBuffer readFrom) { + super(readFrom); + syncNBT = readFrom.readNbt(); + } + + @Override + public void write(PacketBuffer writeInto) { + super.write(writeInto); + writeInto.writeNbt(syncNBT); + } + + @Override + public void doAction(NetworkEvent.Context context) { + getContainer(context).ifPresent(container -> { + if (container instanceof AutomaticContainer) { + AutomaticContainer automaticContainer = (AutomaticContainer) container; + automaticContainer.getTile().onDataPacket(context.getNetworkManager(), + new SUpdateTileEntityPacket(automaticContainer.getTile().getBlockPos(), -1, syncNBT)); + } + }); + } +} diff --git a/src/main/java/software/bernie/techarium/tile/arboretum/ArboretumTile.java b/src/main/java/software/bernie/techarium/tile/arboretum/ArboretumTile.java index 0a289d2f..5b397e77 100644 --- a/src/main/java/software/bernie/techarium/tile/arboretum/ArboretumTile.java +++ b/src/main/java/software/bernie/techarium/tile/arboretum/ArboretumTile.java @@ -29,8 +29,11 @@ import software.bernie.techarium.recipe.recipe.ArboretumRecipe; import software.bernie.techarium.registry.RecipeRegistry; import software.bernie.techarium.tile.base.MultiblockMasterTile; +import software.bernie.techarium.tile.sync.FluidStackDataSlot; +import software.bernie.techarium.tile.sync.IntDataSlot; +import software.bernie.techarium.tile.sync.ItemStackDataSlot; +import software.bernie.techarium.tile.sync.TechariumDataSlot; import software.bernie.techarium.util.Vector2i; - import java.util.EnumMap; import java.util.Map; @@ -68,6 +71,11 @@ private PlayState animationPredicate(AnimationEvent e public ArboretumTile() { super(ARBORETUM.getTileEntityType()); + addDataSlot(new FluidStackDataSlot(() -> getFluidInventory().getFluid(), getFluidInventory()::setFluid, TechariumDataSlot.SyncMode.RENDER)); + addDataSlot(new ItemStackDataSlot(() -> getSoilInventory().getStackInSlot(0), itemStack -> getSoilInventory().setStackInSlot(0, itemStack), TechariumDataSlot.SyncMode.RENDER)); + addDataSlot(new ItemStackDataSlot(() -> getCropInventory().getStackInSlot(0), itemStack -> getCropInventory().setStackInSlot(0, itemStack), TechariumDataSlot.SyncMode.RENDER)); + addDataSlot(new IntDataSlot(() -> getController().getMultiProgressBar().getBarByName("techarium.gui.mainprogress").get().getProgress(), progress -> getController().getMultiProgressBar().getBarByName("techarium.gui.mainprogress").get().setProgress(progress), TechariumDataSlot.SyncMode.RENDER)); + addDataSlot(new IntDataSlot(() -> getController().getMultiProgressBar().getBarByName("techarium.gui.mainprogress").get().getMaxProgress(), progress -> getController().getMultiProgressBar().getBarByName("techarium.gui.mainprogress").get().setMaxProgress(progress), TechariumDataSlot.SyncMode.RENDER)); } @Override diff --git a/src/main/java/software/bernie/techarium/tile/base/MachineMasterTile.java b/src/main/java/software/bernie/techarium/tile/base/MachineMasterTile.java index 0499737c..902c5dbc 100644 --- a/src/main/java/software/bernie/techarium/tile/base/MachineMasterTile.java +++ b/src/main/java/software/bernie/techarium/tile/base/MachineMasterTile.java @@ -7,9 +7,6 @@ import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.network.NetworkManager; -import net.minecraft.network.play.server.SUpdateTileEntityPacket; -import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; @@ -38,13 +35,14 @@ import static software.bernie.techarium.util.StaticHandler.*; -public abstract class MachineMasterTile extends MachineTileBase implements INamedContainerProvider, ITickableTileEntity, IRecipeMachine, IForcedRecipe { +public abstract class MachineMasterTile extends MachineTileBase implements INamedContainerProvider, IRecipeMachine, IForcedRecipe { private final MachineController controller; public MachineMasterTile(TileEntityType tileEntityTypeIn) { super(tileEntityTypeIn, TileBehaviours.base); controller = createMachineController(); + controller.createDataSlots().forEach(this::addDataSlot); } public MachineController getController() { @@ -110,14 +108,17 @@ public AxisAlignedBB getRenderBoundingBox() { @Override public void tick() { - this.getController().tick(); - if (!level.isClientSide()) { + boolean isServer = !level.isClientSide(); + getController().tick(isServer); + + if (isServer) { if(isFirstLoad) { updateMachineTile(); isFirstLoad = false; } else if(level.getGameTime() % 3 == 0){ isFirstLoad = true; } + super.tick(); } } @@ -125,7 +126,6 @@ public void tick() { public void load(BlockState state, CompoundNBT nbt) { getController().deserializeNBT(nbt.getCompound("activeMachine")); super.load(state, nbt); - updateMachineTile(); } @@ -135,25 +135,6 @@ public CompoundNBT save(CompoundNBT compound) { return super.save(compound); } - protected void updateMachineTile() { - requestModelDataUpdate(); - this.setChanged(); - if (this.getLevel() != null) { - this.getLevel().sendBlockUpdated(worldPosition, this.getBlockState(), this.getBlockState(), 3); - } - } - - @Nullable - @Override - public SUpdateTileEntityPacket getUpdatePacket() { - return new SUpdateTileEntityPacket(this.getBlockPos(), -1, this.getUpdateTag()); - } - - @Override - public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) { - handleUpdateTag(this.getBlockState(), pkt.getTag()); - } - @Override @Nonnull public CompoundNBT getUpdateTag() { diff --git a/src/main/java/software/bernie/techarium/tile/base/MachineSlaveTile.java b/src/main/java/software/bernie/techarium/tile/base/MachineSlaveTile.java index a070aa61..78fe1b2a 100644 --- a/src/main/java/software/bernie/techarium/tile/base/MachineSlaveTile.java +++ b/src/main/java/software/bernie/techarium/tile/base/MachineSlaveTile.java @@ -67,16 +67,6 @@ public LazyOptional getCapability(@NotNull Capability cap) { private boolean shouldGetCapabilityFromMaster(@NotNull Capability cap) { return getMasterPos() != BlockPos.ZERO && (cap == CapabilityEnergy.ENERGY || cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY || cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY); } - @Nullable - @Override - public SUpdateTileEntityPacket getUpdatePacket() { - return new SUpdateTileEntityPacket(this.getBlockPos(), -1, this.getUpdateTag()); - } - - @Override - public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) { - handleUpdateTag(this.getBlockState(), pkt.getTag()); - } @Override @Nonnull diff --git a/src/main/java/software/bernie/techarium/tile/base/MachineTileBase.java b/src/main/java/software/bernie/techarium/tile/base/MachineTileBase.java index bce4aa55..df445f75 100644 --- a/src/main/java/software/bernie/techarium/tile/base/MachineTileBase.java +++ b/src/main/java/software/bernie/techarium/tile/base/MachineTileBase.java @@ -1,22 +1,33 @@ package software.bernie.techarium.tile.base; -import java.util.HashMap; -import java.util.Map; +import java.util.*; +import java.util.stream.Stream; +import lombok.Getter; import net.minecraft.block.BlockState; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.nbt.INBT; +import net.minecraft.nbt.ListNBT; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.play.server.SUpdateTileEntityPacket; import net.minecraft.state.DirectionProperty; -import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.CompoundNBT; +import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.Hand; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.server.ServerChunkProvider; +import net.minecraftforge.fml.network.PacketDistributor; import software.bernie.techarium.Techarium; import software.bernie.techarium.block.base.TechariumBlock; import software.bernie.techarium.machine.sideness.FaceConfig; import software.bernie.techarium.machine.sideness.Side; +import software.bernie.techarium.network.NetworkConnection; +import software.bernie.techarium.tile.sync.TechariumDataSlot; import software.bernie.techarium.trait.block.BlockTraits; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; @@ -25,18 +36,32 @@ import software.bernie.techarium.trait.behaviour.IHasBehaviour; import software.bernie.techarium.trait.tile.TileBehaviour; import software.bernie.techarium.trait.tile.TileTraits; -import java.util.Optional; -public abstract class MachineTileBase extends TileEntity implements IHasBehaviour { +import javax.annotation.Nullable; + +public abstract class MachineTileBase extends TileEntity implements ITickableTileEntity, IHasBehaviour { private final TileBehaviour behaviour; private final Map sideFaceConfigs = setFaceControl(); + @Getter + private final List> dataSlots = new ArrayList<>(); + private final List lastSyncedTo = new ArrayList<>(); + public MachineTileBase(TileEntityType tileEntityTypeIn, TileBehaviour behaviour) { super(tileEntityTypeIn); this.behaviour = behaviour.copy(); behaviour.tweak(this); } + protected void addDataSlot(TechariumDataSlot dataSlot) { + dataSlots.add(dataSlot); + } + + @Override + public void tick() { + updateMachineTile(); + } + protected Map setFaceControl(){ Map defaultSetUp = new HashMap<>(); for (Side side: Side.values()){ @@ -73,6 +98,59 @@ public void load(BlockState state, CompoundNBT nbt) { updateMachineTile(); } + @Nullable + @Override + public SUpdateTileEntityPacket getUpdatePacket() { + CompoundNBT nbt = new CompoundNBT(); + ListNBT listNBT = new ListNBT(); + for (int i = 0; i < dataSlots.size(); i++) { + TechariumDataSlot dataSlot = dataSlots.get(i); + if (dataSlot.getMode() == TechariumDataSlot.SyncMode.GUI) + continue; + Optional optionalNBT = dataSlot.toOptionalNBT(); + if (optionalNBT.isPresent()) { + CompoundNBT data = optionalNBT.get(); + data.putInt("dataSlotIndex", i); + listNBT.add(data); + dataSlots.get(i).updatePrevValue(); + } + } + nbt.put("data", listNBT); + nbt.putInt("x", this.worldPosition.getX()); + nbt.putInt("y", this.worldPosition.getY()); + nbt.putInt("z", this.worldPosition.getZ()); + return new SUpdateTileEntityPacket(this.getBlockPos(), -1, nbt); + } + + public SUpdateTileEntityPacket getFullUpdatePacket() { + CompoundNBT nbt = new CompoundNBT(); + ListNBT listNBT = new ListNBT(); + for (int i = 0; i < dataSlots.size(); i++) { + TechariumDataSlot dataSlot = dataSlots.get(i); + if (dataSlot.getMode() == TechariumDataSlot.SyncMode.GUI) + continue; + CompoundNBT data = dataSlot.toNBT(); + data.putInt("dataSlotIndex", i); + listNBT.add(data); + dataSlots.get(i).updatePrevValue(); + } + nbt.put("data", listNBT); + nbt.putInt("x", this.worldPosition.getX()); + nbt.putInt("y", this.worldPosition.getY()); + nbt.putInt("z", this.worldPosition.getZ()); + return new SUpdateTileEntityPacket(this.getBlockPos(), -1, nbt); + } + + @Override + public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) { + CompoundNBT nbt = pkt.getTag(); + ListNBT listNBT = (ListNBT)nbt.get("data"); + for (INBT inbt : listNBT) { + CompoundNBT dataNBT = (CompoundNBT) inbt; + int dataSlotIndex = dataNBT.getInt("dataSlotIndex"); + dataSlots.get(dataSlotIndex).fromNBT(dataNBT); + } + } @Override public CompoundNBT save(CompoundNBT compound) { @@ -85,9 +163,29 @@ public CompoundNBT save(CompoundNBT compound) { protected void updateMachineTile() { requestModelDataUpdate(); this.setChanged(); - if (this.getLevel() != null) { - this.getLevel().sendBlockUpdated(worldPosition, this.getBlockState(), this.getBlockState(), 3); + boolean hasChanged = false; + if (level == null || level.isClientSide) + return; + for (TechariumDataSlot slot: dataSlots) { + if (slot.needsUpdate() && slot.getMode() == TechariumDataSlot.SyncMode.RENDER) { + hasChanged = true; + break; + } + } + + Chunk chunk = level.getChunkAt(worldPosition); + if (hasChanged) { + PacketDistributor.TRACKING_CHUNK.with(() -> chunk).send(getUpdatePacket()); } + SUpdateTileEntityPacket fullPacket = getFullUpdatePacket(); + getTrackingPlayers().filter(p -> !lastSyncedTo.contains(p.getUUID())).forEach(p -> p.connection.send(fullPacket)); + lastSyncedTo.clear(); + getTrackingPlayers().forEach(p -> lastSyncedTo.add(p.getUUID())); + } + + private Stream getTrackingPlayers() { + Chunk chunk = level.getChunkAt(worldPosition); + return ((ServerChunkProvider)level.getChunkSource()).chunkMap.getPlayers(chunk.getPos(), false); } @Override diff --git a/src/main/java/software/bernie/techarium/tile/botarium/BotariumTile.java b/src/main/java/software/bernie/techarium/tile/botarium/BotariumTile.java index e0561734..6e519f5d 100644 --- a/src/main/java/software/bernie/techarium/tile/botarium/BotariumTile.java +++ b/src/main/java/software/bernie/techarium/tile/botarium/BotariumTile.java @@ -25,9 +25,12 @@ import software.bernie.techarium.machine.sideness.FaceConfig; import software.bernie.techarium.machine.sideness.Side; import software.bernie.techarium.recipe.recipe.BotariumRecipe; -import software.bernie.techarium.recipe.recipe.ExchangeStationRecipe; import software.bernie.techarium.registry.RecipeRegistry; import software.bernie.techarium.tile.base.MultiblockMasterTile; +import software.bernie.techarium.tile.sync.FluidStackDataSlot; +import software.bernie.techarium.tile.sync.IntDataSlot; +import software.bernie.techarium.tile.sync.ItemStackDataSlot; +import software.bernie.techarium.tile.sync.TechariumDataSlot; import software.bernie.techarium.util.Vector2i; import java.util.EnumMap; import java.util.Map; @@ -66,6 +69,11 @@ private PlayState animationPredicate(AnimationEvent e public BotariumTile() { super(BOTARIUM.getTileEntityType()); + addDataSlot(new FluidStackDataSlot(() -> getFluidInventory().getFluid(), getFluidInventory()::setFluid, TechariumDataSlot.SyncMode.RENDER)); + addDataSlot(new ItemStackDataSlot(() -> getSoilInventory().getStackInSlot(0), itemStack -> getSoilInventory().setStackInSlot(0, itemStack), TechariumDataSlot.SyncMode.RENDER)); + addDataSlot(new ItemStackDataSlot(() -> getCropInventory().getStackInSlot(0), itemStack -> getCropInventory().setStackInSlot(0, itemStack), TechariumDataSlot.SyncMode.RENDER)); + addDataSlot(new IntDataSlot(() -> getController().getMultiProgressBar().getBarByName("techarium.gui.mainprogress").get().getProgress(), progress -> getController().getMultiProgressBar().getBarByName("techarium.gui.mainprogress").get().setProgress(progress), TechariumDataSlot.SyncMode.RENDER)); + addDataSlot(new IntDataSlot(() -> getController().getMultiProgressBar().getBarByName("techarium.gui.mainprogress").get().getMaxProgress(), progress -> getController().getMultiProgressBar().getBarByName("techarium.gui.mainprogress").get().setMaxProgress(progress), TechariumDataSlot.SyncMode.RENDER)); } @Override diff --git a/src/main/java/software/bernie/techarium/tile/depot/DepotTileEntity.java b/src/main/java/software/bernie/techarium/tile/depot/DepotTileEntity.java index 77d4355c..a98dfc61 100644 --- a/src/main/java/software/bernie/techarium/tile/depot/DepotTileEntity.java +++ b/src/main/java/software/bernie/techarium/tile/depot/DepotTileEntity.java @@ -10,9 +10,6 @@ import net.minecraft.util.ActionResultType; import net.minecraft.util.Hand; import net.minecraft.world.server.ServerWorld; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.items.CapabilityItemHandler; -import net.minecraftforge.items.IItemHandler; import software.bernie.geckolib3.core.IAnimatable; import software.bernie.geckolib3.core.PlayState; import software.bernie.geckolib3.core.builder.AnimationBuilder; @@ -34,6 +31,8 @@ import software.bernie.techarium.registry.ItemRegistry; import software.bernie.techarium.registry.RecipeRegistry; import software.bernie.techarium.tile.base.MachineMasterTile; +import software.bernie.techarium.tile.sync.ItemStackDataSlot; +import software.bernie.techarium.tile.sync.TechariumDataSlot; import java.util.List; @@ -55,6 +54,12 @@ public DepotTileEntity() { for (Side side : Side.values()) { getFaceConfigs().put(side, FaceConfig.ENABLED); } + addDataSlot(new ItemStackDataSlot(() -> getInput().getStackInSlot(0), itemStack -> getInput().setStackInSlot(0, itemStack), TechariumDataSlot.SyncMode.RENDER)); + addDataSlot(new ItemStackDataSlot(() -> getInput().getStackInSlot(1), itemStack -> getInput().setStackInSlot(1, itemStack), TechariumDataSlot.SyncMode.RENDER)); + addDataSlot(new ItemStackDataSlot(() -> getInput().getStackInSlot(2), itemStack -> getInput().setStackInSlot(2, itemStack), TechariumDataSlot.SyncMode.RENDER)); + addDataSlot(new ItemStackDataSlot(() -> getOutput().getStackInSlot(0), itemStack -> getOutput().setStackInSlot(0, itemStack), TechariumDataSlot.SyncMode.RENDER)); + addDataSlot(new ItemStackDataSlot(() -> getOutput().getStackInSlot(1), itemStack -> getOutput().setStackInSlot(1, itemStack), TechariumDataSlot.SyncMode.RENDER)); + addDataSlot(new ItemStackDataSlot(() -> getOutput().getStackInSlot(2), itemStack -> getOutput().setStackInSlot(2, itemStack), TechariumDataSlot.SyncMode.RENDER)); } @Override diff --git a/src/main/java/software/bernie/techarium/tile/exchangestation/ExchangeStationTile.java b/src/main/java/software/bernie/techarium/tile/exchangestation/ExchangeStationTile.java index 28ead26f..35cbe9de 100644 --- a/src/main/java/software/bernie/techarium/tile/exchangestation/ExchangeStationTile.java +++ b/src/main/java/software/bernie/techarium/tile/exchangestation/ExchangeStationTile.java @@ -18,7 +18,6 @@ import software.bernie.techarium.display.container.ExchangeStationContainer; import software.bernie.techarium.machine.addon.inventory.InventoryAddon; import software.bernie.techarium.machine.controller.MachineController; -import software.bernie.techarium.recipe.recipe.ArboretumRecipe; import software.bernie.techarium.recipe.recipe.ExchangeStationRecipe; import software.bernie.techarium.registry.RecipeRegistry; import software.bernie.techarium.tile.base.MachineMasterTile; @@ -50,10 +49,8 @@ public Stream getRecipes() { return super.getRecipes().sorted(Comparator.comparingInt(o1 -> o1.getInput().getCount())); } @Override - public void tick() { - if (getMultiProgressBar() != null) { - this.getMultiProgressBar().attemptTickAllBars(); - } + public void tick(boolean isServer) { + super.tick(isServer); if (getCurrentRecipe() == null) { getController().getRecipes().findFirst().ifPresent(getController()::setCurrentRecipe); } diff --git a/src/main/java/software/bernie/techarium/tile/sync/AdvancedTechariumDataSlot.java b/src/main/java/software/bernie/techarium/tile/sync/AdvancedTechariumDataSlot.java new file mode 100644 index 00000000..5f1d48dc --- /dev/null +++ b/src/main/java/software/bernie/techarium/tile/sync/AdvancedTechariumDataSlot.java @@ -0,0 +1,32 @@ +package software.bernie.techarium.tile.sync; + +import net.minecraft.nbt.CompoundNBT; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class AdvancedTechariumDataSlot & Comparable> extends TechariumDataSlot { + + public AdvancedTechariumDataSlot(Supplier getter, Consumer setter) { + super(getter, setter); + } + + @Override + protected boolean areEqual() { + return prevValue.compareTo(getter.get()) != 0; + } + + @Override + public CompoundNBT toNBT() { + return getter.get().serializeNBT(); + } + + @Override + public void fromNBT(CompoundNBT nbt) { + setter.accept(getter.get().deserializeNBT(nbt)); + } + + @Override + public void updatePrevValue() { + prevValue = getter.get() == null ? null : getter.get().copy(); + } +} diff --git a/src/main/java/software/bernie/techarium/tile/sync/BooleanDataSlot.java b/src/main/java/software/bernie/techarium/tile/sync/BooleanDataSlot.java new file mode 100644 index 00000000..0482bf1d --- /dev/null +++ b/src/main/java/software/bernie/techarium/tile/sync/BooleanDataSlot.java @@ -0,0 +1,27 @@ +package software.bernie.techarium.tile.sync; + +import net.minecraft.nbt.CompoundNBT; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class BooleanDataSlot extends TechariumDataSlot { + public BooleanDataSlot(Supplier getter, Consumer setter) { + super(getter, setter); + } + + public BooleanDataSlot(Supplier getter, Consumer setter, SyncMode mode) { + super(getter, setter, mode); + } + + @Override + public CompoundNBT toNBT() { + CompoundNBT nbt = new CompoundNBT(); + nbt.putBoolean("boolean", getter.get()); + return nbt; + } + + @Override + public void fromNBT(CompoundNBT nbt) { + setter.accept(nbt.getBoolean("boolean")); + } +} diff --git a/src/main/java/software/bernie/techarium/tile/sync/FluidStackDataSlot.java b/src/main/java/software/bernie/techarium/tile/sync/FluidStackDataSlot.java new file mode 100644 index 00000000..247453f4 --- /dev/null +++ b/src/main/java/software/bernie/techarium/tile/sync/FluidStackDataSlot.java @@ -0,0 +1,38 @@ +package software.bernie.techarium.tile.sync; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraftforge.fluids.FluidStack; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class FluidStackDataSlot extends TechariumDataSlot { + public FluidStackDataSlot(Supplier getter, Consumer setter) { + super(getter, setter); + } + + public FluidStackDataSlot(Supplier getter, Consumer setter, SyncMode mode) { + super(getter, setter, mode); + } + + @Override + public CompoundNBT toNBT() { + return getter.get().writeToNBT(new CompoundNBT()); + } + + @Override + public void fromNBT(CompoundNBT nbt) { + setter.accept(FluidStack.loadFluidStackFromNBT(nbt)); + } + + @Override + public void updatePrevValue() { + prevValue = getter.get() == null ? null : getter.get().copy(); + } + + @Override + protected boolean areEqual() { + FluidStack newFluid = getter.get(); + return prevValue.isFluidStackIdentical(newFluid); + } +} diff --git a/src/main/java/software/bernie/techarium/tile/sync/IntDataSlot.java b/src/main/java/software/bernie/techarium/tile/sync/IntDataSlot.java new file mode 100644 index 00000000..7822c2e4 --- /dev/null +++ b/src/main/java/software/bernie/techarium/tile/sync/IntDataSlot.java @@ -0,0 +1,27 @@ +package software.bernie.techarium.tile.sync; + +import net.minecraft.nbt.CompoundNBT; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class IntDataSlot extends TechariumDataSlot { + public IntDataSlot(Supplier getter, Consumer setter) { + super(getter, setter); + } + + public IntDataSlot(Supplier getter, Consumer setter, SyncMode mode) { + super(getter, setter, mode); + } + @Override + public CompoundNBT toNBT() { + CompoundNBT nbt = new CompoundNBT(); + nbt.putInt("int", getter.get()); + return nbt; + } + + @Override + public void fromNBT(CompoundNBT nbt) { + setter.accept(nbt.getInt("int")); + } +} diff --git a/src/main/java/software/bernie/techarium/tile/sync/ItemStackDataSlot.java b/src/main/java/software/bernie/techarium/tile/sync/ItemStackDataSlot.java new file mode 100644 index 00000000..c78e6f7b --- /dev/null +++ b/src/main/java/software/bernie/techarium/tile/sync/ItemStackDataSlot.java @@ -0,0 +1,37 @@ +package software.bernie.techarium.tile.sync; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class ItemStackDataSlot extends TechariumDataSlot { + public ItemStackDataSlot(Supplier getter, Consumer setter) { + super(getter, setter); + } + + public ItemStackDataSlot(Supplier getter, Consumer setter, SyncMode mode) { + super(getter, setter, mode); + } + + @Override + public CompoundNBT toNBT() { + return getter.get().serializeNBT(); + } + + @Override + public void fromNBT(CompoundNBT nbt) { + setter.accept(ItemStack.of(nbt)); + } + + @Override + public void updatePrevValue() { + prevValue = getter.get() == null ? null : getter.get().copy(); + } + + @Override + protected boolean areEqual() { + ItemStack newItemStack = getter.get(); + return prevValue.equals(newItemStack, false); + } +} diff --git a/src/main/java/software/bernie/techarium/tile/sync/ResourceLocationDataSlot.java b/src/main/java/software/bernie/techarium/tile/sync/ResourceLocationDataSlot.java new file mode 100644 index 00000000..ddbb4d58 --- /dev/null +++ b/src/main/java/software/bernie/techarium/tile/sync/ResourceLocationDataSlot.java @@ -0,0 +1,37 @@ +package software.bernie.techarium.tile.sync; + +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.ResourceLocation; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class ResourceLocationDataSlot extends TechariumDataSlot { + public ResourceLocationDataSlot(Supplier getter, Consumer setter) { + super(getter, setter); + } + + public ResourceLocationDataSlot(Supplier getter, Consumer setter, SyncMode mode) { + super(getter, setter, mode); + } + + @Override + public CompoundNBT toNBT() { + CompoundNBT nbt = new CompoundNBT(); + ResourceLocation rl = getter.get(); + if (rl != null) + nbt.putString("rl", rl.toString()); + return nbt; + } + + @Override + protected boolean areEqual() { + return prevValue.toString().equals(getter.get().toString()); + } + + @Override + public void fromNBT(CompoundNBT nbt) { + if (nbt.contains("rl")) + setter.accept(nbt.contains("rl") ? new ResourceLocation(nbt.getString("rl")) : null); + } +} diff --git a/src/main/java/software/bernie/techarium/tile/sync/TechariumDataSlot.java b/src/main/java/software/bernie/techarium/tile/sync/TechariumDataSlot.java new file mode 100644 index 00000000..b90bbc94 --- /dev/null +++ b/src/main/java/software/bernie/techarium/tile/sync/TechariumDataSlot.java @@ -0,0 +1,53 @@ +package software.bernie.techarium.tile.sync; + +import lombok.Getter; +import net.minecraft.nbt.CompoundNBT; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Supplier; + +public abstract class TechariumDataSlot { + final Supplier getter; + final Consumer setter; + @Getter + final SyncMode mode; + T prevValue; + + public TechariumDataSlot(Supplier getter, Consumer setter) { + this(getter, setter, SyncMode.GUI); + } + public TechariumDataSlot(Supplier getter, Consumer setter, SyncMode mode) { + this.getter = getter; + this.setter = setter; + this.mode = mode; + } + public Optional toOptionalNBT() { + if (needsUpdate()) { + return Optional.of(toNBT()); + } + return Optional.empty(); + } + + public abstract CompoundNBT toNBT(); + + public abstract void fromNBT(CompoundNBT nbt); + + public void updatePrevValue() { + prevValue = getter.get(); + } + public boolean needsUpdate() { + if (prevValue == null) + return getter.get() != null; + if (getter.get() == null) + return false; + return !areEqual(); + } + + protected boolean areEqual() { + return prevValue.equals(getter.get()); + } + public enum SyncMode { + RENDER, + GUI; + } +} diff --git a/src/main/java/software/bernie/techarium/tile/sync/TechariumSerializable.java b/src/main/java/software/bernie/techarium/tile/sync/TechariumSerializable.java new file mode 100644 index 00000000..5d73f71a --- /dev/null +++ b/src/main/java/software/bernie/techarium/tile/sync/TechariumSerializable.java @@ -0,0 +1,9 @@ +package software.bernie.techarium.tile.sync; + +import net.minecraft.nbt.CompoundNBT; + +public interface TechariumSerializable> { + CompoundNBT serializeNBT(); + T deserializeNBT(CompoundNBT nbt); + T copy(); +} diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 29d1e459..654dda9f 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -3,4 +3,5 @@ public net.minecraft.block.AbstractBlock field_235684_aB_ # properties public net.minecraft.block.AbstractBlock$Properties field_235803_e_ # lightLevel public net.minecraft.client.gui.screen.Screen field_230710_m_ # buttons protected-f net.minecraft.block.Block field_176227_L # stateDefinition -public net.minecraft.client.gui.screen.Screen field_230710_m_ # buttons \ No newline at end of file +public net.minecraft.client.gui.screen.Screen field_230710_m_ # buttons +protected net.minecraft.inventory.container.Container field_75149_d # containerListeners \ No newline at end of file