Skip to content

Commit

Permalink
Refactor down movement and parkour registration code
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexProgrammerDE committed Dec 11, 2024
1 parent 8899889 commit 8dc852d
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@
import com.soulfiremc.server.pathfinding.graph.actions.movement.SkyDirection;
import com.soulfiremc.server.util.SFBlockHelpers;
import com.soulfiremc.server.util.structs.LazyBoolean;
import it.unimi.dsi.fastutil.Pair;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
Expand Down Expand Up @@ -60,92 +58,44 @@ public static void registerDownMovements(
private static DownMovement registerDownMovement(
SubscriptionConsumer blockSubscribers,
DownMovement movement) {
{
for (var safetyBlock : movement.listSafetyCheckBlocks()) {
blockSubscribers.subscribe(safetyBlock, new DownSafetyCheckSubscription());
}
}

{
for (var obstructingBlock : movement.listObstructFallCheckBlocks()) {
blockSubscribers.subscribe(obstructingBlock, new ObstructingFallCheckSubscription());
}
}

{
var freeBlock = movement.blockToBreak();
blockSubscribers.subscribe(freeBlock.key(), new MovementFreeSubscription(freeBlock.value()));
}

{
var safeBlocks = movement.listCheckSafeMineBlocks();
for (var savedBlock : safeBlocks) {
if (savedBlock == null) {
continue;
}

for (var block : savedBlock) {
blockSubscribers.subscribe(block.position(), new MovementBreakSafetyCheckSubscription(block.type()));
}
}
}
movement.registerSafetyCheckBlocks(blockSubscribers);
movement.registerObstructFallCheckBlocks(blockSubscribers);
movement.registerBlockToBreak(blockSubscribers);
movement.registerCheckSafeMineBlocks(blockSubscribers);

return movement;
}

public Pair<SFVec3i, BlockFace> blockToBreak() {
return Pair.of(targetToMineBlock, BlockFace.TOP);
public void registerBlockToBreak(SubscriptionConsumer blockSubscribers) {
blockSubscribers.subscribe(targetToMineBlock, new MovementFreeSubscription(BlockFace.TOP));
}

// These blocks are possibly safe blocks we can fall on top of
public List<SFVec3i> listSafetyCheckBlocks() {
var requiredFreeBlocks = new ArrayList<SFVec3i>();

public void registerSafetyCheckBlocks(SubscriptionConsumer blockSubscribers) {
// Falls one block
requiredFreeBlocks.add(FEET_POSITION_RELATIVE_BLOCK.sub(0, 2, 0));
blockSubscribers.subscribe(FEET_POSITION_RELATIVE_BLOCK.sub(0, 2, 0), DownSafetyCheckSubscription.INSTANCE);

// Falls two blocks
requiredFreeBlocks.add(FEET_POSITION_RELATIVE_BLOCK.sub(0, 3, 0));
blockSubscribers.subscribe(FEET_POSITION_RELATIVE_BLOCK.sub(0, 3, 0), DownSafetyCheckSubscription.INSTANCE);

// Falls three blocks
requiredFreeBlocks.add(FEET_POSITION_RELATIVE_BLOCK.sub(0, 4, 0));

return requiredFreeBlocks;
blockSubscribers.subscribe(FEET_POSITION_RELATIVE_BLOCK.sub(0, 4, 0), DownSafetyCheckSubscription.INSTANCE);
}

public List<SFVec3i> listObstructFallCheckBlocks() {
var requiredFreeBlocks = new ArrayList<SFVec3i>();

public void registerObstructFallCheckBlocks(SubscriptionConsumer blockSubscribers) {
// Block below the block we mine can obstruct a 2 block fall
requiredFreeBlocks.add(FEET_POSITION_RELATIVE_BLOCK.sub(0, 2, 0));
blockSubscribers.subscribe(FEET_POSITION_RELATIVE_BLOCK.sub(0, 2, 0), ObstructingFallCheckSubscription.INSTANCE);

// Block below the block we mine can obstruct a 3 block fall
requiredFreeBlocks.add(FEET_POSITION_RELATIVE_BLOCK.sub(0, 3, 0));

return requiredFreeBlocks;
blockSubscribers.subscribe(FEET_POSITION_RELATIVE_BLOCK.sub(0, 3, 0), ObstructingFallCheckSubscription.INSTANCE);
}

public BlockSafetyData[][] listCheckSafeMineBlocks() {
var results = new BlockSafetyData[1][];

var firstDirection = SkyDirection.NORTH;
var oppositeDirection = firstDirection.opposite();
var leftDirectionSide = firstDirection.leftSide();
var rightDirectionSide = firstDirection.rightSide();

results[0] =
new BlockSafetyData[]{
new BlockSafetyData(
firstDirection.offset(targetToMineBlock), BlockSafetyData.BlockSafetyType.FLUIDS),
new BlockSafetyData(
oppositeDirection.offset(targetToMineBlock), BlockSafetyData.BlockSafetyType.FLUIDS),
new BlockSafetyData(
leftDirectionSide.offset(targetToMineBlock), BlockSafetyData.BlockSafetyType.FLUIDS),
new BlockSafetyData(
rightDirectionSide.offset(targetToMineBlock), BlockSafetyData.BlockSafetyType.FLUIDS)
};

return results;
public void registerCheckSafeMineBlocks(SubscriptionConsumer blockSubscribers) {
for (var skyDirection : SkyDirection.VALUES) {
blockSubscribers.subscribe(
skyDirection.offset(targetToMineBlock),
new MovementBreakSafetyCheckSubscription(BlockSafetyData.BlockSafetyType.FLUIDS));
}
}

@Override
Expand Down Expand Up @@ -217,6 +167,8 @@ public MinecraftGraph.SubscriptionSingleResult processBlock(MinecraftGraph graph
}

record DownSafetyCheckSubscription() implements DownMovementSubscription {
private static final DownSafetyCheckSubscription INSTANCE = new DownSafetyCheckSubscription();

@Override
public MinecraftGraph.SubscriptionSingleResult processBlock(MinecraftGraph graph, SFVec3i key, DownMovement downMovement, LazyBoolean isFree,
BlockState blockState, SFVec3i absoluteKey) {
Expand Down Expand Up @@ -254,6 +206,8 @@ public MinecraftGraph.SubscriptionSingleResult processBlock(MinecraftGraph graph
}

record ObstructingFallCheckSubscription() implements DownMovementSubscription {
private static final ObstructingFallCheckSubscription INSTANCE = new ObstructingFallCheckSubscription();

@Override
public MinecraftGraph.SubscriptionSingleResult processBlock(MinecraftGraph graph, SFVec3i key, DownMovement downMovement, LazyBoolean isFree,
BlockState blockState, SFVec3i absoluteKey) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,12 @@
import com.soulfiremc.server.pathfinding.NodeState;
import com.soulfiremc.server.pathfinding.SFVec3i;
import com.soulfiremc.server.pathfinding.execution.GapJumpAction;
import com.soulfiremc.server.pathfinding.graph.BlockFace;
import com.soulfiremc.server.pathfinding.graph.GraphInstructions;
import com.soulfiremc.server.pathfinding.graph.MinecraftGraph;
import com.soulfiremc.server.pathfinding.graph.actions.movement.ParkourDirection;
import com.soulfiremc.server.util.SFBlockHelpers;
import com.soulfiremc.server.util.structs.LazyBoolean;
import it.unimi.dsi.fastutil.Pair;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
Expand Down Expand Up @@ -58,55 +55,40 @@ public static void registerParkourMovements(
private static ParkourMovement registerParkourMovement(
SubscriptionConsumer blockSubscribers,
ParkourMovement movement) {
{
for (var freeBlock : movement.listRequiredFreeBlocks()) {
blockSubscribers.subscribe(freeBlock.key(), new MovementFreeSubscription());
}
}

{
blockSubscribers.subscribe(movement.requiredUnsafeBlock(), new ParkourUnsafeToStandOnSubscription());
}

{
blockSubscribers.subscribe(movement.requiredSolidBlock(), new MovementSolidSubscription());
}
movement.registerRequiredFreeBlocks(blockSubscribers);
movement.registerRequiredUnsafeBlock(blockSubscribers);
movement.registerRequiredSolidBlock(blockSubscribers);

return movement;
}

public List<Pair<SFVec3i, BlockFace>> listRequiredFreeBlocks() {
var requiredFreeBlocks = new ArrayList<Pair<SFVec3i, BlockFace>>();

public void registerRequiredFreeBlocks(SubscriptionConsumer blockSubscribers) {
// Make block above the head block free for jump
requiredFreeBlocks.add(Pair.of(FEET_POSITION_RELATIVE_BLOCK.add(0, 2, 0), BlockFace.BOTTOM));
blockSubscribers.subscribe(FEET_POSITION_RELATIVE_BLOCK.add(0, 2, 0), MovementFreeSubscription.INSTANCE);

var oneFurther = direction.offset(FEET_POSITION_RELATIVE_BLOCK);
var blockDigDirection = direction.toSkyDirection().opposite().toBlockFace();

// Room for jumping
requiredFreeBlocks.add(Pair.of(oneFurther, blockDigDirection));
requiredFreeBlocks.add(Pair.of(oneFurther.add(0, 1, 0), blockDigDirection));
requiredFreeBlocks.add(Pair.of(oneFurther.add(0, 2, 0), blockDigDirection));
blockSubscribers.subscribe(oneFurther, MovementFreeSubscription.INSTANCE);
blockSubscribers.subscribe(oneFurther.add(0, 1, 0), MovementFreeSubscription.INSTANCE);
blockSubscribers.subscribe(oneFurther.add(0, 2, 0), MovementFreeSubscription.INSTANCE);

var twoFurther = direction.offset(oneFurther);

// Room for jumping
requiredFreeBlocks.add(Pair.of(twoFurther, blockDigDirection));
requiredFreeBlocks.add(Pair.of(twoFurther.add(0, 1, 0), blockDigDirection));
requiredFreeBlocks.add(Pair.of(twoFurther.add(0, 2, 0), blockDigDirection));

return requiredFreeBlocks;
blockSubscribers.subscribe(twoFurther, MovementFreeSubscription.INSTANCE);
blockSubscribers.subscribe(twoFurther.add(0, 1, 0), MovementFreeSubscription.INSTANCE);
blockSubscribers.subscribe(twoFurther.add(0, 2, 0), MovementFreeSubscription.INSTANCE);
}

public SFVec3i requiredUnsafeBlock() {
public void registerRequiredUnsafeBlock(SubscriptionConsumer blockSubscribers) {
// The gap to jump over, needs to be unsafe for this movement to be possible
return direction.offset(FEET_POSITION_RELATIVE_BLOCK).sub(0, 1, 0);
blockSubscribers.subscribe(direction.offset(FEET_POSITION_RELATIVE_BLOCK).sub(0, 1, 0), ParkourUnsafeToStandOnSubscription.INSTANCE);
}

public SFVec3i requiredSolidBlock() {
public void registerRequiredSolidBlock(SubscriptionConsumer blockSubscribers) {
// Floor block
return targetFeetBlock.sub(0, 1, 0);
blockSubscribers.subscribe(targetFeetBlock.sub(0, 1, 0), MovementSolidSubscription.INSTANCE);
}

@Override
Expand Down Expand Up @@ -141,6 +123,8 @@ default ParkourMovement castAction(GraphAction action) {
}

record MovementFreeSubscription() implements ParkourMovementSubscription {
private static final MovementFreeSubscription INSTANCE = new MovementFreeSubscription();

@Override
public MinecraftGraph.SubscriptionSingleResult processBlock(MinecraftGraph graph, SFVec3i key, ParkourMovement parkourMovement, LazyBoolean isFree,
BlockState blockState, SFVec3i absoluteKey) {
Expand All @@ -153,6 +137,8 @@ public MinecraftGraph.SubscriptionSingleResult processBlock(MinecraftGraph graph
}

record ParkourUnsafeToStandOnSubscription() implements ParkourMovementSubscription {
private static final ParkourUnsafeToStandOnSubscription INSTANCE = new ParkourUnsafeToStandOnSubscription();

@Override
public MinecraftGraph.SubscriptionSingleResult processBlock(MinecraftGraph graph, SFVec3i key, ParkourMovement parkourMovement, LazyBoolean isFree,
BlockState blockState, SFVec3i absoluteKey) {
Expand All @@ -168,6 +154,8 @@ public MinecraftGraph.SubscriptionSingleResult processBlock(MinecraftGraph graph
}

record MovementSolidSubscription() implements ParkourMovementSubscription {
private static final MovementSolidSubscription INSTANCE = new MovementSolidSubscription();

@Override
public MinecraftGraph.SubscriptionSingleResult processBlock(MinecraftGraph graph, SFVec3i key, ParkourMovement parkourMovement, LazyBoolean isFree,
BlockState blockState, SFVec3i absoluteKey) {
Expand Down

0 comments on commit 8dc852d

Please sign in to comment.