From 4fe0220df3fa8e3ced297350dfa9dc0050b4437a Mon Sep 17 00:00:00 2001 From: zyxkad Date: Tue, 17 Dec 2024 12:29:16 -0700 Subject: [PATCH 1/4] add volatile keyword to DistanceDetector fields --- .../DistanceDetectorPeripheral.java | 5 +- .../blockentities/DistanceDetectorEntity.java | 83 ++++++++++--------- 2 files changed, 47 insertions(+), 41 deletions(-) diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java index af1045e4c..8acb1a323 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java @@ -41,8 +41,7 @@ public final boolean ignoresTransparency() { @LuaFunction public final void setDetectionMode(int mode) { - if (mode > 2) mode = 2; - if (mode < 0) mode = 0; + mode = Math.min(Math.max(mode, 0), 2); getPeripheralOwner().tileEntity.setDetectionType(DetectionType.values()[mode]); } @@ -71,7 +70,7 @@ public final double getDistance() { @LuaFunction public final double calculateDistance() { - return getPeripheralOwner().tileEntity.calculateDistance() - 1; + return getPeripheralOwner().tileEntity.calculateAndUpdateDistance() - 1; } @LuaFunction diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java index b9f45d060..d83d404c5 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java @@ -19,14 +19,17 @@ import net.minecraft.world.phys.*; import org.jetbrains.annotations.NotNull; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + public class DistanceDetectorEntity extends PeripheralBlockEntity { - private double maxRange = APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get(); - private float currentDistance = 0; - private boolean showLaser = true; - private boolean shouldCalculatePeriodically = false; - private boolean ignoreTransparent = true; - private DistanceDetectorPeripheral.DetectionType detectionType = DistanceDetectorPeripheral.DetectionType.BOTH; + private volatile double maxRange = APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get(); + private final AtomicInteger currentDistance = new AtomicInteger(Float.floatToRawIntBits(0)); + private final AtomicBoolean showLaser = new AtomicBoolean(true); + private volatile boolean periodicallyCalculate = false; + private volatile boolean ignoreTransparent = true; + private volatile DistanceDetectorPeripheral.DetectionType detectionType = DistanceDetectorPeripheral.DetectionType.BOTH; public DistanceDetectorEntity(BlockPos pos, BlockState state) { super(APBlockEntityTypes.DISTANCE_DETECTOR.get(), pos, state); @@ -39,43 +42,44 @@ protected DistanceDetectorPeripheral createPeripheral() { } public void setShowLaser(boolean showLaser) { - if (this.showLaser != showLaser) - APNetworking.sendToAll(new DistanceDetectorSyncPacket(getBlockPos(), getLevel().dimension(), currentDistance, showLaser)); - this.showLaser = showLaser; + if (this.showLaser.getAndSet(showLaser) != showLaser) { + APNetworking.sendToAll(new DistanceDetectorSyncPacket(getBlockPos(), getLevel().dimension(), this.getCurrentDistance(), showLaser)); + } } public void setCurrentDistance(float currentDistance) { - if (this.currentDistance != currentDistance) - APNetworking.sendToAll(new DistanceDetectorSyncPacket(getBlockPos(), getLevel().dimension(), currentDistance, showLaser)); - this.currentDistance = currentDistance; + int currentDistanceBits = Float.floatToRawIntBits(currentDistance); + if (this.currentDistance.getAndSet(currentDistanceBits) != currentDistanceBits) { + APNetworking.sendToAll(new DistanceDetectorSyncPacket(getBlockPos(), getLevel().dimension(), currentDistance, this.getLaserVisibility())); + } } - public void setShouldCalculatePeriodically(boolean shouldCalculatePeriodically) { - this.shouldCalculatePeriodically = shouldCalculatePeriodically; + public void setShouldCalculatePeriodically(boolean periodicallyCalculate) { + this.periodicallyCalculate = periodicallyCalculate; } public double getMaxDistance() { - return maxRange; + return this.maxRange; } public void setMaxRange(double maxRange) { - this.maxRange = maxRange; + this.maxRange = Math.min(Math.max(maxRange, 0), APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get()); } public float getCurrentDistance() { - return currentDistance; + return Float.intBitsToFloat(this.currentDistance.get()); } public boolean getLaserVisibility() { - return showLaser; + return this.showLaser.get(); } public boolean shouldCalculatePeriodically() { - return shouldCalculatePeriodically; + return this.periodicallyCalculate; } public boolean ignoreTransparent() { - return ignoreTransparent; + return this.ignoreTransparent; } public void setIgnoreTransparent(boolean ignoreTransparent) { @@ -83,7 +87,7 @@ public void setIgnoreTransparent(boolean ignoreTransparent) { } public DistanceDetectorPeripheral.DetectionType getDetectionType() { - return detectionType; + return this.detectionType; } public void setDetectionType(DistanceDetectorPeripheral.DetectionType detectionType) { @@ -92,47 +96,53 @@ public void setDetectionType(DistanceDetectorPeripheral.DetectionType detectionT @Override public void handleTick(Level level, BlockState state, BlockEntityType type) { - if (level.getGameTime() % APConfig.PERIPHERALS_CONFIG.distanceDetectorUpdateRate.get() == 0 && shouldCalculatePeriodically) { + if (level.getGameTime() % APConfig.PERIPHERALS_CONFIG.distanceDetectorUpdateRate.get() == 0 && this.shouldCalculatePeriodically()) { // We calculate the distance every 2 ticks, so we do not have to run the getDistance function of the peripheral // on the main thread which prevents the 1 tick yield time of the function. // The calculateDistance function is not thread safe, so we have to run it on the main thread. // It should be okay to run that function every 2 ticks, calculating it does not take too much time. - calculateDistance(); + this.calculateAndUpdateDistance(); } } @Override public AABB getRenderBoundingBox() { + final float currentDistance = this.getCurrentDistance(); Direction direction = getBlockState().getValue(BaseBlock.ORIENTATION).front(); return AABB.ofSize(Vec3.atCenterOf(getBlockPos()), direction.getStepX() * currentDistance + 1, direction.getStepY() * currentDistance + 1, direction.getStepZ() * currentDistance + 1) .move(direction.getStepX() * currentDistance / 2, direction.getStepY() * currentDistance / 2, direction.getStepZ() * currentDistance / 2); } public double calculateDistance() { + final double maxRange = this.maxRange; Direction direction = getBlockState().getValue(BaseBlock.ORIENTATION).front(); Vec3 center = Vec3.atCenterOf(getBlockPos()); Vec3 from = center.add(direction.getStepX() * 0.501, direction.getStepY() * 0.501, direction.getStepZ() * 0.501); Vec3 to = from.add(direction.getStepX() * maxRange, direction.getStepY() * maxRange, direction.getStepZ() * maxRange); HitResult result = getResult(to, from); - float distance = calculateDistance(result, center, direction); - setCurrentDistance(distance); + return calculateDistance(result, level, center, direction); + } + + public double calculateAndUpdateDistance() { + double distance = this.calculateDistance(); + this.setCurrentDistance((float) distance); return distance; } private HitResult getResult(Vec3 to, Vec3 from) { - if (detectionType == DistanceDetectorPeripheral.DetectionType.ENTITIES) - return HitResultUtil.getEntityHitResult(to, from, getLevel()); - if (detectionType == DistanceDetectorPeripheral.DetectionType.BLOCK) - return HitResultUtil.getBlockHitResult(to, from, getLevel(), ignoreTransparent); - return HitResultUtil.getHitResult(to, from, getLevel(), ignoreTransparent); + return switch (this.detectionType) { + case ENTITIES -> HitResultUtil.getEntityHitResult(to, from, getLevel()); + case BLOCK -> HitResultUtil.getBlockHitResult(to, from, getLevel(), this.ignoreTransparent); + default -> HitResultUtil.getHitResult(to, from, getLevel(), this.ignoreTransparent); + }; } - private float calculateDistance(HitResult result, Vec3 center, Direction direction) { + private static float calculateDistance(HitResult result, Level level, Vec3 center, Direction direction) { float distance = 0; if (result.getType() != HitResult.Type.MISS) { if (result instanceof BlockHitResult blockHitResult) { - BlockState resultBlock = getLevel().getBlockState(blockHitResult.getBlockPos()); + BlockState resultBlock = level.getBlockState(blockHitResult.getBlockPos()); distance = distManhattan(Vec3.atCenterOf(blockHitResult.getBlockPos()), center); distance = amendDistance(resultBlock, direction, distance); @@ -144,7 +154,7 @@ private float calculateDistance(HitResult result, Vec3 center, Direction directi return distance; } - private float amendDistance(BlockState resultBlock, Direction direction, float distance) { + private static float amendDistance(BlockState resultBlock, Direction direction, float distance) { if (resultBlock.getBlock() instanceof SlabBlock && direction.getAxis() == Direction.Axis.Y) { SlabType type = resultBlock.getValue(SlabBlock.TYPE); if (type == SlabType.TOP && direction == Direction.UP) @@ -155,10 +165,7 @@ private float amendDistance(BlockState resultBlock, Direction direction, float d return distance; } - private float distManhattan(Vec3 from, Vec3 to) { - float f = (float) Math.abs(from.x - to.x); - float f1 = (float) Math.abs(from.y - to.y); - float f2 = (float) Math.abs(from.z - to.z); - return f + f1 + f2; + private static float distManhattan(Vec3 from, Vec3 to) { + return Math.abs((float)(from.x - to.x)) + Math.abs((float)(from.y - to.y)) + Math.abs((float)(from.z - to.z)); } } From 7a5b34b362f6cb66332f38526c9b4d0cec4cc46e Mon Sep 17 00:00:00 2001 From: zyxkad Date: Tue, 17 Dec 2024 15:47:00 -0700 Subject: [PATCH 2/4] fix distance detector max distance behaviour --- .../renderer/DistanceDetectorRenderer.java | 9 ++- .../DistanceDetectorPeripheral.java | 4 +- .../blockentities/DistanceDetectorEntity.java | 58 +++++----------- .../common/util/HitResultUtil.java | 67 ++++++++++--------- 4 files changed, 61 insertions(+), 77 deletions(-) diff --git a/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java index 6731f755e..55b7b6f05 100644 --- a/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java +++ b/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java @@ -28,8 +28,13 @@ public DistanceDetectorRenderer(BlockEntityRendererProvider.Context pContext) { @Override public void render(@NotNull DistanceDetectorEntity pBlockEntity, float pPartialTick, @NotNull PoseStack pPoseStack, MultiBufferSource pBufferSource, int pPackedLight, int pPackedOverlay) { - if (pBlockEntity.getLaserVisibility()) - renderBeaconBeam(pBlockEntity, pPoseStack, pBufferSource, BeaconRenderer.BEAM_LOCATION, pPartialTick, 1, 0, pBlockEntity.getCurrentDistance() - 0.5f, EnumColor.RED.getRgb(), 0.05f, 0.09f); + if (pBlockEntity.getLaserVisibility()) { + float distance = pBlockEntity.getCurrentDistance(); + if (distance == -1) { + distance = pBlockEntity.getMaxDistance(); + } + renderBeaconBeam(pBlockEntity, pPoseStack, pBufferSource, BeaconRenderer.BEAM_LOCATION, pPartialTick, 1, 0, distance + 0.5f, EnumColor.RED.getRgb(), 0.05f, 0.09f); + } } @Override diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java index 8acb1a323..9aef4caf5 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java @@ -65,12 +65,12 @@ public final String getDetectionMode() { @LuaFunction public final double getDistance() { - return getPeripheralOwner().tileEntity.getCurrentDistance() - 1; + return getPeripheralOwner().tileEntity.getCurrentDistance(); } @LuaFunction public final double calculateDistance() { - return getPeripheralOwner().tileEntity.calculateAndUpdateDistance() - 1; + return getPeripheralOwner().tileEntity.calculateAndUpdateDistance(); } @LuaFunction diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java index d83d404c5..08bbb7b7a 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java @@ -24,7 +24,7 @@ public class DistanceDetectorEntity extends PeripheralBlockEntity { - private volatile double maxRange = APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get(); + private volatile float maxRange = (float) APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get(); private final AtomicInteger currentDistance = new AtomicInteger(Float.floatToRawIntBits(0)); private final AtomicBoolean showLaser = new AtomicBoolean(true); private volatile boolean periodicallyCalculate = false; @@ -58,12 +58,12 @@ public void setShouldCalculatePeriodically(boolean periodicallyCalculate) { this.periodicallyCalculate = periodicallyCalculate; } - public double getMaxDistance() { + public float getMaxDistance() { return this.maxRange; } - public void setMaxRange(double maxRange) { - this.maxRange = Math.min(Math.max(maxRange, 0), APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get()); + public void setMaxRange(float maxRange) { + this.maxRange = Math.min(Math.max(maxRange, 0), (float) APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get()); } public float getCurrentDistance() { @@ -117,11 +117,14 @@ public double calculateDistance() { final double maxRange = this.maxRange; Direction direction = getBlockState().getValue(BaseBlock.ORIENTATION).front(); Vec3 center = Vec3.atCenterOf(getBlockPos()); - Vec3 from = center.add(direction.getStepX() * 0.501, direction.getStepY() * 0.501, direction.getStepZ() * 0.501); + Vec3 from = center; Vec3 to = from.add(direction.getStepX() * maxRange, direction.getStepY() * maxRange, direction.getStepZ() * maxRange); - HitResult result = getResult(to, from); - return calculateDistance(result, level, center, direction); + HitResult result = this.getHitResult(to, from); + if (result.getType() == HitResult.Type.MISS) { + return -1; + } + return getDistanceOnDirection(direction, result.getLocation(), center) - 0.5f; } public double calculateAndUpdateDistance() { @@ -130,42 +133,17 @@ public double calculateAndUpdateDistance() { return distance; } - private HitResult getResult(Vec3 to, Vec3 from) { + private HitResult getHitResult(Vec3 to, Vec3 from) { + Level level = this.getLevel(); return switch (this.detectionType) { - case ENTITIES -> HitResultUtil.getEntityHitResult(to, from, getLevel()); - case BLOCK -> HitResultUtil.getBlockHitResult(to, from, getLevel(), this.ignoreTransparent); - default -> HitResultUtil.getHitResult(to, from, getLevel(), this.ignoreTransparent); + case ENTITIES -> HitResultUtil.getEntityHitResult(to, from, level); + case BLOCK -> HitResultUtil.getBlockHitResult(to, from, level, this.ignoreTransparent); + default -> HitResultUtil.getHitResult(to, from, level, this.ignoreTransparent); }; } - private static float calculateDistance(HitResult result, Level level, Vec3 center, Direction direction) { - float distance = 0; - if (result.getType() != HitResult.Type.MISS) { - if (result instanceof BlockHitResult blockHitResult) { - BlockState resultBlock = level.getBlockState(blockHitResult.getBlockPos()); - distance = distManhattan(Vec3.atCenterOf(blockHitResult.getBlockPos()), center); - - distance = amendDistance(resultBlock, direction, distance); - } - if (result instanceof EntityHitResult entityHitResult) { - distance = distManhattan(entityHitResult.getLocation(), center); - } - } - return distance; - } - - private static float amendDistance(BlockState resultBlock, Direction direction, float distance) { - if (resultBlock.getBlock() instanceof SlabBlock && direction.getAxis() == Direction.Axis.Y) { - SlabType type = resultBlock.getValue(SlabBlock.TYPE); - if (type == SlabType.TOP && direction == Direction.UP) - return distance + 0.5f; - if (type == SlabType.BOTTOM && direction == Direction.DOWN) - return distance - 0.5f; - } - return distance; - } - - private static float distManhattan(Vec3 from, Vec3 to) { - return Math.abs((float)(from.x - to.x)) + Math.abs((float)(from.y - to.y)) + Math.abs((float)(from.z - to.z)); + private static float getDistanceOnDirection(Direction direction, Vec3 from, Vec3 to) { + Direction.Axis axis = direction.getAxis(); + return Math.abs((float)(axis.choose(from.x, from.y, from.z) - axis.choose(to.x, to.y, to.z))); } } diff --git a/src/main/java/de/srendi/advancedperipherals/common/util/HitResultUtil.java b/src/main/java/de/srendi/advancedperipherals/common/util/HitResultUtil.java index 1a9508a1e..d3d0c9c1e 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/util/HitResultUtil.java +++ b/src/main/java/de/srendi/advancedperipherals/common/util/HitResultUtil.java @@ -34,22 +34,19 @@ public static HitResult getHitResult(Vec3 to, Vec3 from, Level level, boolean ig EntityHitResult entityResult = getEntityHitResult(to, from, level); BlockHitResult blockResult = getBlockHitResult(to, from, level, ignoreTransparent); - if (entityResult.getType() != HitResult.Type.MISS && blockResult.getType() == HitResult.Type.MISS) - return entityResult; - - if (entityResult.getType() == HitResult.Type.MISS && blockResult.getType() != HitResult.Type.MISS) + if (entityResult.getType() == HitResult.Type.MISS) { + if (blockResult.getType() == HitResult.Type.MISS) { + return BlockHitResult.miss(from, blockResult.getDirection(), new BlockPos(to)); + } return blockResult; + } else if (blockResult.getType() == HitResult.Type.MISS) { + return entityResult; + } - if (entityResult.getType() == HitResult.Type.MISS && blockResult.getType() == HitResult.Type.MISS) - return BlockHitResult.miss(from, blockResult.getDirection(), new BlockPos(to)); - - double blockDistance = new BlockPos(from).distManhattan(blockResult.getBlockPos()); - double entityDistance = new BlockPos(from).distManhattan(new Vec3i(entityResult.getLocation().x, entityResult.getLocation().y, entityResult.getLocation().z)); + double blockDistance = from.distanceToSqr(blockResult.getLocation()); + double entityDistance = from.distanceToSqr(entityResult.getLocation()); - if (blockDistance < entityDistance) - return blockResult; - - return entityResult; + return blockDistance < entityDistance ? blockResult : entityResult; } /** @@ -69,27 +66,24 @@ public static EntityHitResult getEntityHitResult(Vec3 to, Vec3 from, Level level List entities = level.getEntities((Entity) null, checkingBox, (entity) -> true); - if (entities.isEmpty()) - return new EmptyEntityHitResult(); - Entity nearestEntity = null; + Vec3 hitPos = null; + double nearestDist = 0; // Find the nearest entity for (Entity entity : entities) { - if (nearestEntity == null) { - nearestEntity = entity; - continue; + Vec3 pos = entity.getBoundingBox().clip(from, to).orElse(null); + if (pos != null) { + double distance = from.distanceToSqr(pos); + if (nearestEntity == null || distance < nearestDist) { + nearestEntity = entity; + hitPos = pos; + nearestDist = distance; + } } - - double distance = new BlockPos(from).distManhattan(new Vec3i(entity.getX(), entity.getY(), entity.getZ())); - double nearestDistance = new BlockPos(from).distManhattan(new Vec3i(nearestEntity.getX(), nearestEntity.getY(), nearestEntity.getZ())); - - // If it's closer, set it as the nearest entity - if (distance < nearestDistance) - nearestEntity = entity; } - return new EntityHitResult(nearestEntity); + return nearestEntity == null ? EmptyEntityHitResult.INSTANCE : new EntityHitResult(nearestEntity, hitPos); } /** @@ -103,15 +97,16 @@ public static EntityHitResult getEntityHitResult(Vec3 to, Vec3 from, Level level */ @NotNull public static BlockHitResult getBlockHitResult(Vec3 to, Vec3 from, Level level, boolean ignoreNoOccluded) { - return level.clip(new AdvancecClipContext(from, to, ignoreNoOccluded ? IgnoreNoOccludedContext.INSTANCE : ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, null)); + return level.clip(new AdvancedClipContext(from, to, ignoreNoOccluded ? IgnoreNoOccludedContext.INSTANCE : ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, null, true)); } public static class EmptyEntityHitResult extends EntityHitResult { + public static final EmptyEntityHitResult INSTANCE = new EmptyEntityHitResult(); /** * The super constructor is a NotNull argument but since this result is empty, we'll just return null */ - public EmptyEntityHitResult() { + private EmptyEntityHitResult() { super(null, null); } @@ -125,9 +120,10 @@ public Type getType() { /** * A shape getter which ignores blocks which are not occluding like glass */ - private enum IgnoreNoOccludedContext implements ClipContext.ShapeGetter { + private static class IgnoreNoOccludedContext implements ClipContext.ShapeGetter { + public static final IgnoreNoOccludedContext INSTANCE = new IgnoreNoOccludedContext(); - INSTANCE; + private IgnoreNoOccludedContext() {} @NotNull @Override @@ -139,18 +135,23 @@ public VoxelShape get(BlockState pState, @NotNull BlockGetter pBlock, @NotNull B /** * A clip context but with a custom shape getter. Used to define another shape getter for the block like {@link IgnoreNoOccludedContext} */ - private static class AdvancecClipContext extends ClipContext { + private static class AdvancedClipContext extends ClipContext { private final ShapeGetter blockShapeGetter; + private final boolean ignoreSourceBlock; - protected AdvancecClipContext(Vec3 from, Vec3 to, ShapeGetter blockShapeGetter, Fluid fluidShapeGetter, @Nullable Entity entity) { + protected AdvancedClipContext(Vec3 from, Vec3 to, ShapeGetter blockShapeGetter, Fluid fluidShapeGetter, @Nullable Entity entity, boolean ignoreSourceBlock) { super(from, to, Block.COLLIDER, fluidShapeGetter, entity); this.blockShapeGetter = blockShapeGetter; + this.ignoreSourceBlock = ignoreSourceBlock; } @NotNull @Override public VoxelShape getBlockShape(@NotNull BlockState pBlockState, @NotNull BlockGetter pLevel, @NotNull BlockPos pPos) { + if (this.ignoreSourceBlock && pPos.equals(new BlockPos(this.getFrom()))) { + return Shapes.empty(); + } return blockShapeGetter.get(pBlockState, pLevel, pPos, this.collisionContext); } } From a4906c29baf1084bc64261b25ce09897246c0216 Mon Sep 17 00:00:00 2001 From: zyxkad Date: Tue, 17 Dec 2024 15:50:02 -0700 Subject: [PATCH 3/4] fix double float convert --- .../computercraft/peripheral/DistanceDetectorPeripheral.java | 2 +- .../common/blocks/blockentities/DistanceDetectorEntity.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java index 9aef4caf5..3a83fe304 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java @@ -85,7 +85,7 @@ public final void setCalculatePeriodically(boolean shouldRenderPeriodically) { @LuaFunction public final void setMaxRange(double maxDistance) { - getPeripheralOwner().tileEntity.setMaxRange(Math.max(0, Math.min(APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get(), maxDistance))); + getPeripheralOwner().tileEntity.setMaxRange((float) maxDistance); } @LuaFunction diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java index 08bbb7b7a..50ea33462 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java @@ -24,7 +24,7 @@ public class DistanceDetectorEntity extends PeripheralBlockEntity { - private volatile float maxRange = (float) APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get(); + private volatile float maxRange = APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get().floatValue(); private final AtomicInteger currentDistance = new AtomicInteger(Float.floatToRawIntBits(0)); private final AtomicBoolean showLaser = new AtomicBoolean(true); private volatile boolean periodicallyCalculate = false; @@ -63,7 +63,7 @@ public float getMaxDistance() { } public void setMaxRange(float maxRange) { - this.maxRange = Math.min(Math.max(maxRange, 0), (float) APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get()); + this.maxRange = Math.min(Math.max(maxRange, 0), APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get().floatValue()); } public float getCurrentDistance() { From 6ef834b7ba08efae0708338d64bdbcd68ffc89bf Mon Sep 17 00:00:00 2001 From: zyxkad Date: Wed, 18 Dec 2024 12:07:57 -0700 Subject: [PATCH 4/4] Persistence distance detector settings --- .../renderer/DistanceDetectorRenderer.java | 2 +- .../DistanceDetectorPeripheral.java | 2 +- .../blocks/base/PeripheralBlockEntity.java | 7 +- .../blockentities/DistanceDetectorEntity.java | 110 ++++++++++++++---- .../common/network/APNetworking.java | 2 - .../toclient/DistanceDetectorSyncPacket.java | 59 ---------- 6 files changed, 95 insertions(+), 87 deletions(-) delete mode 100644 src/main/java/de/srendi/advancedperipherals/common/network/toclient/DistanceDetectorSyncPacket.java diff --git a/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java b/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java index 55b7b6f05..2bb048706 100644 --- a/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java +++ b/src/main/java/de/srendi/advancedperipherals/client/renderer/DistanceDetectorRenderer.java @@ -31,7 +31,7 @@ public void render(@NotNull DistanceDetectorEntity pBlockEntity, float pPartialT if (pBlockEntity.getLaserVisibility()) { float distance = pBlockEntity.getCurrentDistance(); if (distance == -1) { - distance = pBlockEntity.getMaxDistance(); + distance = pBlockEntity.getMaxRange(); } renderBeaconBeam(pBlockEntity, pPoseStack, pBufferSource, BeaconRenderer.BEAM_LOCATION, pPartialTick, 1, 0, distance + 0.5f, EnumColor.RED.getRgb(), 0.05f, 0.09f); } diff --git a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java index 3a83fe304..105292147 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java +++ b/src/main/java/de/srendi/advancedperipherals/common/addons/computercraft/peripheral/DistanceDetectorPeripheral.java @@ -90,7 +90,7 @@ public final void setMaxRange(double maxDistance) { @LuaFunction public final double getMaxRange() { - return getPeripheralOwner().tileEntity.getMaxDistance(); + return getPeripheralOwner().tileEntity.getMaxRange(); } public enum DetectionType { diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PeripheralBlockEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PeripheralBlockEntity.java index 654fefeb3..e98b317d8 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PeripheralBlockEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/base/PeripheralBlockEntity.java @@ -230,7 +230,12 @@ public CompoundTag getPeripheralSettings() { @Override public void markSettingsChanged() { - setChanged(); + this.setChanged(); + } + + protected void sendUpdate() { + this.setChanged(); + this.getLevel().sendBlockUpdated(this.getBlockPos(), this.getBlockState(), this.getBlockState(), 11); } public ComputerSide getComputerSide(Direction direction) { diff --git a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java index 50ea33462..db5b451cc 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java +++ b/src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/DistanceDetectorEntity.java @@ -5,11 +5,13 @@ import de.srendi.advancedperipherals.common.blocks.base.PeripheralBlockEntity; import de.srendi.advancedperipherals.common.configuration.APConfig; import de.srendi.advancedperipherals.common.network.APNetworking; -import de.srendi.advancedperipherals.common.network.toclient.DistanceDetectorSyncPacket; import de.srendi.advancedperipherals.common.setup.APBlockEntityTypes; import de.srendi.advancedperipherals.common.util.HitResultUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.SlabBlock; import net.minecraft.world.level.block.entity.BlockEntity; @@ -17,6 +19,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.SlabType; import net.minecraft.world.phys.*; + import org.jetbrains.annotations.NotNull; import java.util.concurrent.atomic.AtomicBoolean; @@ -24,8 +27,8 @@ public class DistanceDetectorEntity extends PeripheralBlockEntity { - private volatile float maxRange = APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get().floatValue(); - private final AtomicInteger currentDistance = new AtomicInteger(Float.floatToRawIntBits(0)); + private final AtomicInteger maxRange = new AtomicInteger(Float.floatToRawIntBits(APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get().floatValue())); + private final AtomicInteger currentDistance = new AtomicInteger(Float.floatToRawIntBits(-1)); private final AtomicBoolean showLaser = new AtomicBoolean(true); private volatile boolean periodicallyCalculate = false; private volatile boolean ignoreTransparent = true; @@ -41,49 +44,70 @@ protected DistanceDetectorPeripheral createPeripheral() { return new DistanceDetectorPeripheral(this); } - public void setShowLaser(boolean showLaser) { - if (this.showLaser.getAndSet(showLaser) != showLaser) { - APNetworking.sendToAll(new DistanceDetectorSyncPacket(getBlockPos(), getLevel().dimension(), this.getCurrentDistance(), showLaser)); - } + public float getMaxRange() { + return Float.intBitsToFloat(this.maxRange.get()); } - public void setCurrentDistance(float currentDistance) { - int currentDistanceBits = Float.floatToRawIntBits(currentDistance); - if (this.currentDistance.getAndSet(currentDistanceBits) != currentDistanceBits) { - APNetworking.sendToAll(new DistanceDetectorSyncPacket(getBlockPos(), getLevel().dimension(), currentDistance, this.getLaserVisibility())); - } + protected void setMaxRangeNoUpdate(float maxRange) { + maxRange = Math.min(Math.max(maxRange, 0), APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get().floatValue()); + int maxRangeBits = Float.floatToRawIntBits(maxRange); + this.maxRange.set(maxRangeBits); } - public void setShouldCalculatePeriodically(boolean periodicallyCalculate) { - this.periodicallyCalculate = periodicallyCalculate; + public void setMaxRange(float maxRange) { + maxRange = Math.min(Math.max(maxRange, 0), APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get().floatValue()); + int maxRangeBits = Float.floatToRawIntBits(maxRange); + if (this.maxRange.getAndSet(maxRangeBits) != maxRange) { + this.sendUpdate(); + } } - public float getMaxDistance() { - return this.maxRange; + public float getCurrentDistance() { + return Float.intBitsToFloat(this.currentDistance.get()); } - public void setMaxRange(float maxRange) { - this.maxRange = Math.min(Math.max(maxRange, 0), APConfig.PERIPHERALS_CONFIG.distanceDetectorRange.get().floatValue()); + protected void setCurrentDistanceNoUpdate(float currentDistance) { + int currentDistanceBits = Float.floatToRawIntBits(currentDistance); + this.currentDistance.set(currentDistanceBits); } - public float getCurrentDistance() { - return Float.intBitsToFloat(this.currentDistance.get()); + public void setCurrentDistance(float currentDistance) { + int currentDistanceBits = Float.floatToRawIntBits(currentDistance); + if (this.currentDistance.getAndSet(currentDistanceBits) != currentDistanceBits) { + this.sendUpdate(); + } } public boolean getLaserVisibility() { return this.showLaser.get(); } + protected void setShowLaserNoUpdate(boolean showLaser) { + this.showLaser.set(showLaser); + } + + public void setShowLaser(boolean showLaser) { + if (this.showLaser.getAndSet(showLaser) != showLaser) { + this.sendUpdate(); + } + } + public boolean shouldCalculatePeriodically() { return this.periodicallyCalculate; } + public void setShouldCalculatePeriodically(boolean periodicallyCalculate) { + this.periodicallyCalculate = periodicallyCalculate; + this.setChanged(); + } + public boolean ignoreTransparent() { return this.ignoreTransparent; } public void setIgnoreTransparent(boolean ignoreTransparent) { this.ignoreTransparent = ignoreTransparent; + this.setChanged(); } public DistanceDetectorPeripheral.DetectionType getDetectionType() { @@ -92,6 +116,7 @@ public DistanceDetectorPeripheral.DetectionType getDetectionType() { public void setDetectionType(DistanceDetectorPeripheral.DetectionType detectionType) { this.detectionType = detectionType; + this.setChanged(); } @Override @@ -107,14 +132,53 @@ public void handleTick(Level level, BlockState state, Bl @Override public AABB getRenderBoundingBox() { - final float currentDistance = this.getCurrentDistance(); + float currentDistance = this.getCurrentDistance(); + if (currentDistance == -1) { + currentDistance = this.getMaxRange(); + } Direction direction = getBlockState().getValue(BaseBlock.ORIENTATION).front(); return AABB.ofSize(Vec3.atCenterOf(getBlockPos()), direction.getStepX() * currentDistance + 1, direction.getStepY() * currentDistance + 1, direction.getStepZ() * currentDistance + 1) - .move(direction.getStepX() * currentDistance / 2, direction.getStepY() * currentDistance / 2, direction.getStepZ() * currentDistance / 2); + .move(direction.getStepX() * currentDistance / 2, direction.getStepY() * currentDistance / 2, direction.getStepZ() * currentDistance / 2); + } + + @Override + public void load(@NotNull CompoundTag compound) { + this.setMaxRangeNoUpdate(compound.getFloat("maxRange")); + this.setCurrentDistanceNoUpdate(compound.getFloat("currentDistance")); + this.setShowLaserNoUpdate(compound.getBoolean("showLaser")); + this.setShouldCalculatePeriodically(compound.getBoolean("calculatePeriodically")); + this.setIgnoreTransparent(compound.getBoolean("ignoreTransparent")); + this.setDetectionType(DistanceDetectorPeripheral.DetectionType.values()[compound.getByte("detectionType")]); + super.load(compound); + } + + @Override + public void saveAdditional(@NotNull CompoundTag compound) { + super.saveAdditional(compound); + compound.putFloat("maxRange", this.getMaxRange()); + compound.putFloat("currentDistance", this.getCurrentDistance()); + compound.putBoolean("showLaser", this.getLaserVisibility()); + compound.putBoolean("calculatePeriodically", this.shouldCalculatePeriodically()); + compound.putBoolean("ignoreTransparent", this.ignoreTransparent()); + compound.putByte("detectionType", (byte) this.getDetectionType().ordinal()); + } + + @Override + public CompoundTag getUpdateTag() { + CompoundTag compound = super.getUpdateTag(); + compound.putFloat("maxRange", this.getMaxRange()); + compound.putFloat("currentDistance", this.getCurrentDistance()); + compound.putBoolean("showLaser", this.getLaserVisibility()); + return compound; + } + + @Override + public ClientboundBlockEntityDataPacket getUpdatePacket() { + return ClientboundBlockEntityDataPacket.create(this); } public double calculateDistance() { - final double maxRange = this.maxRange; + final double maxRange = this.getMaxRange(); Direction direction = getBlockState().getValue(BaseBlock.ORIENTATION).front(); Vec3 center = Vec3.atCenterOf(getBlockPos()); Vec3 from = center; diff --git a/src/main/java/de/srendi/advancedperipherals/common/network/APNetworking.java b/src/main/java/de/srendi/advancedperipherals/common/network/APNetworking.java index 0caad2cf5..d007a4b1d 100644 --- a/src/main/java/de/srendi/advancedperipherals/common/network/APNetworking.java +++ b/src/main/java/de/srendi/advancedperipherals/common/network/APNetworking.java @@ -2,7 +2,6 @@ import de.srendi.advancedperipherals.AdvancedPeripherals; import de.srendi.advancedperipherals.common.network.base.IPacket; -import de.srendi.advancedperipherals.common.network.toclient.DistanceDetectorSyncPacket; import de.srendi.advancedperipherals.common.network.toclient.RenderableObjectBulkSyncPacket; import de.srendi.advancedperipherals.common.network.toclient.RenderableObjectClearPacket; import de.srendi.advancedperipherals.common.network.toclient.RenderableObjectDeletePacket; @@ -39,7 +38,6 @@ public class APNetworking { private static int index = 0; public static void init() { - registerServerToClient(DistanceDetectorSyncPacket.class, DistanceDetectorSyncPacket::decode); registerServerToClient(SaddleTurtleInfoPacket.class, SaddleTurtleInfoPacket::decode); registerServerToClient(ToastToClientPacket.class, ToastToClientPacket::decode); registerServerToClient(RenderableObjectSyncPacket.class, RenderableObjectSyncPacket::decode); diff --git a/src/main/java/de/srendi/advancedperipherals/common/network/toclient/DistanceDetectorSyncPacket.java b/src/main/java/de/srendi/advancedperipherals/common/network/toclient/DistanceDetectorSyncPacket.java deleted file mode 100644 index 484ec7520..000000000 --- a/src/main/java/de/srendi/advancedperipherals/common/network/toclient/DistanceDetectorSyncPacket.java +++ /dev/null @@ -1,59 +0,0 @@ -package de.srendi.advancedperipherals.common.network.toclient; - -import de.srendi.advancedperipherals.AdvancedPeripherals; -import de.srendi.advancedperipherals.common.blocks.blockentities.DistanceDetectorEntity; -import de.srendi.advancedperipherals.common.network.base.IPacket; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Registry; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraftforge.network.NetworkEvent; - -public class DistanceDetectorSyncPacket implements IPacket { - - private final BlockPos position; - private final ResourceKey world; - private final float distance; - private final boolean showLaser; - - public DistanceDetectorSyncPacket(BlockPos position, ResourceKey world, float distance, boolean showLaser) { - this.position = position; - this.world = world; - this.distance = distance; - this.showLaser = showLaser; - } - - @Override - public void handle(NetworkEvent.Context context) { - ClientLevel level = Minecraft.getInstance().level; - if (!level.dimension().equals(world)) - return; - - BlockEntity tileEntity = level.getBlockEntity(position); - if (tileEntity == null) { - AdvancedPeripherals.debug("Could not update distance detector at " + position + " in world " + world.location() - + " because the world or the tile entity couldn't be found. Ignoring it"); - return; - } - if (tileEntity instanceof DistanceDetectorEntity detector) { - detector.setCurrentDistance(distance); - detector.setShowLaser(showLaser); - } - } - - @Override - public void encode(FriendlyByteBuf buffer) { - buffer.writeBlockPos(position); - buffer.writeResourceKey(world); - buffer.writeFloat(distance); - buffer.writeBoolean(showLaser); - } - - public static DistanceDetectorSyncPacket decode(FriendlyByteBuf buffer) { - return new DistanceDetectorSyncPacket(buffer.readBlockPos(), buffer.readResourceKey(Registry.DIMENSION_REGISTRY), buffer.readFloat(), buffer.readBoolean()); - } -}