From 1b11589d367d87b75fc1303e989efaa52aadef55 Mon Sep 17 00:00:00 2001 From: Des Herriott Date: Tue, 15 Oct 2024 15:40:54 +0100 Subject: [PATCH] fixed race condition in CC / air cannon integration --- .../block/entity/AirCannonBlockEntity.java | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/main/java/me/desht/pneumaticcraft/common/block/entity/AirCannonBlockEntity.java b/src/main/java/me/desht/pneumaticcraft/common/block/entity/AirCannonBlockEntity.java index 20490cb4f..2d30b4cfa 100644 --- a/src/main/java/me/desht/pneumaticcraft/common/block/entity/AirCannonBlockEntity.java +++ b/src/main/java/me/desht/pneumaticcraft/common/block/entity/AirCannonBlockEntity.java @@ -76,6 +76,7 @@ import javax.annotation.Nullable; import java.util.*; import java.util.Map.Entry; +import java.util.concurrent.atomic.AtomicBoolean; import static me.desht.pneumaticcraft.common.util.PneumaticCraftUtils.xlate; @@ -134,6 +135,8 @@ public class AirCannonBlockEntity extends AbstractAirHandlingBlockEntity public boolean insertingInventoryHasSpace = true; private boolean gpsSlotChanged = true; private FakePlayer fakePlayer = null; + private final AtomicBoolean firePending = new AtomicBoolean(false); + private final AtomicBoolean lastFireOK = new AtomicBoolean(false); private static final int INVENTORY_SIZE = 2; private static final int CANNON_SLOT = 0; @@ -175,6 +178,10 @@ public void tickCommonPre() { public void tickServer() { super.tickServer(); + if (firePending.get()) { + lastFireOK.set(fire()); + } + updateTrackedItems(); updateTrackedTNT(); @@ -570,7 +577,7 @@ public void onNeighborBlockUpdate(BlockPos fromPos) { super.onNeighborBlockUpdate(fromPos); boolean isPowered = rsController.getCurrentRedstonePower() > 0; if (isPowered && !wasPowered && rsController.shouldRun()) { - fire(); + lastFireOK.set(fire()); } } @@ -593,8 +600,14 @@ private boolean inventoryCanCarry() { }); } - private synchronized boolean fire() { + private synchronized boolean requestFire() { + firePending.set(true); + return true; + } + + private boolean fire() { Entity launchedEntity = getCloseEntityIfUpgraded(); + firePending.set(false); if (getPressure() >= PneumaticValues.MIN_PRESSURE_AIR_CANNON && (launchedEntity != null || !itemHandler.getStackInSlot(CANNON_SLOT).isEmpty())) { float force = getForce(); //noinspection SuspiciousNameCombination @@ -694,7 +707,16 @@ public Object[] call(Object[] args) { public Object[] call(Object[] args) { requireNoArgs(args); // returns true if the fire succeeded. - return new Object[]{fire()}; + return new Object[]{ requestFire() }; + } + }); + + registry.registerLuaMethod(new LuaMethod("firedOK") { + @Override + public Object[] call(Object[] args) { + requireNoArgs(args); + // returns true if the fire succeeded. + return new Object[]{ lastFireOK.get() }; } });