From 4f4ac3f8095082a56153c3d29f4c34dbd14eea9c Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 25 Sep 2024 20:34:53 +0100 Subject: [PATCH] Mobs with feather falling 4 boots can now walk and pathfind on clouds --- .../unicopia/InteractionManager.java | 17 +++++++++--- .../unicopia/block/cloud/CloudBedBlock.java | 2 +- .../unicopia/block/cloud/CloudBlock.java | 4 ++- .../unicopia/block/cloud/CloudChestBlock.java | 3 ++- .../unicopia/block/cloud/CloudDoorBlock.java | 8 ++++++ .../block/cloud/CloudStairsBlock.java | 2 +- .../mixin/server/MixinPathNodeMaker.java | 26 +++++++++++++++++++ .../mixin/server/MixinPlayerManager.java | 2 +- src/main/resources/unicopia.mixin.json | 1 + 9 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/server/MixinPathNodeMaker.java diff --git a/src/main/java/com/minelittlepony/unicopia/InteractionManager.java b/src/main/java/com/minelittlepony/unicopia/InteractionManager.java index 5326ce75..b3fb38b8 100644 --- a/src/main/java/com/minelittlepony/unicopia/InteractionManager.java +++ b/src/main/java/com/minelittlepony/unicopia/InteractionManager.java @@ -2,6 +2,7 @@ package com.minelittlepony.unicopia; import java.util.Map; import java.util.Optional; +import java.util.Stack; import java.util.UUID; import org.jetbrains.annotations.NotNull; @@ -37,7 +38,7 @@ public class InteractionManager { @Nullable private SyncedConfig config; - private EquineContext equineContext = EquineContext.ABSENT; + private final Stack equineContext = new Stack<>(); public static InteractionManager getInstance() { return INSTANCE; @@ -109,11 +110,21 @@ public class InteractionManager { } public void setEquineContext(EquineContext context) { - equineContext = context; + equineContext.push(context); + } + + public void clearEquineContext() { + if (!equineContext.isEmpty()) { + equineContext.pop(); + } } public EquineContext getEquineContext() { - return getClientPony().map(EquineContext.class::cast).orElse(equineContext); + return getClientPony().map(EquineContext.class::cast).orElseGet(this::getPathingEquineContext); + } + + public EquineContext getPathingEquineContext() { + return equineContext.isEmpty() ? EquineContext.ABSENT : equineContext.peek(); } public Optional getClientPony() { diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBedBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBedBlock.java index 5b8f1c69..e4d562c3 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBedBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBedBlock.java @@ -75,6 +75,6 @@ public class CloudBedBlock extends FancyBedBlock implements CloudLike { @Override @Deprecated public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) { - return true; + return baseState.canPathfindThrough(world, pos, type); } } diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java index 23e0e3f8..6381eda2 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudBlock.java @@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.block.cloud; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.EquineContext; +import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.entity.player.Pony; import net.minecraft.block.Block; @@ -173,7 +174,8 @@ public class CloudBlock extends Block implements CloudLike { @Override @Deprecated public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) { - return true; + System.out.println(InteractionManager.getInstance().getPathingEquineContext().collidesWithClouds()); + return type != NavigationType.LAND || !InteractionManager.getInstance().getPathingEquineContext().collidesWithClouds(); } protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context, EquineContext equineContext) { diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudChestBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudChestBlock.java index 49708712..7d53232c 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudChestBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudChestBlock.java @@ -5,6 +5,7 @@ import java.util.Optional; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.EquineContext; +import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.block.UBlockEntities; import net.minecraft.block.BlockState; import net.minecraft.block.ChestBlock; @@ -139,7 +140,7 @@ public class CloudChestBlock extends ChestBlock implements CloudLike { @Override @Deprecated public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) { - return true; + return type != NavigationType.LAND || !InteractionManager.getInstance().getPathingEquineContext().collidesWithClouds(); } public static class TileData extends ChestBlockEntity { diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudDoorBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudDoorBlock.java index 0e22e7ea..b243a67f 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudDoorBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudDoorBlock.java @@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.block.cloud; import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.EquineContext; +import com.minelittlepony.unicopia.InteractionManager; import com.minelittlepony.unicopia.Race; import net.minecraft.block.BlockSetType; @@ -10,6 +11,7 @@ import net.minecraft.block.BlockState; import net.minecraft.block.DoorBlock; import net.minecraft.block.ShapeContext; import net.minecraft.entity.Entity; +import net.minecraft.entity.ai.pathing.NavigationType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemPlacementContext; import net.minecraft.util.ActionResult; @@ -84,4 +86,10 @@ public class CloudDoorBlock extends DoorBlock implements CloudLike { entity.setVelocity(entity.getVelocity().multiply(0.5F, 1, 0.5F)); } } + + @Override + @Deprecated + public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) { + return !InteractionManager.getInstance().getPathingEquineContext().collidesWithClouds() || super.canPathfindThrough(state, world, pos, type); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudStairsBlock.java b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudStairsBlock.java index 5292dd2d..dcff5ff1 100644 --- a/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudStairsBlock.java +++ b/src/main/java/com/minelittlepony/unicopia/block/cloud/CloudStairsBlock.java @@ -97,6 +97,6 @@ public class CloudStairsBlock extends StairsBlock implements CloudLike { @Override @Deprecated public boolean canPathfindThrough(BlockState state, BlockView world, BlockPos pos, NavigationType type) { - return true; + return baseBlock.canPathfindThrough(state, world, pos, type); } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/server/MixinPathNodeMaker.java b/src/main/java/com/minelittlepony/unicopia/mixin/server/MixinPathNodeMaker.java new file mode 100644 index 00000000..9e18310c --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/server/MixinPathNodeMaker.java @@ -0,0 +1,26 @@ +package com.minelittlepony.unicopia.mixin.server; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.minelittlepony.unicopia.EquineContext; +import com.minelittlepony.unicopia.InteractionManager; + +import net.minecraft.entity.ai.pathing.PathNodeMaker; +import net.minecraft.entity.mob.MobEntity; +import net.minecraft.world.chunk.ChunkCache; + +@Mixin(PathNodeMaker.class) +abstract class MixinPathNodeMaker { + @Inject(method = "init", at = @At("HEAD")) + private void onInit(ChunkCache cachedWorld, MobEntity entity, CallbackInfo info) { + InteractionManager.getInstance().setEquineContext(EquineContext.of(entity)); + } + + @Inject(method = "clear", at = @At("HEAD")) + private void onClear(CallbackInfo info) { + InteractionManager.getInstance().clearEquineContext(); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/server/MixinPlayerManager.java b/src/main/java/com/minelittlepony/unicopia/mixin/server/MixinPlayerManager.java index 0c845c1c..271bf40a 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/server/MixinPlayerManager.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/server/MixinPlayerManager.java @@ -44,6 +44,6 @@ abstract class MixinPlayerManager { @Inject(method = "respawnPlayer", at = @At("RETURN")) private void afterRespawnPlayer(ServerPlayerEntity player, boolean alive, CallbackInfoReturnable info) { - InteractionManager.getInstance().setEquineContext(EquineContext.ABSENT); + InteractionManager.getInstance().clearEquineContext(); } } diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index 3079ef57..533483c0 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -54,6 +54,7 @@ "MixinWorld", "PointOfInterestTypesAccessor", "server.MixinEntityTrackerEntry", + "server.MixinPathNodeMaker", "server.MixinPlayerManager", "server.MixinServerPlayerEntity", "server.MixinServerPlayNetworkHandler",