Skip to content

Commit

Permalink
Improved thermoregulator spreading
Browse files Browse the repository at this point in the history
  • Loading branch information
Adubbz committed Jan 8, 2024
1 parent e2c27a2 commit 9d997ea
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import toughasnails.api.temperature.TemperatureHelper;
import toughasnails.block.ThermoregulatorBlock;
import toughasnails.container.ThermoregulatorContainer;
import toughasnails.core.ToughAsNails;
import toughasnails.init.ModTags;
import toughasnails.temperature.AreaFill;

Expand Down Expand Up @@ -224,19 +223,19 @@ public static void serverTick(Level level, BlockPos pos, BlockState state, Therm
blockEntity.filledBlocks.clear();
AreaFill.fill(level, fillStart, new AreaFill.PositionChecker() {
@Override
public void onSolid(Level level, AreaFill.PosAndDepth pos) {}
public void onSolid(Level level, AreaFill.FillPos pos) {}

@Override
public void onPassable(Level level, AreaFill.PosAndDepth pos)
public void onPassable(Level level, AreaFill.FillPos pos)
{
blockEntity.filledBlocks.add(pos.pos());
}

@Override
public boolean isPassable(Level level, BlockPos pos)
public boolean isPassable(Level level, AreaFill.FillPos pos)
{
BlockState state = level.getBlockState(pos);
return state.isAir() || !isFullySolid(level, pos);
BlockState state = level.getBlockState(pos.pos());
return isConfined(level, pos.pos()) && (state.isAir() || !isFlowBlocking(level, pos, state));
}
}, SPREAD_RADIUS);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@
import net.minecraft.world.phys.Vec3;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import toughasnails.api.temperature.ITemperature;
import toughasnails.api.temperature.TemperatureHelper;
import toughasnails.block.entity.ThermoregulatorBlockEntity;
import toughasnails.core.ToughAsNails;
import toughasnails.temperature.AreaFill;

import java.util.Arrays;
Expand Down Expand Up @@ -84,7 +82,7 @@ private static void populateConnectedBlocks(Player player)
Set<BlockPos> blockingPositions = new HashSet<>();
AreaFill.fill(level, playerPos, new AreaFill.PositionChecker() {
@Override
public void onSolid(Level level, AreaFill.PosAndDepth pos)
public void onSolid(Level level, AreaFill.FillPos pos)
{
BlockState state = level.getBlockState(pos.pos());

Expand All @@ -100,7 +98,7 @@ else if (TemperatureHelper.isCoolingBlock(state))
}

@Override
public void onPassable(Level level, AreaFill.PosAndDepth pos)
public void onPassable(Level level, AreaFill.FillPos pos)
{
passablePositions.add(pos.pos());
}
Expand Down
1 change: 1 addition & 0 deletions common/src/main/java/toughasnails/init/ModParticles.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package toughasnails.init;

import net.minecraft.core.particles.ParticleType;
import net.minecraft.core.particles.SimpleParticleType;
import net.minecraft.resources.ResourceLocation;
import toughasnails.api.TANAPI;

Expand Down
78 changes: 41 additions & 37 deletions common/src/main/java/toughasnails/temperature/AreaFill.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
import net.minecraft.core.Direction;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.Heightmap;
import toughasnails.api.temperature.TemperatureHelper;
import toughasnails.core.ToughAsNails;
import toughasnails.init.ModConfig;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
Expand All @@ -26,13 +27,13 @@ public static void fill(Level level, BlockPos pos, PositionChecker checker)

public static void fill(Level level, BlockPos pos, PositionChecker checker, final int maxDepth)
{
Set<PosAndDepth> checked = Sets.newHashSet();
Queue<PosAndDepth> queue = new LinkedList();
Set<FillPos> checked = Sets.newHashSet();
Queue<FillPos> queue = new LinkedList();

queue.add(new PosAndDepth(pos, 1));
queue.add(new FillPos(pos, 1, Direction.DOWN));
while (!queue.isEmpty())
{
PosAndDepth posToCheck = queue.poll();
FillPos posToCheck = queue.poll();

// Skip already checked positions
if (checked.contains(posToCheck))
Expand All @@ -41,7 +42,7 @@ public static void fill(Level level, BlockPos pos, PositionChecker checker, fina
// Positive x is east, negative x is west
if (checkPassable(checker, level, posToCheck))
{
PosAndDepth westPos = posToCheck;
FillPos westPos = posToCheck;
while (westPos.depth() < maxDepth && checkPassable(checker, level, westPos))
{
checked.add(westPos);
Expand All @@ -56,7 +57,7 @@ public static void fill(Level level, BlockPos pos, PositionChecker checker, fina
if (posToCheck.depth() >= maxDepth)
continue;

PosAndDepth eastPos = posToCheck.east();
FillPos eastPos = posToCheck.east();
while (eastPos.depth() < maxDepth && checkPassable(checker, level, eastPos))
{
checked.add(eastPos);
Expand All @@ -74,12 +75,12 @@ public static void fill(Level level, BlockPos pos, PositionChecker checker, fina
}
}

private static void expand(Queue<PosAndDepth> queue, Set<PosAndDepth> checked, PositionChecker checker, Level level, PosAndDepth pos)
private static void expand(Queue<FillPos> queue, Set<FillPos> checked, PositionChecker checker, Level level, FillPos pos)
{
PosAndDepth north = pos.north(); // Negative Z
PosAndDepth south = pos.south(); // Positive Z
PosAndDepth down = pos.below(); // Negative Y
PosAndDepth up = pos.above(); // Positive Y
FillPos north = pos.north(); // Negative Z
FillPos south = pos.south(); // Positive Z
FillPos down = pos.below(); // Negative Y
FillPos up = pos.above(); // Positive Y

if (checkPassable(checker, level, north)) queue.add(north);
else checkSolid(checked, checker, level, north);
Expand All @@ -94,69 +95,72 @@ private static void expand(Queue<PosAndDepth> queue, Set<PosAndDepth> checked, P
else checkSolid(checked, checker, level, up);
}

private static void checkSolid(Set<PosAndDepth> checked, PositionChecker checker, Level level, PosAndDepth pos)
private static void checkSolid(Set<FillPos> checked, PositionChecker checker, Level level, FillPos pos)
{
checked.add(pos);
checker.onSolid(level, pos);
}

private static boolean checkPassable(PositionChecker checker, Level level, PosAndDepth pos)
private static boolean checkPassable(PositionChecker checker, Level level, FillPos pos)
{
BlockState state = level.getBlockState(pos.pos());
boolean passable = checker.isPassable(level, pos.pos());
boolean passable = checker.isPassable(level, pos);
if (passable) checker.onPassable(level, pos);
return passable;
}

public interface PositionChecker {
void onSolid(Level level, PosAndDepth pos);
void onSolid(Level level, FillPos pos);

default void onPassable(Level level, PosAndDepth pos) {
default void onPassable(Level level, FillPos pos) {
}

default boolean isPassable(Level level, BlockPos pos)
default boolean isPassable(Level level, FillPos pos)
{
BlockState state = level.getBlockState(pos);
return state.isAir() || (!isFullySolid(level, pos) && !TemperatureHelper.isHeatingBlock(state) && !TemperatureHelper.isCoolingBlock(state));
BlockState state = level.getBlockState(pos.pos());
return isConfined(level, pos.pos()) && (state.isAir() || (!isFlowBlocking(level, pos, state) && !TemperatureHelper.isHeatingBlock(state) && !TemperatureHelper.isCoolingBlock(state)));
}

default boolean isFullySolid(Level level, BlockPos pos)
default boolean isConfined(Level level, BlockPos pos)
{
BlockState state = level.getBlockState(pos);
return Arrays.stream(Direction.values()).allMatch(dir -> state.isFaceSturdy(level, pos, dir));
return pos.getY() < level.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, pos).below().getY();
}

default boolean isFlowBlocking(Level level, FillPos pos, BlockState state)
{
return state.isFaceSturdy(level, pos.pos(), pos.source()) || state.isFaceSturdy(level, pos.pos(), pos.source().getOpposite());
}
}

public record PosAndDepth(BlockPos pos, int depth)
public record FillPos(BlockPos pos, int depth, Direction source)
{
public PosAndDepth north()
public FillPos north()
{
return new PosAndDepth(pos().north(), depth() + 1);
return new FillPos(pos().north(), depth() + 1, Direction.SOUTH);
}

public PosAndDepth south()
public FillPos south()
{
return new PosAndDepth(pos().south(), depth() + 1);
return new FillPos(pos().south(), depth() + 1, Direction.NORTH);
}

public PosAndDepth east()
public FillPos east()
{
return new PosAndDepth(pos().east(), depth() + 1);
return new FillPos(pos().east(), depth() + 1, Direction.WEST);
}

public PosAndDepth west()
public FillPos west()
{
return new PosAndDepth(pos().west(), depth() + 1);
return new FillPos(pos().west(), depth() + 1, Direction.EAST);
}

public PosAndDepth above()
public FillPos above()
{
return new PosAndDepth(pos().above(), depth() + 1);
return new FillPos(pos().above(), depth() + 1, Direction.DOWN);
}

public PosAndDepth below()
public FillPos below()
{
return new PosAndDepth(pos().below(), depth() + 1);
return new FillPos(pos().below(), depth() + 1, Direction.UP);
}
}
}
3 changes: 3 additions & 0 deletions common/src/main/resources/toughasnails.accesswidener
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ accessible method net/minecraft/client/renderer/item/ItemProperties register (Ln
# Potion registration
accessible method net/minecraft/world/item/alchemy/PotionBrewing addMix (Lnet/minecraft/world/item/alchemy/Potion;Lnet/minecraft/world/item/Item;Lnet/minecraft/world/item/alchemy/Potion;)V

# Particle registration
accessible method net/minecraft/core/particles/SimpleParticleType <init> (Z)V

# Thirst
accessible field net/minecraft/world/food/FoodData foodLevel I
accessible field net/minecraft/world/food/FoodData saturationLevel F
Expand Down

0 comments on commit 9d997ea

Please sign in to comment.