From bc9ecd798de34266356720be0eaeaa8f368cef1f Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 23 Feb 2021 18:08:50 +0200 Subject: [PATCH] Workaround for entity pathfinding in inverted gravity --- .../unicopia/entity/RotatedView.java | 32 +++++++++++++++++++ .../unicopia/mixin/MixinMobEntity.java | 16 ++++++++++ .../unicopia/mixin/MixinServerWorld.java | 1 + .../unicopia/mixin/MixinWorld.java | 23 ++++++++++++- .../unicopia/mixin/MixinWorldChunk.java | 30 +++++++++++++++++ 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/entity/RotatedView.java create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/MixinWorldChunk.java diff --git a/src/main/java/com/minelittlepony/unicopia/entity/RotatedView.java b/src/main/java/com/minelittlepony/unicopia/entity/RotatedView.java new file mode 100644 index 00000000..e2703bb0 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/RotatedView.java @@ -0,0 +1,32 @@ +package com.minelittlepony.unicopia.entity; + +import net.minecraft.util.math.BlockPos; + +public interface RotatedView { + + void setRotationCenter(int y, int increments); + + int getRotationY(); + + int getRotationIncrements(); + + default void clearRotation() { + setRotationCenter(0, 0); + } + + default BlockPos applyRotation(BlockPos pos) { + int newY = applyRotation(pos.getY()); + if (newY == pos.getY()) { + return pos; + } + return new BlockPos(pos.getX(), applyRotation(pos.getY()), pos.getZ()); + } + + default int applyRotation(int y) { + if (getRotationIncrements() == 0) { + return y; + } + return y - ((y - getRotationY()) * 2); + } + +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinMobEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinMobEntity.java index 23088e21..25fb8a63 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinMobEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinMobEntity.java @@ -8,7 +8,9 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minelittlepony.unicopia.entity.Creature; import com.minelittlepony.unicopia.entity.PonyContainer; +import com.minelittlepony.unicopia.entity.RotatedView; import com.minelittlepony.unicopia.entity.Equine; +import com.minelittlepony.unicopia.entity.Living; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; @@ -29,4 +31,18 @@ abstract class MixinMobEntity extends LivingEntity implements PonyContainer entityType, World world, CallbackInfo info) { ((Creature)get()).initAi(goalSelector, targetSelector); } + + @Inject(method = "tickNewAi", at = @At("HEAD")) + public void beforeTickAi(CallbackInfo into) { + Equine eq = Equine.of(this); + + if (eq instanceof Living && eq.getPhysics().isGravityNegative()) { + ((RotatedView)world).setRotationCenter((int)getY(), 1); + } + } + + @Inject(method = "tickNewAi", at = @At("RETURN")) + public void afterTickAi(CallbackInfo into) { + ((RotatedView)world).clearRotation(); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerWorld.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerWorld.java index 9a2ecf46..d6d12835 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerWorld.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinServerWorld.java @@ -6,6 +6,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.minelittlepony.unicopia.BlockDestructionManager; + import net.minecraft.block.BlockState; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java index dce1739f..4d5087f4 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java @@ -9,6 +9,7 @@ import javax.annotation.Nullable; import org.spongepowered.asm.mixin.Mixin; import com.minelittlepony.unicopia.BlockDestructionManager; +import com.minelittlepony.unicopia.entity.RotatedView; import com.minelittlepony.unicopia.entity.behaviour.Disguise; import net.minecraft.entity.Entity; @@ -18,10 +19,30 @@ import net.minecraft.world.World; import net.minecraft.world.WorldAccess; @Mixin(World.class) -abstract class MixinWorld implements WorldAccess, BlockDestructionManager.Source { +abstract class MixinWorld implements WorldAccess, BlockDestructionManager.Source, RotatedView { private final BlockDestructionManager destructions = new BlockDestructionManager((World)(Object)this); + private int rotationY; + private int rotationIncrements; + + @Override + public void setRotationCenter(int y, int increments) { + rotationY = y; + rotationIncrements = increments; + } + + @Override + public int getRotationY() { + return rotationY; + } + + @Override + public int getRotationIncrements() { + return rotationIncrements; + } + + @Override public BlockDestructionManager getDestructionManager() { return destructions; diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorldChunk.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorldChunk.java new file mode 100644 index 00000000..8fea9604 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorldChunk.java @@ -0,0 +1,30 @@ +package com.minelittlepony.unicopia.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +import com.minelittlepony.unicopia.entity.RotatedView; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.WorldChunk; + +@Mixin(WorldChunk.class) +abstract class MixinWorldChunk { + + @ModifyVariable(method = { + "getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;", + "setBlockState(Lnet/minecraft/util/math/BlockPos;)V", + "getBlockEntity(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/chunk/WorldChunk$CreationType;)Lnet/minecraft/block/entity/BlockEntity;", + "setBlockEntity(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/entity/BlockEntity;)V", + "removeBlockEntity(Lnet/minecraft/util/math/BlockPos;)V", + }, at = @At("HEAD")) + private BlockPos modifyBlockPos(BlockPos pos) { + return ((RotatedView)((WorldChunk)(Object)this).getWorld()).applyRotation(pos); + } + + @ModifyVariable(method = "getFluidState(III)Lnet/minecraft/fluid/FluidState;", at = @At("HEAD"), ordinal = 1) + private int modifyFluidPos(int y) { + return ((RotatedView)((WorldChunk)(Object)this).getWorld()).applyRotation(y); + } +}