From e6c78610f3bab3f1875d39730f068cb696f63f7e Mon Sep 17 00:00:00 2001 From: TheMCLoveMan Date: Thu, 21 Mar 2024 23:01:51 +0100 Subject: [PATCH] [24w11a] Get some custom components to work --- .../uselessmod/api/CoffeeType.java | 14 +++ .../init/UselessDataComponents.java | 7 +- .../world/level/block/PaintBucketBlock.java | 4 +- .../entity/CoffeeMachineBlockEntity.java | 102 +++++++++++++++++- .../entity/MachineSupplierBlockEntity.java | 18 ++++ .../block/entity/PaintBucketBlockEntity.java | 13 ++- 6 files changed, 149 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/themcbrothers/uselessmod/api/CoffeeType.java b/src/main/java/net/themcbrothers/uselessmod/api/CoffeeType.java index d1be2f18..b9d7ee99 100644 --- a/src/main/java/net/themcbrothers/uselessmod/api/CoffeeType.java +++ b/src/main/java/net/themcbrothers/uselessmod/api/CoffeeType.java @@ -5,6 +5,7 @@ import net.minecraft.world.effect.MobEffectInstance; import org.jetbrains.annotations.Nullable; +import java.util.Objects; import java.util.Set; public class CoffeeType { @@ -42,6 +43,19 @@ public String getDescriptionId() { return this.descriptionId; } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CoffeeType that = (CoffeeType) o; + return color == that.color && foil == that.foil && Objects.equals(effects, that.effects); + } + + @Override + public int hashCode() { + return Objects.hash(effects, color, foil); + } + public static class Properties { private final Set effects; private final int color; diff --git a/src/main/java/net/themcbrothers/uselessmod/init/UselessDataComponents.java b/src/main/java/net/themcbrothers/uselessmod/init/UselessDataComponents.java index b70d7631..c288290c 100644 --- a/src/main/java/net/themcbrothers/uselessmod/init/UselessDataComponents.java +++ b/src/main/java/net/themcbrothers/uselessmod/init/UselessDataComponents.java @@ -10,6 +10,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.neoforged.neoforge.registries.DeferredHolder; import net.themcbrothers.uselessmod.api.CoffeeType; +import net.themcbrothers.uselessmod.world.level.block.entity.CoffeeMachineBlockEntity; import java.util.List; @@ -31,7 +32,11 @@ static void register() { () -> DataComponentType.builder() .persistent(BlockState.CODEC) .build()); - + public static final DeferredHolder, DataComponentType> COFFEE_MACHINE_CONTENTS = Registration.DATA_COMPONENT_TYPES.register("coffee_machine_contents", + () -> DataComponentType.builder() + .persistent(CoffeeMachineBlockEntity.Contents.CODEC) + .networkSynchronized(CoffeeMachineBlockEntity.Contents.STREAM_CODEC) + .build()); public static final DeferredHolder, DataComponentType> COFFEE_TYPE = Registration.DATA_COMPONENT_TYPES.register("coffee_type", () -> DataComponentType.builder() .persistent(CoffeeType.CODEC) diff --git a/src/main/java/net/themcbrothers/uselessmod/world/level/block/PaintBucketBlock.java b/src/main/java/net/themcbrothers/uselessmod/world/level/block/PaintBucketBlock.java index ef1296c4..2db85bc6 100644 --- a/src/main/java/net/themcbrothers/uselessmod/world/level/block/PaintBucketBlock.java +++ b/src/main/java/net/themcbrothers/uselessmod/world/level/block/PaintBucketBlock.java @@ -4,10 +4,10 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.NonNullList; +import net.minecraft.server.level.ServerLevel; import net.minecraft.tags.FluidTags; import net.minecraft.world.Containers; import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.DyeColor; @@ -160,7 +160,7 @@ protected ItemInteractionResult useItemOn(ItemStack p_316304_, BlockState state, @Override public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) { - if (!state.is(newState.getBlock()) && level.getBlockEntity(pos) instanceof PaintBucketBlockEntity blockEntity) { + if (level instanceof ServerLevel && !state.is(newState.getBlock()) && level.getBlockEntity(pos) instanceof PaintBucketBlockEntity blockEntity) { Containers.dropContents(level, pos, NonNullList.of(blockEntity.stackHandler.getStackInSlot(0))); } diff --git a/src/main/java/net/themcbrothers/uselessmod/world/level/block/entity/CoffeeMachineBlockEntity.java b/src/main/java/net/themcbrothers/uselessmod/world/level/block/entity/CoffeeMachineBlockEntity.java index fc5f470f..357cb9a2 100644 --- a/src/main/java/net/themcbrothers/uselessmod/world/level/block/entity/CoffeeMachineBlockEntity.java +++ b/src/main/java/net/themcbrothers/uselessmod/world/level/block/entity/CoffeeMachineBlockEntity.java @@ -1,15 +1,21 @@ package net.themcbrothers.uselessmod.world.level.block.entity; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.core.*; import net.minecraft.core.component.DataComponentMap; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.tags.FluidTags; +import net.minecraft.util.ExtraCodecs; import net.minecraft.world.ContainerHelper; import net.minecraft.world.WorldlyContainer; import net.minecraft.world.entity.player.Inventory; @@ -38,6 +44,7 @@ import net.themcbrothers.uselessmod.config.ServerConfig; import net.themcbrothers.uselessmod.init.ModBlockEntityTypes; import net.themcbrothers.uselessmod.init.ModRecipeTypes; +import net.themcbrothers.uselessmod.init.UselessDataComponents; import net.themcbrothers.uselessmod.network.packets.BlockEntitySyncPacket; import net.themcbrothers.uselessmod.world.inventory.CoffeeMachineMenu; import net.themcbrothers.uselessmod.world.item.crafting.CoffeeRecipe; @@ -308,9 +315,9 @@ public void load(CompoundTag compound, HolderLookup.Provider lookupProvider) { this.cookingProgress = compound.getInt("CookTime"); this.cookingTotalTime = compound.getInt("CookTimeTotal"); this.useMilk = compound.getBoolean("UseMilk"); + this.energyStorage.setEnergyStored(compound.getInt("EnergyStored")); this.tankHandler.getWaterTank().readFromNBT(lookupProvider, compound.getCompound("Water")); this.tankHandler.getMilkTank().readFromNBT(lookupProvider, compound.getCompound("Milk")); - this.energyStorage.setEnergyStored(compound.getInt("EnergyStored")); } @Override @@ -321,9 +328,15 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider lookupProvi tag.putInt("CookTime", this.cookingProgress); tag.putInt("CookTimeTotal", this.cookingTotalTime); tag.putBoolean("UseMilk", this.useMilk); - tag.put("Water", this.tankHandler.getWaterTank().writeToNBT(lookupProvider, new CompoundTag())); - tag.put("Milk", this.tankHandler.getMilkTank().writeToNBT(lookupProvider, new CompoundTag())); tag.putInt("EnergyStored", this.energyStorage.getEnergyStored()); + + if (!this.tankHandler.getWaterTank().isEmpty()) { + tag.put("Water", this.tankHandler.getWaterTank().writeToNBT(lookupProvider, new CompoundTag())); + } + + if (!this.tankHandler.getMilkTank().isEmpty()) { + tag.put("Milk", this.tankHandler.getMilkTank().writeToNBT(lookupProvider, new CompoundTag())); + } } @Override @@ -454,12 +467,47 @@ protected AbstractContainerMenu createMenu(int id, Inventory inventory) { @Override public void applyComponents(DataComponentMap components) { - super.applyComponents(components); // TODO components + super.applyComponents(components); + + Contents contents = components.get(UselessDataComponents.COFFEE_MACHINE_CONTENTS.get()); + if (contents != null) { + this.tankHandler.getWaterTank().setFluid(contents.water()); + this.tankHandler.getMilkTank().setFluid(contents.milk()); + this.energyStorage.setEnergyStored(contents.energy()); + this.litTime = contents.burnTime(); + this.cookingProgress = contents.cookTime(); + this.cookingTotalTime = contents.cookTimeTotal(); + this.useMilk = contents.useMilk(); + } } @Override public void collectComponents(DataComponentMap.Builder builder) { super.collectComponents(builder); + + builder.set(UselessDataComponents.COFFEE_MACHINE_CONTENTS.get(), + new Contents( + this.tankHandler.getWaterTank().getFluid(), + this.tankHandler.getMilkTank().getFluid(), + this.energyStorage.getEnergyStored(), + this.litTime, + this.cookingProgress, + this.cookingTotalTime, + this.useMilk + )); + } + + @Override + public void removeComponentsFromTag(CompoundTag tag) { + super.removeComponentsFromTag(tag); + + tag.remove("EnergyStored"); + tag.remove("Water"); + tag.remove("Milk"); + tag.remove("BurnTime"); + tag.remove("CookTime"); + tag.remove("CookTimeTotal"); + tag.remove("UseMilk"); } public class CoffeeMachineTank implements IFluidHandler { @@ -532,4 +580,50 @@ public FluidTank getMilkTank() { return milkTank; } } + + public record Contents( + FluidStack water, + FluidStack milk, + int energy, + int burnTime, + int cookTime, + int cookTimeTotal, + boolean useMilk + ) { + public static final Codec CODEC = RecordCodecBuilder.create(instance -> + instance.group( + ExtraCodecs.strictOptionalField(FluidStack.CODEC, "water", FluidStack.EMPTY).forGetter(Contents::water), + ExtraCodecs.strictOptionalField(FluidStack.CODEC, "milk", FluidStack.EMPTY).forGetter(Contents::milk), + ExtraCodecs.strictOptionalField(ExtraCodecs.NON_NEGATIVE_INT, "energy", 0).forGetter(Contents::energy), + ExtraCodecs.strictOptionalField(ExtraCodecs.NON_NEGATIVE_INT, "burn_time", 0).forGetter(Contents::burnTime), + ExtraCodecs.strictOptionalField(ExtraCodecs.NON_NEGATIVE_INT, "cook_time", 0).forGetter(Contents::cookTime), + ExtraCodecs.strictOptionalField(ExtraCodecs.NON_NEGATIVE_INT, "cook_time_total", 0).forGetter(Contents::cookTimeTotal), + ExtraCodecs.strictOptionalField(Codec.BOOL, "use_milk", false).forGetter(Contents::useMilk) + ).apply(instance, Contents::new)); + + public static final StreamCodec STREAM_CODEC = new StreamCodec<>() { + @Override + public Contents decode(RegistryFriendlyByteBuf buf) { + FluidStack water = FluidStack.OPTIONAL_STREAM_CODEC.decode(buf); + FluidStack milk = FluidStack.OPTIONAL_STREAM_CODEC.decode(buf); + int energy = ByteBufCodecs.VAR_INT.decode(buf); + int burnTime = ByteBufCodecs.VAR_INT.decode(buf); + int cookTime = ByteBufCodecs.VAR_INT.decode(buf); + int cookTimeTotal = ByteBufCodecs.VAR_INT.decode(buf); + boolean useMilk = ByteBufCodecs.BOOL.decode(buf); + return new Contents(water, milk, energy, burnTime, cookTime, cookTimeTotal, useMilk); + } + + @Override + public void encode(RegistryFriendlyByteBuf buf, Contents contents) { + FluidStack.OPTIONAL_STREAM_CODEC.encode(buf, contents.water()); + FluidStack.OPTIONAL_STREAM_CODEC.encode(buf, contents.milk()); + ByteBufCodecs.VAR_INT.encode(buf, contents.energy()); + ByteBufCodecs.VAR_INT.encode(buf, contents.burnTime()); + ByteBufCodecs.VAR_INT.encode(buf, contents.cookTime()); + ByteBufCodecs.VAR_INT.encode(buf, contents.cookTimeTotal()); + ByteBufCodecs.BOOL.encode(buf, contents.useMilk()); + } + }; + } } diff --git a/src/main/java/net/themcbrothers/uselessmod/world/level/block/entity/MachineSupplierBlockEntity.java b/src/main/java/net/themcbrothers/uselessmod/world/level/block/entity/MachineSupplierBlockEntity.java index 29b81c37..0af9a105 100644 --- a/src/main/java/net/themcbrothers/uselessmod/world/level/block/entity/MachineSupplierBlockEntity.java +++ b/src/main/java/net/themcbrothers/uselessmod/world/level/block/entity/MachineSupplierBlockEntity.java @@ -2,6 +2,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; +import net.minecraft.core.component.DataComponentMap; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; @@ -14,6 +15,7 @@ import net.neoforged.neoforge.client.model.data.ModelData; import net.neoforged.neoforge.client.model.data.ModelProperty; import net.themcbrothers.uselessmod.init.ModBlockEntityTypes; +import net.themcbrothers.uselessmod.init.UselessDataComponents; import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; @@ -93,4 +95,20 @@ public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt, H public ModelData getModelData() { return ModelData.builder().with(MIMIC_PROPERTY, this.mimic).build(); } + + @Override + public void applyComponents(DataComponentMap components) { + this.setMimic(components.get(UselessDataComponents.MIMIC.get())); + } + + @Override + public void collectComponents(DataComponentMap.Builder builder) { + builder.set(UselessDataComponents.MIMIC.get(), this.getMimic()); + } + + @SuppressWarnings("deprecation") + @Override + public void removeComponentsFromTag(CompoundTag tag) { + tag.remove("Mimic"); + } } diff --git a/src/main/java/net/themcbrothers/uselessmod/world/level/block/entity/PaintBucketBlockEntity.java b/src/main/java/net/themcbrothers/uselessmod/world/level/block/entity/PaintBucketBlockEntity.java index e9ec7e59..d6e8236a 100644 --- a/src/main/java/net/themcbrothers/uselessmod/world/level/block/entity/PaintBucketBlockEntity.java +++ b/src/main/java/net/themcbrothers/uselessmod/world/level/block/entity/PaintBucketBlockEntity.java @@ -56,7 +56,7 @@ public void setColor(float[] colorValues) { } /** - * @param color + * @param color Color */ public void setColor(int color) { this.colorTank.setFluid(new FluidStack(UselessFluids.PAINT.get(), FluidType.BUCKET_VOLUME)); @@ -65,7 +65,10 @@ public void setColor(int color) { } private void saveColorAndItem(CompoundTag tag, HolderLookup.Provider lookupProvider) { - tag.put("Tank", this.colorTank.writeToNBT(lookupProvider, new CompoundTag())); + if (!this.colorTank.isEmpty()) { + tag.put("Tank", this.colorTank.writeToNBT(lookupProvider, new CompoundTag())); + } + tag.put("Slots", this.stackHandler.serializeNBT(lookupProvider)); } @@ -104,4 +107,10 @@ public void collectComponents(DataComponentMap.Builder builder) { public void applyComponents(DataComponentMap components) { this.colorTank.setFluid(FluidStack.of(components.getOrDefault(NeoForgeMod.FLUID_STACK_COMPONENT.get(), FluidStack.EMPTY.immutable()))); } + + @SuppressWarnings("deprecation") + @Override + public void removeComponentsFromTag(CompoundTag tag) { + tag.remove("Tank"); + } }