Pulley a Stunt

- Fluid manipulation of Hose Pulleys can no longer cause chunks to be loaded
- Hose Pulleys no longer lose infinite status upon un- and reloading
- Hose Pulleys now retain infinite status if surrounding lake is not fully loaded
- Fixed Hose Pulley not loading in extended on the client side
This commit is contained in:
simibubi 2022-12-08 20:05:06 +01:00
parent fecb410909
commit 450359b212
4 changed files with 49 additions and 23 deletions

View file

@ -86,7 +86,7 @@ public class FluidDrainingBehaviour extends FluidManipulationBehaviour {
while (!queue.isEmpty()) {
// Dont dequeue here, so we can decide not to dequeue a valid entry when
// simulating
BlockPos currentPos = queue.first().pos;
BlockPos currentPos = queue.first().pos();
BlockState blockState = world.getBlockState(currentPos);
BlockState emptied = blockState;
Fluid fluid = Fluids.EMPTY;
@ -262,10 +262,15 @@ public class FluidDrainingBehaviour extends FluidManipulationBehaviour {
}
private void continueSearch() {
fluid = search(fluid, frontier, visited, (e, d) -> {
queue.enqueue(new BlockPosEntry(e, d));
validationSet.add(e);
}, false);
try {
fluid = search(fluid, frontier, visited, (e, d) -> {
queue.enqueue(new BlockPosEntry(e, d));
validationSet.add(e);
}, false);
} catch (ChunkNotLoadedException e) {
tileEntity.sendData();
visited.clear();
}
Level world = getWorld();
int maxBlocks = maxBlocks();
@ -273,14 +278,14 @@ public class FluidDrainingBehaviour extends FluidManipulationBehaviour {
infinite = true;
// Find first block with valid fluid
while (true) {
BlockPos first = queue.first().pos;
BlockPos first = queue.first().pos();
if (canPullFluidsFrom(world.getBlockState(first), first) != FluidBlockType.SOURCE) {
queue.dequeue();
continue;
}
break;
}
BlockPos firstValid = queue.first().pos;
BlockPos firstValid = queue.first().pos();
frontier.clear();
visited.clear();
queue.clear();
@ -297,7 +302,13 @@ public class FluidDrainingBehaviour extends FluidManipulationBehaviour {
}
private void continueValidation() {
search(fluid, validationFrontier, validationVisited, (e, d) -> newValidationSet.add(e), false);
try {
search(fluid, validationFrontier, validationVisited, (e, d) -> newValidationSet.add(e), false);
} catch (ChunkNotLoadedException e) {
validationFrontier.clear();
setLongValidationTimer();
return;
}
int maxBlocks = maxBlocks();
if (validationVisited.size() > maxBlocks && canDrainInfinitely(fluid)) {

View file

@ -71,8 +71,15 @@ public class FluidFillingBehaviour extends FluidManipulationBehaviour {
}
protected void continueValidation(Fluid fluid) {
search(fluid, infinityCheckFrontier, infinityCheckVisited,
(p, d) -> infinityCheckFrontier.add(new BlockPosEntry(p, d)), true);
try {
search(fluid, infinityCheckFrontier, infinityCheckVisited,
(p, d) -> infinityCheckFrontier.add(new BlockPosEntry(p, d)), true);
} catch (ChunkNotLoadedException e) {
infinityCheckFrontier.clear();
setLongValidationTimer();
return;
}
int maxBlocks = maxBlocks();
if (infinityCheckVisited.size() > maxBlocks && maxBlocks != -1 && !fillInfinite()) {
@ -154,7 +161,7 @@ public class FluidFillingBehaviour extends FluidManipulationBehaviour {
boolean success = false;
for (int i = 0; !success && !queue.isEmpty() && i < searchedPerTick; i++) {
BlockPosEntry entry = queue.first();
BlockPos currentPos = entry.pos;
BlockPos currentPos = entry.pos();
if (visited.contains(currentPos)) {
queue.dequeue();
@ -223,7 +230,7 @@ public class FluidFillingBehaviour extends FluidManipulationBehaviour {
SpaceType nextSpaceType = getAtPos(world, offsetPos, fluid);
if (nextSpaceType != SpaceType.BLOCKING)
queue.enqueue(new BlockPosEntry(offsetPos, entry.distance + 1));
queue.enqueue(new BlockPosEntry(offsetPos, entry.distance() + 1));
}
}

View file

@ -14,6 +14,7 @@ import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.core.BlockPos;
@ -35,23 +36,20 @@ import net.minecraftforge.fluids.FluidStack;
public abstract class FluidManipulationBehaviour extends TileEntityBehaviour {
protected static class BlockPosEntry {
public BlockPos pos;
public int distance;
public BlockPosEntry(BlockPos pos, int distance) {
this.pos = pos;
this.distance = distance;
}
public static record BlockPosEntry(BlockPos pos, int distance) {
};
public static class ChunkNotLoadedException extends Exception {
private static final long serialVersionUID = 1L;
}
BoundingBox affectedArea;
BlockPos rootPos;
boolean infinite;
protected boolean counterpartActed;
// Search
static final int searchedPerTick = 256;
static final int searchedPerTick = 1024;
static final int validationTimerMin = 160;
List<BlockPosEntry> frontier;
Set<BlockPos> visited;
@ -143,7 +141,7 @@ public abstract class FluidManipulationBehaviour extends TileEntityBehaviour {
}
protected Fluid search(Fluid fluid, List<BlockPosEntry> frontier, Set<BlockPos> visited,
BiConsumer<BlockPos, Integer> add, boolean searchDownward) {
BiConsumer<BlockPos, Integer> add, boolean searchDownward) throws ChunkNotLoadedException {
Level world = getWorld();
int maxBlocks = maxBlocks();
int maxRange = canDrainInfinitely(fluid) ? maxRange() : maxRange() / 2;
@ -158,6 +156,9 @@ public abstract class FluidManipulationBehaviour extends TileEntityBehaviour {
continue;
visited.add(currentPos);
if (!world.isLoaded(currentPos))
throw new ChunkNotLoadedException();
FluidState fluidState = world.getFluidState(currentPos);
if (fluidState.isEmpty())
continue;
@ -175,6 +176,8 @@ public abstract class FluidManipulationBehaviour extends TileEntityBehaviour {
continue;
BlockPos offsetPos = currentPos.relative(side);
if (!world.isLoaded(offsetPos))
throw new ChunkNotLoadedException();
if (visited.contains(offsetPos))
continue;
if (offsetPos.distSqr(rootPos) > maxRangeSq)
@ -221,6 +224,8 @@ public abstract class FluidManipulationBehaviour extends TileEntityBehaviour {
@Override
public void write(CompoundTag nbt, boolean clientPacket) {
if (infinite)
NBTHelper.putMarker(nbt, "Infinite");
if (rootPos != null)
nbt.put("LastPos", NbtUtils.writeBlockPos(rootPos));
if (affectedArea != null) {
@ -234,6 +239,7 @@ public abstract class FluidManipulationBehaviour extends TileEntityBehaviour {
@Override
public void read(CompoundTag nbt, boolean clientPacket) {
infinite = nbt.contains("Infinite");
if (nbt.contains("LastPos"))
rootPos = NbtUtils.readBlockPos(nbt.getCompound("LastPos"));
if (nbt.contains("AffectedAreaFrom") && nbt.contains("AffectedAreaTo"))

View file

@ -147,6 +147,8 @@ public class HosePulleyTileEntity extends KineticTileEntity {
@Override
protected void write(CompoundTag compound, boolean clientPacket) {
if (clientPacket)
offset.forceNextSync();
compound.put("Offset", offset.writeNBT());
compound.put("Tank", internalTank.writeToNBT(new CompoundTag()));
super.write(compound, clientPacket);