From 9f6aa3b823040549a9a8ad329cfb47b8ca2ecd0d Mon Sep 17 00:00:00 2001 From: PainterFlow11 <163044531+PainterFlow@users.noreply.github.com> Date: Wed, 1 Jul 2026 16:11:41 +0200 Subject: [PATCH 1/9] e --- build.gradle | 2 + .../redstone/VSQEntityRedstonePower.java | 40 ++++++++ .../VSQEntityRedstonePowerAccess.java | 5 + .../entity/EntityRedstonePowerMixin.java | 96 +++++++++++++++++++ .../world/redstone/SignalGetterMixin.java | 30 ++++++ .../resources/vanilla-squared.mixins.json | 4 +- 6 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java create mode 100644 src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePowerAccess.java create mode 100644 src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java create mode 100644 src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java diff --git a/build.gradle b/build.gradle index 7db16ee5..66de793f 100644 --- a/build.gradle +++ b/build.gradle @@ -33,6 +33,8 @@ loom { client { programArgs("--username", "PainterFlow11") // usernameVSQ programArgs("--model", "slim") // modelVSQ + vmArgs("-DMC_DEBUG_ENABLED=true") + vmArgs("-DMC_DEBUG_NEIGHBORSUPDATE=true") } } } diff --git a/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java new file mode 100644 index 00000000..a18c31e1 --- /dev/null +++ b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java @@ -0,0 +1,40 @@ +package blob.vanillasquared.main.world.redstone; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.phys.AABB; + +public final class VSQEntityRedstonePower { + public static final String POWER_REDSTONE_KEY = "vsq:powerRedstone"; + + private VSQEntityRedstonePower() { + } + + public static int getPower(Entity entity) { + if (entity instanceof VSQEntityRedstonePowerAccess access) { + return access.vsq$getRedstonePower(); + } + return 0; + } + + public static int getSignal(ServerLevel level, BlockPos pos) { + AABB blockBounds = new AABB(pos); + int signal = 0; + for (Entity entity : level.getEntities((Entity) null, blockBounds, entity -> entity.getBoundingBox().intersects(blockBounds))) { + signal = Math.max(signal, getPower(entity)); + if (signal >= 15) { + return 15; + } + } + return signal; + } + + public static void updateNeighbors(ServerLevel level, AABB sourceBounds) { + AABB updateBounds = sourceBounds.inflate(1.0D); + for (BlockPos pos : BlockPos.betweenClosed(updateBounds)) { + level.updateNeighborsAt(pos, Blocks.AIR, null); + } + } +} diff --git a/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePowerAccess.java b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePowerAccess.java new file mode 100644 index 00000000..745006ef --- /dev/null +++ b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePowerAccess.java @@ -0,0 +1,5 @@ +package blob.vanillasquared.main.world.redstone; + +public interface VSQEntityRedstonePowerAccess { + int vsq$getRedstonePower(); +} diff --git a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java new file mode 100644 index 00000000..d3bda9d0 --- /dev/null +++ b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java @@ -0,0 +1,96 @@ +package blob.vanillasquared.mixin.world.entity; + +import blob.vanillasquared.main.world.redstone.VSQEntityRedstonePower; +import blob.vanillasquared.main.world.redstone.VSQEntityRedstonePowerAccess; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; +import net.minecraft.world.phys.AABB; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Entity.class) +public abstract class EntityRedstonePowerMixin implements VSQEntityRedstonePowerAccess { + @Unique + private AABB vsq$previousRedstoneSourceBounds; + @Unique + private int vsq$previousRedstonePower; + @Unique + private int vsq$redstonePower; + + @Inject(method = "", at = @At("RETURN")) + private void vsq$initEntityRedstonePower(EntityType entityType, Level level, CallbackInfo ci) { + this.vsq$previousRedstoneSourceBounds = null; + this.vsq$previousRedstonePower = 0; + this.vsq$redstonePower = 0; + } + + @Inject(method = "load", at = @At("TAIL")) + private void vsq$loadEntityRedstonePower(ValueInput input, CallbackInfo ci) { + this.vsq$redstonePower = Mth.clamp(input.getIntOr(VSQEntityRedstonePower.POWER_REDSTONE_KEY, 0), 0, 15); + } + + @Inject(method = "saveWithoutId", at = @At("TAIL")) + private void vsq$saveEntityRedstonePower(ValueOutput output, CallbackInfo ci) { + if (this.vsq$redstonePower > 0) { + output.putInt(VSQEntityRedstonePower.POWER_REDSTONE_KEY, this.vsq$redstonePower); + } + } + + @Override + public int vsq$getRedstonePower() { + return this.vsq$redstonePower; + } + + @Inject(method = "tick", at = @At("TAIL")) + private void vsq$tickEntityRedstonePower(CallbackInfo ci) { + Entity entity = (Entity) (Object) this; + if (!(entity.level() instanceof ServerLevel level)) { + return; + } + + AABB currentBounds = entity.getBoundingBox(); + int currentPower = VSQEntityRedstonePower.getPower(entity); + boolean boundsChanged = this.vsq$previousRedstoneSourceBounds != null + && !this.vsq$previousRedstoneSourceBounds.equals(currentBounds); + + if (this.vsq$previousRedstonePower > 0 && this.vsq$previousRedstoneSourceBounds != null + && (currentPower <= 0 || boundsChanged)) { + VSQEntityRedstonePower.updateNeighbors(level, this.vsq$previousRedstoneSourceBounds); + } + + if (currentPower > 0) { + if (entity.tickCount % 2 == 0) { + VSQEntityRedstonePower.updateNeighbors(level, currentBounds); + } + this.vsq$previousRedstoneSourceBounds = currentBounds; + } else { + this.vsq$previousRedstoneSourceBounds = null; + } + this.vsq$previousRedstonePower = currentPower; + } + + @Inject(method = "remove", at = @At("HEAD")) + private void vsq$removeEntityRedstonePower(Entity.RemovalReason reason, CallbackInfo ci) { + Entity entity = (Entity) (Object) this; + if (!(entity.level() instanceof ServerLevel level)) { + return; + } + + if (this.vsq$previousRedstonePower > 0 && this.vsq$previousRedstoneSourceBounds != null) { + VSQEntityRedstonePower.updateNeighbors(level, this.vsq$previousRedstoneSourceBounds); + } else if (VSQEntityRedstonePower.getPower(entity) > 0) { + VSQEntityRedstonePower.updateNeighbors(level, entity.getBoundingBox()); + } + + this.vsq$previousRedstoneSourceBounds = null; + this.vsq$previousRedstonePower = 0; + } +} diff --git a/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java b/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java new file mode 100644 index 00000000..9fa454c6 --- /dev/null +++ b/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java @@ -0,0 +1,30 @@ +package blob.vanillasquared.mixin.world.redstone; + +import blob.vanillasquared.main.world.redstone.VSQEntityRedstonePower; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.SignalGetter; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(SignalGetter.class) +public interface SignalGetterMixin { + @Inject(method = "getSignal", at = @At("RETURN"), cancellable = true) + private void vsq$getEntityRedstoneSignal(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { + SignalGetter signalGetter = (SignalGetter) this; + if (signalGetter instanceof ServerLevel level) { + cir.setReturnValue(Math.max(cir.getReturnValue(), VSQEntityRedstonePower.getSignal(level, pos))); + } + } + + @Inject(method = "getDirectSignal", at = @At("RETURN"), cancellable = true) + private void vsq$getDirectEntityRedstoneSignal(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { + SignalGetter signalGetter = (SignalGetter) this; + if (signalGetter instanceof ServerLevel level) { + cir.setReturnValue(Math.max(cir.getReturnValue(), VSQEntityRedstonePower.getSignal(level, pos))); + } + } +} diff --git a/src/main/resources/vanilla-squared.mixins.json b/src/main/resources/vanilla-squared.mixins.json index 578ab84f..d5af68d0 100644 --- a/src/main/resources/vanilla-squared.mixins.json +++ b/src/main/resources/vanilla-squared.mixins.json @@ -17,6 +17,7 @@ "world.block.SulfurSpikeBlockMixin", "world.dmgsources.CombatRulesMixin", "world.entity.EntityFlagsPredicateMixin", + "world.entity.EntityRedstonePowerMixin", "world.entity.CubeMobMoveControlAccessor", "world.entity.LivingEntityAccessor", "world.entity.LivingEntityAttributesMixin", @@ -55,7 +56,8 @@ "world.loot.LootItemEntityPropertyConditionMixin", "world.entity.entities.FishingRodHookMixin", "world.entity.entities.PlayerMixin", - "world.entity.entities.SulfurCubeMixin" + "world.entity.entities.SulfurCubeMixin", + "world.redstone.SignalGetterMixin" ], "injectors": { "defaultRequire": 1 From 18d2512b7efa639038006e8a9f5b52baf791760e Mon Sep 17 00:00:00 2001 From: PainterFlow11 <163044531+PainterFlow@users.noreply.github.com> Date: Wed, 1 Jul 2026 16:26:04 +0200 Subject: [PATCH 2/9] e --- .../main/world/redstone/VSQEntityRedstonePower.java | 3 ++- .../mixin/world/entity/EntityRedstonePowerMixin.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java index a18c31e1..8f8b346d 100644 --- a/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java +++ b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java @@ -22,7 +22,8 @@ public static int getPower(Entity entity) { public static int getSignal(ServerLevel level, BlockPos pos) { AABB blockBounds = new AABB(pos); int signal = 0; - for (Entity entity : level.getEntities((Entity) null, blockBounds, entity -> entity.getBoundingBox().intersects(blockBounds))) { + for (Entity entity : level.getEntities((Entity) null, blockBounds, + entity -> !entity.isRemoved() && entity.getBoundingBox().intersects(blockBounds))) { signal = Math.max(signal, getPower(entity)); if (signal >= 15) { return 15; diff --git a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java index d3bda9d0..8dbee43b 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java @@ -77,7 +77,7 @@ public abstract class EntityRedstonePowerMixin implements VSQEntityRedstonePower this.vsq$previousRedstonePower = currentPower; } - @Inject(method = "remove", at = @At("HEAD")) + @Inject(method = "onRemoval", at = @At("TAIL")) private void vsq$removeEntityRedstonePower(Entity.RemovalReason reason, CallbackInfo ci) { Entity entity = (Entity) (Object) this; if (!(entity.level() instanceof ServerLevel level)) { From 5434fe6f3db14db5cbee0e06cf47b1b373510cc5 Mon Sep 17 00:00:00 2001 From: PainterFlow11 <163044531+PainterFlow@users.noreply.github.com> Date: Wed, 1 Jul 2026 16:53:46 +0200 Subject: [PATCH 3/9] ee --- .../redstone/VSQEntityRedstonePowerAccess.java | 2 ++ .../world/entity/EntityRedstonePowerMixin.java | 5 +++++ .../world/entity/entities/SulfurCubeMixin.java | 15 +++++++++++++++ .../item/sulfur_cube_archetype/fast_flat.json | 5 +++++ .../tags/item/sulfur_cube_swallowable.json | 5 +++++ 5 files changed, 32 insertions(+) create mode 100644 src/main/resources/data/minecraft/tags/item/sulfur_cube_archetype/fast_flat.json create mode 100644 src/main/resources/data/minecraft/tags/item/sulfur_cube_swallowable.json diff --git a/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePowerAccess.java b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePowerAccess.java index 745006ef..344e2ed9 100644 --- a/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePowerAccess.java +++ b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePowerAccess.java @@ -2,4 +2,6 @@ public interface VSQEntityRedstonePowerAccess { int vsq$getRedstonePower(); + + void vsq$setRedstonePower(int power); } diff --git a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java index 8dbee43b..b3a45022 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java @@ -49,6 +49,11 @@ public abstract class EntityRedstonePowerMixin implements VSQEntityRedstonePower return this.vsq$redstonePower; } + @Override + public void vsq$setRedstonePower(int power) { + this.vsq$redstonePower = Mth.clamp(power, 0, 15); + } + @Inject(method = "tick", at = @At("TAIL")) private void vsq$tickEntityRedstonePower(CallbackInfo ci) { Entity entity = (Entity) (Object) this; diff --git a/src/main/java/blob/vanillasquared/mixin/world/entity/entities/SulfurCubeMixin.java b/src/main/java/blob/vanillasquared/mixin/world/entity/entities/SulfurCubeMixin.java index 6389aeb2..d9246b79 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/entity/entities/SulfurCubeMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/entity/entities/SulfurCubeMixin.java @@ -2,6 +2,7 @@ import blob.vanillasquared.main.world.entity.SulfurCubeBreedingState; import blob.vanillasquared.main.world.item.VSQItems; +import blob.vanillasquared.main.world.redstone.VSQEntityRedstonePowerAccess; import blob.vanillasquared.mixin.world.entity.CubeMobMoveControlAccessor; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.server.level.ServerLevel; @@ -11,12 +12,14 @@ import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.AgeableMob; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.ExperienceOrb; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.goal.Goal; import net.minecraft.world.entity.ai.goal.TemptGoal; import net.minecraft.world.entity.monster.cubemob.SulfurCube; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Items; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.gamerules.GameRules; @@ -89,6 +92,11 @@ protected SulfurCubeMixin(EntityType type, Level level) { } } + @Inject(method = "customServerAiStep", at = @At("TAIL")) + private void vsq$updateRedstonePower(ServerLevel level, CallbackInfo ci) { + this.vsq$setRedstonePowerForContent(); + } + @Inject(method = "customServerAiStep", at = @At("TAIL")) private void vsq$tickBreeding(ServerLevel level, CallbackInfo ci) { if (this.getAge() != 0) { @@ -127,6 +135,13 @@ protected SulfurCubeMixin(EntityType type, Level level) { @Inject(method = "readAdditionalSaveData", at = @At("TAIL")) private void vsq$loadBreedingState(ValueInput input, CallbackInfo ci) { this.vsq$inLove = input.getIntOr("VSQInLove", 0); + this.vsq$setRedstonePowerForContent(); + } + + @Unique + private void vsq$setRedstonePowerForContent() { + ItemStack bodyItem = this.getItemBySlot(EquipmentSlot.BODY); + ((VSQEntityRedstonePowerAccess) this).vsq$setRedstonePower(bodyItem.is(Items.REDSTONE_BLOCK) ? 15 : 0); } @Override diff --git a/src/main/resources/data/minecraft/tags/item/sulfur_cube_archetype/fast_flat.json b/src/main/resources/data/minecraft/tags/item/sulfur_cube_archetype/fast_flat.json new file mode 100644 index 00000000..b62d1a48 --- /dev/null +++ b/src/main/resources/data/minecraft/tags/item/sulfur_cube_archetype/fast_flat.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:redstone_block" + ] +} diff --git a/src/main/resources/data/minecraft/tags/item/sulfur_cube_swallowable.json b/src/main/resources/data/minecraft/tags/item/sulfur_cube_swallowable.json new file mode 100644 index 00000000..b62d1a48 --- /dev/null +++ b/src/main/resources/data/minecraft/tags/item/sulfur_cube_swallowable.json @@ -0,0 +1,5 @@ +{ + "values": [ + "minecraft:redstone_block" + ] +} From 78d44da5c60c60c4d1ea0a38bb5ce8966826b78d Mon Sep 17 00:00:00 2001 From: PainterFlow11 <163044531+PainterFlow@users.noreply.github.com> Date: Wed, 1 Jul 2026 16:59:39 +0200 Subject: [PATCH 4/9] eee --- build.gradle | 2 -- 1 file changed, 2 deletions(-) diff --git a/build.gradle b/build.gradle index 66de793f..7db16ee5 100644 --- a/build.gradle +++ b/build.gradle @@ -33,8 +33,6 @@ loom { client { programArgs("--username", "PainterFlow11") // usernameVSQ programArgs("--model", "slim") // modelVSQ - vmArgs("-DMC_DEBUG_ENABLED=true") - vmArgs("-DMC_DEBUG_NEIGHBORSUPDATE=true") } } } From 89d268c646463c58a97c296d53274e327e667994 Mon Sep 17 00:00:00 2001 From: PainterFlow11 <163044531+PainterFlow@users.noreply.github.com> Date: Thu, 2 Jul 2026 14:17:14 +0200 Subject: [PATCH 5/9] fixed all of codesmiths crying issues --- .../redstone/VSQEntityRedstonePower.java | 23 +++++++- .../VSQEntityRedstonePowerLevelAccess.java | 9 +++ .../mixin/world/ServerLevelMixin.java | 24 +++++++- .../entity/EntityRedstonePowerMixin.java | 59 +++++++++++++------ .../entity/entities/SulfurCubeMixin.java | 5 +- src/main/resources/assets/vsq/lang/en_us.json | 2 + 6 files changed, 98 insertions(+), 24 deletions(-) create mode 100644 src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePowerLevelAccess.java diff --git a/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java index 8f8b346d..e2a08e93 100644 --- a/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java +++ b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java @@ -19,11 +19,30 @@ public static int getPower(Entity entity) { return 0; } + public static boolean hasPoweredEntities(ServerLevel level) { + return level instanceof VSQEntityRedstonePowerLevelAccess access && access.vsq$getPoweredEntityCount() > 0; + } + + public static void incrementPoweredEntityCount(ServerLevel level) { + if (level instanceof VSQEntityRedstonePowerLevelAccess access) { + access.vsq$incrementPoweredEntityCount(); + } + } + + public static void decrementPoweredEntityCount(ServerLevel level) { + if (level instanceof VSQEntityRedstonePowerLevelAccess access) { + access.vsq$decrementPoweredEntityCount(); + } + } + public static int getSignal(ServerLevel level, BlockPos pos) { + if (!hasPoweredEntities(level)) { + return 0; + } + AABB blockBounds = new AABB(pos); int signal = 0; - for (Entity entity : level.getEntities((Entity) null, blockBounds, - entity -> !entity.isRemoved() && entity.getBoundingBox().intersects(blockBounds))) { + for (Entity entity : level.getEntities((Entity) null, blockBounds, entity -> !entity.isRemoved())) { signal = Math.max(signal, getPower(entity)); if (signal >= 15) { return 15; diff --git a/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePowerLevelAccess.java b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePowerLevelAccess.java new file mode 100644 index 00000000..07c1c156 --- /dev/null +++ b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePowerLevelAccess.java @@ -0,0 +1,9 @@ +package blob.vanillasquared.main.world.redstone; + +public interface VSQEntityRedstonePowerLevelAccess { + int vsq$getPoweredEntityCount(); + + void vsq$incrementPoweredEntityCount(); + + void vsq$decrementPoweredEntityCount(); +} diff --git a/src/main/java/blob/vanillasquared/mixin/world/ServerLevelMixin.java b/src/main/java/blob/vanillasquared/mixin/world/ServerLevelMixin.java index 4a7be507..62543591 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/ServerLevelMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/ServerLevelMixin.java @@ -3,8 +3,10 @@ import blob.vanillasquared.main.world.effect.ChannelingState; import blob.vanillasquared.main.world.effect.LungingState; import blob.vanillasquared.main.world.effect.SwirlingState; +import blob.vanillasquared.main.world.redstone.VSQEntityRedstonePowerLevelAccess; import net.minecraft.server.level.ServerLevel; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -12,11 +14,31 @@ import java.util.function.BooleanSupplier; @Mixin(ServerLevel.class) -public abstract class ServerLevelMixin { +public abstract class ServerLevelMixin implements VSQEntityRedstonePowerLevelAccess { + @Unique + private int vsq$poweredEntityCount; + @Inject(method = "tick", at = @At("TAIL")) private void vsq$tickChanneling(BooleanSupplier haveTime, CallbackInfo ci) { ChannelingState.tick((ServerLevel) (Object) this); LungingState.tick((ServerLevel) (Object) this); SwirlingState.tick((ServerLevel) (Object) this); } + + @Override + public int vsq$getPoweredEntityCount() { + return this.vsq$poweredEntityCount; + } + + @Override + public void vsq$incrementPoweredEntityCount() { + this.vsq$poweredEntityCount++; + } + + @Override + public void vsq$decrementPoweredEntityCount() { + if (this.vsq$poweredEntityCount > 0) { + this.vsq$poweredEntityCount--; + } + } } diff --git a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java index b3a45022..0cb4416b 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java @@ -5,8 +5,6 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.Level; import net.minecraft.world.level.storage.ValueInput; import net.minecraft.world.level.storage.ValueOutput; import net.minecraft.world.phys.AABB; @@ -24,17 +22,15 @@ public abstract class EntityRedstonePowerMixin implements VSQEntityRedstonePower private int vsq$previousRedstonePower; @Unique private int vsq$redstonePower; - - @Inject(method = "", at = @At("RETURN")) - private void vsq$initEntityRedstonePower(EntityType entityType, Level level, CallbackInfo ci) { - this.vsq$previousRedstoneSourceBounds = null; - this.vsq$previousRedstonePower = 0; - this.vsq$redstonePower = 0; - } + @Unique + private boolean vsq$redstonePowerCounted; + @Unique + private ServerLevel vsq$redstonePowerCountedLevel; @Inject(method = "load", at = @At("TAIL")) private void vsq$loadEntityRedstonePower(ValueInput input, CallbackInfo ci) { this.vsq$redstonePower = Mth.clamp(input.getIntOr(VSQEntityRedstonePower.POWER_REDSTONE_KEY, 0), 0, 15); + this.vsq$reconcileRedstonePowerCount(); } @Inject(method = "saveWithoutId", at = @At("TAIL")) @@ -52,11 +48,13 @@ public abstract class EntityRedstonePowerMixin implements VSQEntityRedstonePower @Override public void vsq$setRedstonePower(int power) { this.vsq$redstonePower = Mth.clamp(power, 0, 15); + this.vsq$reconcileRedstonePowerCount(); } @Inject(method = "tick", at = @At("TAIL")) private void vsq$tickEntityRedstonePower(CallbackInfo ci) { Entity entity = (Entity) (Object) this; + this.vsq$reconcileRedstonePowerCount(); if (!(entity.level() instanceof ServerLevel level)) { return; } @@ -85,17 +83,44 @@ public abstract class EntityRedstonePowerMixin implements VSQEntityRedstonePower @Inject(method = "onRemoval", at = @At("TAIL")) private void vsq$removeEntityRedstonePower(Entity.RemovalReason reason, CallbackInfo ci) { Entity entity = (Entity) (Object) this; - if (!(entity.level() instanceof ServerLevel level)) { - return; - } - - if (this.vsq$previousRedstonePower > 0 && this.vsq$previousRedstoneSourceBounds != null) { - VSQEntityRedstonePower.updateNeighbors(level, this.vsq$previousRedstoneSourceBounds); - } else if (VSQEntityRedstonePower.getPower(entity) > 0) { - VSQEntityRedstonePower.updateNeighbors(level, entity.getBoundingBox()); + if (entity.level() instanceof ServerLevel level) { + if (this.vsq$previousRedstonePower > 0 && this.vsq$previousRedstoneSourceBounds != null) { + VSQEntityRedstonePower.updateNeighbors(level, this.vsq$previousRedstoneSourceBounds); + } else if (VSQEntityRedstonePower.getPower(entity) > 0) { + VSQEntityRedstonePower.updateNeighbors(level, entity.getBoundingBox()); + } } + this.vsq$unregisterRedstonePowerCount(); this.vsq$previousRedstoneSourceBounds = null; this.vsq$previousRedstonePower = 0; } + + @Unique + private void vsq$reconcileRedstonePowerCount() { + Entity entity = (Entity) (Object) this; + if (this.vsq$redstonePower > 0 && !entity.isRemoved() && entity.level() instanceof ServerLevel level) { + if (!this.vsq$redstonePowerCounted) { + VSQEntityRedstonePower.incrementPoweredEntityCount(level); + this.vsq$redstonePowerCounted = true; + this.vsq$redstonePowerCountedLevel = level; + } else if (this.vsq$redstonePowerCountedLevel != level) { + this.vsq$unregisterRedstonePowerCount(); + VSQEntityRedstonePower.incrementPoweredEntityCount(level); + this.vsq$redstonePowerCounted = true; + this.vsq$redstonePowerCountedLevel = level; + } + } else { + this.vsq$unregisterRedstonePowerCount(); + } + } + + @Unique + private void vsq$unregisterRedstonePowerCount() { + if (this.vsq$redstonePowerCounted && this.vsq$redstonePowerCountedLevel != null) { + VSQEntityRedstonePower.decrementPoweredEntityCount(this.vsq$redstonePowerCountedLevel); + } + this.vsq$redstonePowerCounted = false; + this.vsq$redstonePowerCountedLevel = null; + } } diff --git a/src/main/java/blob/vanillasquared/mixin/world/entity/entities/SulfurCubeMixin.java b/src/main/java/blob/vanillasquared/mixin/world/entity/entities/SulfurCubeMixin.java index d9246b79..28fd12eb 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/entity/entities/SulfurCubeMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/entity/entities/SulfurCubeMixin.java @@ -93,12 +93,9 @@ protected SulfurCubeMixin(EntityType type, Level level) { } @Inject(method = "customServerAiStep", at = @At("TAIL")) - private void vsq$updateRedstonePower(ServerLevel level, CallbackInfo ci) { + private void vsq$customServerAiStep(ServerLevel level, CallbackInfo ci) { this.vsq$setRedstonePowerForContent(); - } - @Inject(method = "customServerAiStep", at = @At("TAIL")) - private void vsq$tickBreeding(ServerLevel level, CallbackInfo ci) { if (this.getAge() != 0) { this.vsq$resetLove(); return; diff --git a/src/main/resources/assets/vsq/lang/en_us.json b/src/main/resources/assets/vsq/lang/en_us.json index 2521281d..c38694ad 100644 --- a/src/main/resources/assets/vsq/lang/en_us.json +++ b/src/main/resources/assets/vsq/lang/en_us.json @@ -144,6 +144,8 @@ "death.attack.swirled.item": "%s was swirled by %s using %s", "tag.entity_type.minecraft.aquatic": "Aquatic Mobs", "tag.item.minecraft.sulfur_cube_food": "Sulfur Cube Food", + "tag.item.minecraft.sulfur_cube_swallowable": "Sulfur Cube Swallowable", + "tag.item.minecraft.sulfur_cube_archetype.fast_flat": "Sulfur Cube Fast Flat Archetype", "tag.item.vsq.enchantable.melee_weapon": "Melee Weapons", "tag.item.vsq.enchantable.all_weapons": "All Weapons", "tag.item.vsq.enchantable.sharpness": "Sharpness Items", From 5342c18aac7dfc561d1b6db8f8e113ba3b61d908 Mon Sep 17 00:00:00 2001 From: PainterFlow11 <163044531+PainterFlow@users.noreply.github.com> Date: Thu, 2 Jul 2026 15:55:06 +0200 Subject: [PATCH 6/9] e --- .../mixin/world/entity/EntityRedstonePowerMixin.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java index 0cb4416b..81ec3dea 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java @@ -29,7 +29,8 @@ public abstract class EntityRedstonePowerMixin implements VSQEntityRedstonePower @Inject(method = "load", at = @At("TAIL")) private void vsq$loadEntityRedstonePower(ValueInput input, CallbackInfo ci) { - this.vsq$redstonePower = Mth.clamp(input.getIntOr(VSQEntityRedstonePower.POWER_REDSTONE_KEY, 0), 0, 15); + input.getInt(VSQEntityRedstonePower.POWER_REDSTONE_KEY) + .ifPresent(power -> this.vsq$redstonePower = Mth.clamp(power, 0, 15)); this.vsq$reconcileRedstonePowerCount(); } @@ -63,6 +64,7 @@ public abstract class EntityRedstonePowerMixin implements VSQEntityRedstonePower int currentPower = VSQEntityRedstonePower.getPower(entity); boolean boundsChanged = this.vsq$previousRedstoneSourceBounds != null && !this.vsq$previousRedstoneSourceBounds.equals(currentBounds); + boolean powerChanged = this.vsq$previousRedstonePower != currentPower; if (this.vsq$previousRedstonePower > 0 && this.vsq$previousRedstoneSourceBounds != null && (currentPower <= 0 || boundsChanged)) { @@ -70,7 +72,7 @@ public abstract class EntityRedstonePowerMixin implements VSQEntityRedstonePower } if (currentPower > 0) { - if (entity.tickCount % 2 == 0) { + if (this.vsq$previousRedstoneSourceBounds == null || boundsChanged || powerChanged) { VSQEntityRedstonePower.updateNeighbors(level, currentBounds); } this.vsq$previousRedstoneSourceBounds = currentBounds; From 80bc52a911fe06c817e5f6f09a0359b90e70bc7f Mon Sep 17 00:00:00 2001 From: pxlarified Date: Sat, 4 Jul 2026 03:35:43 +0200 Subject: [PATCH 7/9] Fix redstone sulfur cube review issues --- .../world/redstone/VSQEntityRedstonePower.java | 17 ++++++++++++++++- .../mixin/world/ServerLevelMixin.java | 11 +++++------ .../world/entity/EntityRedstonePowerMixin.java | 7 +++++++ .../world/entity/entities/SulfurCubeMixin.java | 9 ++++++++- .../mixin/world/redstone/SignalGetterMixin.java | 9 +-------- 5 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java index e2a08e93..2636fa35 100644 --- a/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java +++ b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java @@ -2,6 +2,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.phys.AABB; @@ -54,7 +55,21 @@ public static int getSignal(ServerLevel level, BlockPos pos) { public static void updateNeighbors(ServerLevel level, AABB sourceBounds) { AABB updateBounds = sourceBounds.inflate(1.0D); for (BlockPos pos : BlockPos.betweenClosed(updateBounds)) { - level.updateNeighborsAt(pos, Blocks.AIR, null); + if (vsq$isOnShell(pos, updateBounds)) { + level.updateNeighborsAt(pos, Blocks.REDSTONE_WIRE, null); + } } } + + private static boolean vsq$isOnShell(BlockPos pos, AABB bounds) { + int minX = Mth.floor(bounds.minX); + int minY = Mth.floor(bounds.minY); + int minZ = Mth.floor(bounds.minZ); + int maxX = Mth.floor(bounds.maxX); + int maxY = Mth.floor(bounds.maxY); + int maxZ = Mth.floor(bounds.maxZ); + return pos.getX() == minX || pos.getX() == maxX + || pos.getY() == minY || pos.getY() == maxY + || pos.getZ() == minZ || pos.getZ() == maxZ; + } } diff --git a/src/main/java/blob/vanillasquared/mixin/world/ServerLevelMixin.java b/src/main/java/blob/vanillasquared/mixin/world/ServerLevelMixin.java index 62543591..56635848 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/ServerLevelMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/ServerLevelMixin.java @@ -11,12 +11,13 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BooleanSupplier; @Mixin(ServerLevel.class) public abstract class ServerLevelMixin implements VSQEntityRedstonePowerLevelAccess { @Unique - private int vsq$poweredEntityCount; + private final AtomicInteger vsq$poweredEntityCount = new AtomicInteger(); @Inject(method = "tick", at = @At("TAIL")) private void vsq$tickChanneling(BooleanSupplier haveTime, CallbackInfo ci) { @@ -27,18 +28,16 @@ public abstract class ServerLevelMixin implements VSQEntityRedstonePowerLevelAcc @Override public int vsq$getPoweredEntityCount() { - return this.vsq$poweredEntityCount; + return this.vsq$poweredEntityCount.get(); } @Override public void vsq$incrementPoweredEntityCount() { - this.vsq$poweredEntityCount++; + this.vsq$poweredEntityCount.incrementAndGet(); } @Override public void vsq$decrementPoweredEntityCount() { - if (this.vsq$poweredEntityCount > 0) { - this.vsq$poweredEntityCount--; - } + this.vsq$poweredEntityCount.updateAndGet(count -> count > 0 ? count - 1 : 0); } } diff --git a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java index 81ec3dea..e01cb06d 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java @@ -5,6 +5,9 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.monster.cubemob.SulfurCube; +import net.minecraft.world.item.Items; import net.minecraft.world.level.storage.ValueInput; import net.minecraft.world.level.storage.ValueOutput; import net.minecraft.world.phys.AABB; @@ -31,6 +34,10 @@ public abstract class EntityRedstonePowerMixin implements VSQEntityRedstonePower private void vsq$loadEntityRedstonePower(ValueInput input, CallbackInfo ci) { input.getInt(VSQEntityRedstonePower.POWER_REDSTONE_KEY) .ifPresent(power -> this.vsq$redstonePower = Mth.clamp(power, 0, 15)); + Entity entity = (Entity) (Object) this; + if (entity instanceof SulfurCube sulfurCube) { + this.vsq$redstonePower = sulfurCube.getItemBySlot(EquipmentSlot.BODY).is(Items.REDSTONE_BLOCK) ? 15 : 0; + } this.vsq$reconcileRedstonePowerCount(); } diff --git a/src/main/java/blob/vanillasquared/mixin/world/entity/entities/SulfurCubeMixin.java b/src/main/java/blob/vanillasquared/mixin/world/entity/entities/SulfurCubeMixin.java index 28fd12eb..eea753a8 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/entity/entities/SulfurCubeMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/entity/entities/SulfurCubeMixin.java @@ -49,6 +49,8 @@ public abstract class SulfurCubeMixin extends AgeableMob implements SulfurCubeBr @Unique private int vsq$breedTime; @Unique + private int vsq$lastResolvedContentRedstonePower = -1; + @Unique @Nullable private ServerPlayer vsq$loveCause; @@ -138,7 +140,12 @@ protected SulfurCubeMixin(EntityType type, Level level) { @Unique private void vsq$setRedstonePowerForContent() { ItemStack bodyItem = this.getItemBySlot(EquipmentSlot.BODY); - ((VSQEntityRedstonePowerAccess) this).vsq$setRedstonePower(bodyItem.is(Items.REDSTONE_BLOCK) ? 15 : 0); + int redstonePower = bodyItem.is(Items.REDSTONE_BLOCK) ? 15 : 0; + if (redstonePower == this.vsq$lastResolvedContentRedstonePower) { + return; + } + this.vsq$lastResolvedContentRedstonePower = redstonePower; + ((VSQEntityRedstonePowerAccess) this).vsq$setRedstonePower(redstonePower); } @Override diff --git a/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java b/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java index 9fa454c6..37fe2e1c 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java @@ -12,6 +12,7 @@ @Mixin(SignalGetter.class) public interface SignalGetterMixin { + // Mirror redstone blocks: entity power contributes weak power only, not strong/direct power. @Inject(method = "getSignal", at = @At("RETURN"), cancellable = true) private void vsq$getEntityRedstoneSignal(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { SignalGetter signalGetter = (SignalGetter) this; @@ -19,12 +20,4 @@ public interface SignalGetterMixin { cir.setReturnValue(Math.max(cir.getReturnValue(), VSQEntityRedstonePower.getSignal(level, pos))); } } - - @Inject(method = "getDirectSignal", at = @At("RETURN"), cancellable = true) - private void vsq$getDirectEntityRedstoneSignal(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { - SignalGetter signalGetter = (SignalGetter) this; - if (signalGetter instanceof ServerLevel level) { - cir.setReturnValue(Math.max(cir.getReturnValue(), VSQEntityRedstonePower.getSignal(level, pos))); - } - } } From 39c775c9ca772f09b90b56a0506ec825b267863a Mon Sep 17 00:00:00 2001 From: pxlarified Date: Sat, 4 Jul 2026 04:01:12 +0200 Subject: [PATCH 8/9] Fix entity redstone review issues --- .../main/world/redstone/VSQEntityRedstonePower.java | 2 +- .../mixin/world/ServerLevelMixin.java | 11 +++++++++++ .../world/entity/EntityRedstonePowerMixin.java | 3 ++- .../mixin/world/redstone/SignalGetterMixin.java | 13 ++++++++++--- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java index 2636fa35..93d6d766 100644 --- a/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java +++ b/src/main/java/blob/vanillasquared/main/world/redstone/VSQEntityRedstonePower.java @@ -55,7 +55,7 @@ public static int getSignal(ServerLevel level, BlockPos pos) { public static void updateNeighbors(ServerLevel level, AABB sourceBounds) { AABB updateBounds = sourceBounds.inflate(1.0D); for (BlockPos pos : BlockPos.betweenClosed(updateBounds)) { - if (vsq$isOnShell(pos, updateBounds)) { + if (vsq$isOnShell(pos, updateBounds) || new AABB(pos).intersects(sourceBounds)) { level.updateNeighborsAt(pos, Blocks.REDSTONE_WIRE, null); } } diff --git a/src/main/java/blob/vanillasquared/mixin/world/ServerLevelMixin.java b/src/main/java/blob/vanillasquared/mixin/world/ServerLevelMixin.java index 56635848..8d65d067 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/ServerLevelMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/ServerLevelMixin.java @@ -3,13 +3,17 @@ import blob.vanillasquared.main.world.effect.ChannelingState; import blob.vanillasquared.main.world.effect.LungingState; import blob.vanillasquared.main.world.effect.SwirlingState; +import blob.vanillasquared.main.world.redstone.VSQEntityRedstonePower; +import blob.vanillasquared.main.world.redstone.VSQEntityRedstonePowerAccess; import blob.vanillasquared.main.world.redstone.VSQEntityRedstonePowerLevelAccess; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BooleanSupplier; @@ -26,6 +30,13 @@ public abstract class ServerLevelMixin implements VSQEntityRedstonePowerLevelAcc SwirlingState.tick((ServerLevel) (Object) this); } + @Inject(method = "addEntity", at = @At("RETURN")) + private void vsq$reconcileLoadedEntityRedstonePower(Entity entity, CallbackInfoReturnable cir) { + if (cir.getReturnValue() && entity instanceof VSQEntityRedstonePowerAccess access) { + access.vsq$setRedstonePower(VSQEntityRedstonePower.getPower(entity)); + } + } + @Override public int vsq$getPoweredEntityCount() { return this.vsq$poweredEntityCount.get(); diff --git a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java index e01cb06d..c97643ed 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java @@ -92,7 +92,8 @@ public abstract class EntityRedstonePowerMixin implements VSQEntityRedstonePower @Inject(method = "onRemoval", at = @At("TAIL")) private void vsq$removeEntityRedstonePower(Entity.RemovalReason reason, CallbackInfo ci) { Entity entity = (Entity) (Object) this; - if (entity.level() instanceof ServerLevel level) { + ServerLevel level = entity.level() instanceof ServerLevel currentLevel ? currentLevel : this.vsq$redstonePowerCountedLevel; + if (level != null) { if (this.vsq$previousRedstonePower > 0 && this.vsq$previousRedstoneSourceBounds != null) { VSQEntityRedstonePower.updateNeighbors(level, this.vsq$previousRedstoneSourceBounds); } else if (VSQEntityRedstonePower.getPower(entity) > 0) { diff --git a/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java b/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java index 37fe2e1c..c09ec88e 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java @@ -11,11 +11,18 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(SignalGetter.class) -public interface SignalGetterMixin { - // Mirror redstone blocks: entity power contributes weak power only, not strong/direct power. +public abstract class SignalGetterMixin { @Inject(method = "getSignal", at = @At("RETURN"), cancellable = true) private void vsq$getEntityRedstoneSignal(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { - SignalGetter signalGetter = (SignalGetter) this; + SignalGetter signalGetter = (SignalGetter) (Object) this; + if (signalGetter instanceof ServerLevel level) { + cir.setReturnValue(Math.max(cir.getReturnValue(), VSQEntityRedstonePower.getSignal(level, pos))); + } + } + + @Inject(method = "getDirectSignal", at = @At("RETURN"), cancellable = true) + private void vsq$getDirectEntityRedstoneSignal(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { + SignalGetter signalGetter = (SignalGetter) (Object) this; if (signalGetter instanceof ServerLevel level) { cir.setReturnValue(Math.max(cir.getReturnValue(), VSQEntityRedstonePower.getSignal(level, pos))); } From 98cf7cc77683bcb6dd15b0e5a5fc1b43c4eba4a4 Mon Sep 17 00:00:00 2001 From: pxlarified Date: Sat, 4 Jul 2026 04:10:21 +0200 Subject: [PATCH 9/9] Fix entity redstone power updates --- .../entity/EntityRedstonePowerMixin.java | 27 +++++++++++++++++++ .../world/redstone/SignalGetterMixin.java | 27 +++++++------------ 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java index c97643ed..58e2b37a 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/entity/EntityRedstonePowerMixin.java @@ -55,8 +55,10 @@ public abstract class EntityRedstonePowerMixin implements VSQEntityRedstonePower @Override public void vsq$setRedstonePower(int power) { + int previousPower = this.vsq$redstonePower; this.vsq$redstonePower = Mth.clamp(power, 0, 15); this.vsq$reconcileRedstonePowerCount(); + this.vsq$notifyRedstonePowerChange(previousPower); } @Inject(method = "tick", at = @At("TAIL")) @@ -106,6 +108,31 @@ public abstract class EntityRedstonePowerMixin implements VSQEntityRedstonePower this.vsq$previousRedstonePower = 0; } + @Unique + private void vsq$notifyRedstonePowerChange(int previousPower) { + if (previousPower == this.vsq$redstonePower) { + return; + } + + Entity entity = (Entity) (Object) this; + if (!(entity.level() instanceof ServerLevel level)) { + return; + } + + AABB currentBounds = entity.getBoundingBox(); + if (previousPower > 0) { + VSQEntityRedstonePower.updateNeighbors(level, + this.vsq$previousRedstoneSourceBounds != null ? this.vsq$previousRedstoneSourceBounds : currentBounds); + } + if (this.vsq$redstonePower > 0) { + VSQEntityRedstonePower.updateNeighbors(level, currentBounds); + this.vsq$previousRedstoneSourceBounds = currentBounds; + } else { + this.vsq$previousRedstoneSourceBounds = null; + } + this.vsq$previousRedstonePower = this.vsq$redstonePower; + } + @Unique private void vsq$reconcileRedstonePowerCount() { Entity entity = (Entity) (Object) this; diff --git a/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java b/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java index c09ec88e..02236ea2 100644 --- a/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java +++ b/src/main/java/blob/vanillasquared/mixin/world/redstone/SignalGetterMixin.java @@ -6,25 +6,18 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.SignalGetter; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -@Mixin(SignalGetter.class) -public abstract class SignalGetterMixin { - @Inject(method = "getSignal", at = @At("RETURN"), cancellable = true) - private void vsq$getEntityRedstoneSignal(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { - SignalGetter signalGetter = (SignalGetter) (Object) this; - if (signalGetter instanceof ServerLevel level) { - cir.setReturnValue(Math.max(cir.getReturnValue(), VSQEntityRedstonePower.getSignal(level, pos))); - } +@Mixin(ServerLevel.class) +public abstract class SignalGetterMixin implements SignalGetter { + @Override + public int getSignal(BlockPos pos, Direction direction) { + int signal = SignalGetter.super.getSignal(pos, direction); + return Math.max(signal, VSQEntityRedstonePower.getSignal((ServerLevel) (Object) this, pos)); } - @Inject(method = "getDirectSignal", at = @At("RETURN"), cancellable = true) - private void vsq$getDirectEntityRedstoneSignal(BlockPos pos, Direction direction, CallbackInfoReturnable cir) { - SignalGetter signalGetter = (SignalGetter) (Object) this; - if (signalGetter instanceof ServerLevel level) { - cir.setReturnValue(Math.max(cir.getReturnValue(), VSQEntityRedstonePower.getSignal(level, pos))); - } + @Override + public int getDirectSignal(BlockPos pos, Direction direction) { + int signal = SignalGetter.super.getDirectSignal(pos, direction); + return Math.max(signal, VSQEntityRedstonePower.getSignal((ServerLevel) (Object) this, pos)); } }