diff --git a/gradle.properties b/gradle.properties
index dc2c1053..3f4169c3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -5,7 +5,7 @@ org.gradle.caching=true
org.gradle.configuration-cache=true
minecraft_version=26.1.2
minecraft_version_range=[26.1,26.2]
-neo_version=26.1.2.99
+neo_version=26.1.2.109
## Mod Properties
diff --git a/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/BucketInteraction.java b/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/BucketInteraction.java
index 12bed3f0..32a32c12 100644
--- a/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/BucketInteraction.java
+++ b/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/BucketInteraction.java
@@ -1,5 +1,7 @@
package com.devdyna.cakesticklib.api.aspect.logic;
+import com.devdyna.cakesticklib.api.templates.SynchedBlockEntity;
+
import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
@@ -29,6 +31,10 @@ default InteractionResult executeWhenNotBucket(ItemStack stack, BlockState state
default InteractionResult bucketAction(ItemStack item, BlockState blockState, Level level,
BlockPos blockPos, Player player, InteractionHand hand, BlockHitResult blockHitResult) {
+ if (level.getBlockEntity(blockPos) != null)
+ if (level.getBlockEntity(blockPos) instanceof SynchedBlockEntity be)
+ be.update();
+
if (item.isEmpty())
return executeWhenEmpty(item, blockState, level, blockPos, player, hand, blockHitResult);
diff --git a/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/FluidClearableTank.java b/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/FluidClearableTank.java
index 8f8d07fb..49296d81 100644
--- a/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/FluidClearableTank.java
+++ b/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/FluidClearableTank.java
@@ -1,5 +1,7 @@
package com.devdyna.cakesticklib.api.aspect.logic;
+import com.devdyna.cakesticklib.api.templates.SynchedBlockEntity;
+
import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
@@ -17,6 +19,9 @@ default InteractionResult useItemToClear(BlockState blockState, Level level,
// if (!player.isCrouching())
// return InteractionResult.FAIL;
+ if (level.getBlockEntity(blockPos) instanceof SynchedBlockEntity be)
+ be.update();
+
if (level.isClientSide())
return InteractionResult.SUCCESS;
diff --git a/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/FluidTooltipWhenEmpty.java b/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/FluidTooltipWhenEmpty.java
index a72c54e9..914c36d6 100644
--- a/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/FluidTooltipWhenEmpty.java
+++ b/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/FluidTooltipWhenEmpty.java
@@ -1,8 +1,9 @@
package com.devdyna.cakesticklib.api.aspect.logic;
-
import static com.devdyna.cakesticklib.CakeStickLib.MODULE_ID;
+import com.devdyna.cakesticklib.api.templates.SynchedBlockEntity;
+
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.world.InteractionHand;
@@ -17,7 +18,9 @@
/**
* Warning :
- *
This only support atm SINGLE FLUID TANKS!
+ *
+ *
+ * This only support atm SINGLE FLUID TANKS!
*/
public interface FluidTooltipWhenEmpty {
@@ -31,6 +34,9 @@ default boolean showWhen(BlockEntity be) {
default InteractionResult sendFluidTooltip(ItemStack stack, BlockState state, Level level, BlockPos pos,
Player player, InteractionHand hand, BlockHitResult hitResult) {
+ if (level.getBlockEntity(pos) instanceof SynchedBlockEntity be)
+ be.update();
+
if (level.isClientSide())
return InteractionResult.SUCCESS;
@@ -42,7 +48,8 @@ default InteractionResult sendFluidTooltip(ItemStack stack, BlockState state, Le
else
player.sendOverlayMessage(
Component.literal(
- fluid.getFluidType().getDescription().getString() + " : " + tank.getAmountAsInt(0) + "mb"));
+ fluid.getFluidType().getDescription().getString() + " : " + tank.getAmountAsInt(0)
+ + "mb"));
return InteractionResult.SUCCESS;
}
diff --git a/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/NoGuiStorage.java b/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/NoGuiStorage.java
index 7309aaa6..23d42967 100644
--- a/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/NoGuiStorage.java
+++ b/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/NoGuiStorage.java
@@ -2,6 +2,7 @@
import java.util.ArrayList;
+import com.devdyna.cakesticklib.api.templates.SynchedBlockEntity;
import com.devdyna.cakesticklib.api.utils.x;
import net.minecraft.core.BlockPos;
@@ -28,6 +29,9 @@ default InteractionResult itemUseOn(Player player, Level level, BlockPos pos, In
if (be instanceof NoGuiStorage storage) {
+ if (be instanceof SynchedBlockEntity sync)
+ sync.update();
+
// If holding item -> try insert
if (!stack.isEmpty() && !extractOnly() && insertFilter(stack) && requiredToInsert(stack)) {
diff --git a/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/Tickable.java b/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/Tickable.java
new file mode 100644
index 00000000..e3de4233
--- /dev/null
+++ b/src/main/java/com/devdyna/cakesticklib/api/aspect/logic/Tickable.java
@@ -0,0 +1,51 @@
+package com.devdyna.cakesticklib.api.aspect.logic;
+
+// RIP TickingBE 2025-2026
+
+public interface Tickable {
+
+ /**
+ * Server only ticking
+ *
+ *
+ * Level-null SAFE
+ *
+ *
+ * Useful for block events
+ *
+ *
+ * Dont require super!
+ */
+ default void tickServer() {
+ }
+
+ /**
+ * Client only ticking
+ *
+ *
+ * Level-null SAFE
+ *
+ *
+ * Useful for player events
+ *
+ *
+ * Dont require super!
+ */
+ default void tickClient() {
+ }
+
+ /**
+ * Client and Server ticking
+ *
+ *
+ * Level-null SAFE
+ *
+ *
+ * Usefull for particles
+ *
+ *
+ * Dont require super!
+ */
+ default void tickBoth() {
+ }
+}
diff --git a/src/main/java/com/devdyna/cakesticklib/api/client/HudRenderable.java b/src/main/java/com/devdyna/cakesticklib/api/client/hud/HudRenderable.java
similarity index 91%
rename from src/main/java/com/devdyna/cakesticklib/api/client/HudRenderable.java
rename to src/main/java/com/devdyna/cakesticklib/api/client/hud/HudRenderable.java
index 28e09b65..1ceabb56 100644
--- a/src/main/java/com/devdyna/cakesticklib/api/client/HudRenderable.java
+++ b/src/main/java/com/devdyna/cakesticklib/api/client/hud/HudRenderable.java
@@ -1,6 +1,5 @@
-package com.devdyna.cakesticklib.api.client;
+package com.devdyna.cakesticklib.api.client.hud;
-import com.devdyna.cakesticklib.api.client.hud.HudInfoRenderHandler;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphicsExtractor;
diff --git a/src/main/java/com/devdyna/cakesticklib/api/client/utils/FluidRenderHelper.java b/src/main/java/com/devdyna/cakesticklib/api/client/utils/FluidRenderHelper.java
new file mode 100644
index 00000000..433d3af6
--- /dev/null
+++ b/src/main/java/com/devdyna/cakesticklib/api/client/utils/FluidRenderHelper.java
@@ -0,0 +1,208 @@
+package com.devdyna.cakesticklib.api.client.utils;
+
+import java.util.function.Consumer;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.SubmitNodeCollector;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.core.Direction;
+import net.neoforged.neoforge.fluids.FluidStack;
+
+public class FluidRenderHelper {
+
+ private TextureAtlasSprite texture;
+ private int color = 0xFFFFFF;
+ private float x = 0;
+ private float y = 0;
+ private float z = 0;
+ private float amount = 1000;
+ private float height = 1.0f;
+ private float width = 1.0f;
+ private float scale = 1.0f;
+ private Consumer modified = p -> {
+ p.scale(scale, scale, scale);
+ p.translate(x, y, z);
+ };
+
+ public FluidRenderHelper() {
+ }
+
+ public static FluidRenderHelper of() {
+ return new FluidRenderHelper();
+ }
+
+ // /**
+ // * define the texture of the render
+ // *
+ // * REQUIRED
+ // */
+ // public FluidRenderHelper texture(Identifier rl) {
+ // return texture(Minecraft.getInstance().getAtlasManager().get(new
+ // SpriteId(AtlasIds.BLOCKS, rl)));
+ // }
+
+ /**
+ * define the texture of the render
+ *
+ * REQUIRED
+ */
+ public FluidRenderHelper texture(FluidStack fluid) {
+ return texture(Minecraft.getInstance()
+ .getModelManager()
+ .getFluidStateModelSet()
+ .get(fluid.getFluid().defaultFluidState()).stillMaterial().sprite());
+ }
+
+ /**
+ * define the texture of the render
+ *
+ * REQUIRED
+ */
+ public FluidRenderHelper textureAndColor(FluidStack f) {
+ color(f);
+ return texture(f);
+ }
+
+ /**
+ * define the texture of the render
+ *
+ * REQUIRED
+ */
+ public FluidRenderHelper texture(TextureAtlasSprite sp) {
+ texture = sp;
+ return this;
+ }
+
+ /**
+ * define the color of the render
+ *
+ * REQUIRED
+ */
+ public FluidRenderHelper color(int c) {
+ color = c;
+ return this;
+ }
+
+ /**
+ * define the color of the render
+ *
+ * use the default fluid color
+ *
+ * REQUIRED
+ */
+ public FluidRenderHelper color(FluidStack f) {
+
+ var fluidModel = Minecraft.getInstance()
+ .getModelManager()
+ .getFluidStateModelSet()
+ .get(f.getFluid().defaultFluidState());
+
+ return color((fluidModel.fluidTintSource() != null
+ ? fluidModel.fluidTintSource().colorAsStack(
+ com.devdyna.cakesticklib.api.utils.x.fluid(f.getFluid()))
+ : -1) | 0xFF000000);
+ }
+
+ /**
+ * define the fluid amount
+ *
+ * REQUIRED
+ */
+ public FluidRenderHelper amount(float a) {
+ amount = a;
+ return this;
+ }
+
+ /**
+ * define the offset of the entire render
+ *
+ * Default = 0
+ */
+ public FluidRenderHelper offset(float x, float y, float z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ return this;
+ }
+
+ /**
+ * multiply the scale
+ *
+ * Default = x1.0f
+ */
+ @Deprecated
+ public FluidRenderHelper scaleMultiplier(float h, float w) {
+ this.height = h;
+ this.width = w;
+ return this;
+ }
+
+ /**
+ * multiply the scale using the same scale factor
+ *
+ * Default = x1.0f
+ */
+ public FluidRenderHelper scaleMultiplier(float v) {
+ this.scale = v;
+ return this;
+ }
+
+ /**
+ * multiply the scale using the same scale factor
+ *
+ * Default = x1.0f
+ */
+ public FluidRenderHelper modify(Consumer m) {
+ this.modified = m;
+ return this;
+ }
+
+ public void build(PoseStack stack, SubmitNodeCollector node, int packedLight) {
+
+ if (this.texture == null)
+ throw new NullPointerException(
+ "FluidRenderHelper/Texture: You need to set the texture sprite BEFORE build it!");
+
+ stack.pushPose();
+
+ modified.accept(stack);
+
+ float faceSize = 14 / 16f;
+ float fluidHeight = amount * faceSize;
+ float inset = 1 / 16f;
+
+ TextureRenderUtil.renderDirectionalFace(Direction.NORTH, stack, node, texture,
+ inset, inset, inset,
+ width * faceSize, height * fluidHeight,
+ color, packedLight);
+
+ TextureRenderUtil.renderDirectionalFace(Direction.SOUTH, stack, node, texture,
+ inset, inset, inset,
+ width * faceSize, height * fluidHeight,
+ color, packedLight);
+
+ TextureRenderUtil.renderDirectionalFace(Direction.EAST, stack, node, texture,
+ inset, inset, inset,
+ width * faceSize, height * fluidHeight,
+ color, packedLight);
+
+ TextureRenderUtil.renderDirectionalFace(Direction.WEST, stack, node, texture,
+ inset, inset, inset,
+ width * faceSize, height * fluidHeight,
+ color, packedLight);
+
+ TextureRenderUtil.renderDirectionalFace(Direction.UP, stack, node, texture,
+ inset, inset, inset + fluidHeight,
+ width * faceSize, height * faceSize,
+ color, packedLight);
+
+ TextureRenderUtil.renderDirectionalFace(Direction.DOWN, stack, node, texture,
+ inset, inset, 1 - inset,
+ width * faceSize, height * faceSize,
+ color, packedLight);
+
+ stack.popPose();
+ }
+
+}
diff --git a/src/main/java/com/devdyna/cakesticklib/api/client/utils/SimpleItemRender.java b/src/main/java/com/devdyna/cakesticklib/api/client/utils/SimpleItemRender.java
new file mode 100644
index 00000000..be421b9e
--- /dev/null
+++ b/src/main/java/com/devdyna/cakesticklib/api/client/utils/SimpleItemRender.java
@@ -0,0 +1,125 @@
+package com.devdyna.cakesticklib.api.client.utils;
+
+import org.joml.Quaternionf;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.math.Axis;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.SubmitNodeCollector;
+import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
+import net.minecraft.client.renderer.item.ItemStackRenderState;
+import net.minecraft.client.renderer.texture.OverlayTexture;
+import net.minecraft.world.level.Level;
+
+public class SimpleItemRender {
+
+ private boolean whenOn = true;
+
+ private Quaternionf angle = Axis.XP.rotationDegrees(0);
+ private double translateX = 0.5;
+ private double translateY = 0.5;
+ private double translateZ = 0.5;
+ private float scaleX = 1;
+ private float scaleY = 1;
+ private float scaleZ = 1;
+
+ // private Item item = Items.STONE;
+
+ private SimpleItemRender() {
+
+ }
+
+ public static SimpleItemRender of() {
+ return new SimpleItemRender();
+ }
+
+ public SimpleItemRender whenOn(boolean whenOn) {
+ this.whenOn = whenOn;
+ return this;
+ }
+
+ public SimpleItemRender rotate(Quaternionf angle) {
+ this.angle = new Quaternionf(this.angle).mul(angle);
+ return this;
+ }
+
+ public SimpleItemRender rotateXP(float angle) {
+ return rotate(Axis.XP.rotationDegrees(angle));
+ }
+
+ public SimpleItemRender rotateXN(float angle) {
+ return rotate(Axis.XN.rotationDegrees(angle));
+ }
+
+ public SimpleItemRender rotateYP(float angle) {
+ return rotate(Axis.YP.rotationDegrees(angle));
+ }
+
+ public SimpleItemRender rotateYN(float angle) {
+ return rotate(Axis.YN.rotationDegrees(angle));
+ }
+
+ public SimpleItemRender rotateZP(float angle) {
+ return rotate(Axis.ZP.rotationDegrees(angle));
+ }
+
+ public SimpleItemRender rotateZN(float angle) {
+ return rotate(Axis.ZN.rotationDegrees(angle));
+ }
+
+ public SimpleItemRender move(double x, double y, double z) {
+ this.translateX = x;
+ this.translateY = y;
+ this.translateZ = z;
+ return this;
+ }
+
+ public SimpleItemRender scale(float x, float y, float z) {
+ this.scaleX = x;
+ this.scaleY = y;
+ this.scaleZ = z;
+ return this;
+ }
+
+ // public SimpleItemRender item(ItemStack i) {
+ // return item(i.getItem());
+ // }
+
+ // public SimpleItemRender item(Item i) {
+ // this.item = i;
+ // return this;
+ // }
+
+ // public SimpleItemRender item(DeferredHolder- i) {
+ // return item(i.get());
+ // }
+
+ /**
+ * light -> {@link net.minecraft.util.LightCoordsUtil} OR {@code .lightCoords}
+ *
+ * overlay -> {@link net.minecraft.client.renderer.texture.OverlayTexture}
+ * outline -> default {@code 0}
+ */
+ public void build(ItemStackRenderState r, PoseStack p, SubmitNodeCollector c, Level level, int lightCoords,
+ int overlayCoords, int outlineColor) {
+
+ if (whenOn) {
+ p.pushPose();
+ p.translate(translateX, translateY, translateZ);
+ p.mulPose(angle);
+ p.scale(scaleX, scaleY, scaleZ);
+ // r.renderStatic(x.item(item),
+ // ItemDisplayContext.GROUND, light, overlay, p, buffer, level,
+ // level.getRandom().nextInt());
+
+ r.submit(p, c, lightCoords, overlayCoords, outlineColor);
+ p.popPose();
+ }
+ }
+
+ public void build(BlockEntityRenderState state, ItemStackRenderState r, PoseStack p, SubmitNodeCollector c) {
+ build(r, p, c, Minecraft.getInstance().level, state.lightCoords, OverlayTexture.NO_OVERLAY, 0);
+ }
+
+}
diff --git a/src/main/java/com/devdyna/cakesticklib/api/client/utils/TextureRenderUtil.java b/src/main/java/com/devdyna/cakesticklib/api/client/utils/TextureRenderUtil.java
new file mode 100644
index 00000000..bd4cf709
--- /dev/null
+++ b/src/main/java/com/devdyna/cakesticklib/api/client/utils/TextureRenderUtil.java
@@ -0,0 +1,117 @@
+package com.devdyna.cakesticklib.api.client.utils;
+
+import com.mojang.blaze3d.vertex.PoseStack;
+
+import net.minecraft.client.renderer.Sheets;
+import net.minecraft.client.renderer.SubmitNodeCollector;
+import net.minecraft.client.renderer.texture.OverlayTexture;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.core.Direction;
+
+public class TextureRenderUtil {
+
+ /**
+ * @param light based on net.minecraft.client.renderer.LightTexture
+ */
+ public static void renderDirectionalFace(Direction face, PoseStack pose, SubmitNodeCollector node,
+ TextureAtlasSprite texture, float x, float y, float z, float w, float h, int color, int light) {
+ switch (face) {
+ case DOWN -> renderFace(pose, node, texture, color, light,
+ x, x + w,
+ 1.0f - z, 1.0f - z,
+ y, y,
+ y + h, y + h,
+ x, x + w,
+ y, y + h,
+ 0, -1, 0);
+ case UP -> renderFace(pose, node, texture, color, light,
+ x, x + w,
+ z, z,
+ y + h, y + h,
+ y, y,
+ x, x + w, y,
+ y + h,
+ 0, 1, 0);
+ case NORTH -> renderFace(pose, node, texture, color, light,
+ x, x + w,
+ y + h, y,
+ z, z,
+ z, z,
+ x, x + w, y,
+ y + h,
+ 0, 0, -1);
+ case SOUTH -> renderFace(pose, node, texture, color, light,
+ x, x + w,
+ y, y + h,
+ 1.0f - z, 1.0f - z,
+ 1.0f - z, 1.0f - z,
+ x + w, x,
+ y + h, y,
+ 0, 0, 1);
+ case EAST -> renderFace(pose, node, texture, color, light,
+ 1.0f - z, 1.0f - z, y + h, y, x,
+ x + w, x + w, x,
+ x, x + w,
+ y, y + h,
+ 1, 0, 0);
+ case WEST -> renderFace(pose, node, texture, color, light,
+ z, z,
+ y, y + h,
+ x, x + w,
+ x + w, x,
+ x + w, x,
+ y + h, y,
+ -1, 0, 0);
+ }
+ }
+
+ public static void renderFace(PoseStack pose, SubmitNodeCollector node, TextureAtlasSprite texture,
+ int color, int light,
+ float x0, float x1,
+ float y0, float y1,
+ float z0, float z1,
+ float z2, float z3,
+ float u0, float u1,
+ float v0, float v1,
+ float normalX, float normalY, float normalZ) {
+
+ node.submitCustomGeometry(pose, Sheets.translucentBlockItemSheet(),
+ (stack, consumer) -> {
+
+ consumer.addVertex(stack, x0, y0, z0)
+ .setColor(color)
+ .setUv(texture.getU(u0 * texture.contents().width() / 16f),
+ texture.getV(v0 * texture.contents().height()
+ / 16f))
+ .setOverlay(OverlayTexture.NO_OVERLAY)
+ .setLight(light)
+ .setNormal(stack, normalX, normalY, normalZ);
+ consumer.addVertex(stack, x1, y0, z1)
+ .setColor(color)
+ .setUv(texture.getU(u1 * texture.contents().width() / 16f),
+ texture.getV(v0 * texture.contents().height()
+ / 16f))
+ .setOverlay(OverlayTexture.NO_OVERLAY)
+ .setLight(light)
+ .setNormal(stack, normalX, normalY, normalZ);
+ consumer.addVertex(stack, x1, y1, z2)
+ .setColor(color)
+ .setUv(texture.getU(u1 * texture.contents().width() / 16f),
+ texture.getV(v1 * texture.contents().height()
+ / 16f))
+ .setOverlay(OverlayTexture.NO_OVERLAY)
+ .setLight(light)
+ .setNormal(stack, normalX, normalY, normalZ);
+ consumer.addVertex(stack, x0, y1, z3)
+ .setColor(color)
+ .setUv(texture.getU(u0 * texture.contents().width() / 16f),
+ texture.getV(v1 * texture.contents().height()
+ / 16f))
+ .setOverlay(OverlayTexture.NO_OVERLAY)
+ .setLight(light)
+ .setNormal(stack, normalX, normalY, normalZ);
+
+ });
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/devdyna/cakesticklib/api/templates/SynchedBlockEntity.java b/src/main/java/com/devdyna/cakesticklib/api/templates/SynchedBlockEntity.java
new file mode 100644
index 00000000..788cf1f3
--- /dev/null
+++ b/src/main/java/com/devdyna/cakesticklib/api/templates/SynchedBlockEntity.java
@@ -0,0 +1,65 @@
+package com.devdyna.cakesticklib.api.templates;
+
+import java.util.Objects;
+
+import net.minecraft.core.BlockPos;
+import net.minecraft.core.HolderLookup;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.Connection;
+import net.minecraft.network.protocol.Packet;
+import net.minecraft.network.protocol.game.ClientGamePacketListener;
+import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
+import net.minecraft.server.level.ServerChunkCache;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import net.minecraft.world.level.block.entity.BlockEntityType;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.storage.ValueInput;
+
+/**
+ * Utility BE that will sync packets to clients
+ */
+public abstract class SynchedBlockEntity extends BlockEntity {
+
+ public SynchedBlockEntity(BlockEntityType> t, BlockPos p, BlockState s) {
+ super(t, p, s);
+ }
+
+ @Override
+ public Packet getUpdatePacket() {
+ return ClientboundBlockEntityDataPacket.create(this);
+ }
+
+ @Override
+ public CompoundTag getUpdateTag(HolderLookup.Provider p) {
+ return saveWithoutMetadata(p);
+ }
+
+ @Override
+ public void handleUpdateTag(ValueInput i) {
+ loadAdditional(i);
+ }
+
+ @Override
+ public void onLoad() {
+ super.onLoad();
+ this.setChanged();
+ update();
+ }
+
+ public void update() {
+ if (level instanceof ServerLevel server) {
+ var chunk = server.getChunkAt(getBlockPos());
+ if (Objects.requireNonNull(chunk.getLevel()).getChunkSource() instanceof ServerChunkCache cache)
+ cache.chunkMap.getPlayers(chunk.getPos(), false)
+ .forEach(p -> p.connection.send(Objects.requireNonNull(getUpdatePacket())));
+ }
+ }
+
+ @Override
+ public void onDataPacket(Connection c, ValueInput i) {
+ super.onDataPacket(c, i);
+ loadAdditional(i);
+ }
+
+}
diff --git a/src/main/java/com/devdyna/cakesticklib/api/templates/TickingBE.java b/src/main/java/com/devdyna/cakesticklib/api/templates/TickingBE.java
index 9e0f9bd8..d8c9a184 100644
--- a/src/main/java/com/devdyna/cakesticklib/api/templates/TickingBE.java
+++ b/src/main/java/com/devdyna/cakesticklib/api/templates/TickingBE.java
@@ -1,59 +1,17 @@
package com.devdyna.cakesticklib.api.templates;
+import com.devdyna.cakesticklib.api.aspect.logic.Tickable;
+
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
-
-public abstract class TickingBE extends BlockEntity {
+//replaced by Tickable BE interface
+@Deprecated
+public abstract class TickingBE extends BlockEntity implements Tickable {
public TickingBE(BlockEntityType> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
- /**
- * Server only ticking
- *
- *
- * Level-null SAFE
- *
- *
- * Useful for block events
- *
- *
- * Dont require super!
- */
- public void tickServer() {
- }
-
- /**
- * Client only ticking
- *
- *
- * Level-null SAFE
- *
- *
- * Useful for player events
- *
- *
- * Dont require super!
- */
- public void tickClient() {
- }
-
- /**
- * Client and Server ticking
- *
- *
- * Level-null SAFE
- *
- *
- * Usefull for particles
- *
- *
- * Dont require super!
- */
- public void tickBoth() {
- }
-
}
diff --git a/src/main/java/com/devdyna/cakesticklib/api/templates/TickingBlock.java b/src/main/java/com/devdyna/cakesticklib/api/templates/TickingBlock.java
index 07026a6c..75c483c1 100644
--- a/src/main/java/com/devdyna/cakesticklib/api/templates/TickingBlock.java
+++ b/src/main/java/com/devdyna/cakesticklib/api/templates/TickingBlock.java
@@ -2,6 +2,8 @@
import javax.annotation.Nullable;
+import com.devdyna.cakesticklib.api.aspect.logic.Tickable;
+
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock;
@@ -21,7 +23,7 @@ public TickingBlock(Properties p) {
public BlockEntityTicker getTicker(Level l, BlockState s,
BlockEntityType ty) {
return (lvl, pos, b, t) -> {
- if (t instanceof TickingBE be) {
+ if (t instanceof Tickable be) {
if (l == null)
return;
diff --git a/src/main/java/com/devdyna/cakesticklib/api/utils/ClazzUtil.java b/src/main/java/com/devdyna/cakesticklib/api/utils/ClazzUtil.java
index 98b22ecc..da1c3cd8 100644
--- a/src/main/java/com/devdyna/cakesticklib/api/utils/ClazzUtil.java
+++ b/src/main/java/com/devdyna/cakesticklib/api/utils/ClazzUtil.java
@@ -9,7 +9,7 @@
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.neoforged.neoforge.registries.DeferredHolder;
-@Deprecated
+// @Deprecated //TODO maybe i need to reclassificate this deprecation
public class ClazzUtil {
public static String[] getAllStrings(Class> clazz) {
diff --git a/src/main/java/com/devdyna/cakesticklib/setup/Client.java b/src/main/java/com/devdyna/cakesticklib/setup/Client.java
index 46a5734a..540243dc 100644
--- a/src/main/java/com/devdyna/cakesticklib/setup/Client.java
+++ b/src/main/java/com/devdyna/cakesticklib/setup/Client.java
@@ -5,11 +5,11 @@
import java.util.List;
import com.devdyna.cakesticklib.api.client.ItemRenderDecorator;
+import com.devdyna.cakesticklib.api.client.hud.HudRenderable;
import com.devdyna.cakesticklib.api.datagen.selectors.EjectTypeProperty;
import com.devdyna.cakesticklib.api.upgrades.eject.EjectModifierScreen;
import com.devdyna.cakesticklib.api.FluidRegister;
import com.devdyna.cakesticklib.api.FluidRenderUtils;
-import com.devdyna.cakesticklib.api.client.HudRenderable;
import com.devdyna.cakesticklib.api.utils.ClazzUtil;
import com.devdyna.cakesticklib.api.utils.ModAddonUtil;
import com.devdyna.cakesticklib.api.utils.x;