From bd74a03b8bdc96c200098c22eea2295044e3657e Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 23 Feb 2021 23:49:14 +0200 Subject: [PATCH] More AI fixes for inverted entities --- .../unicopia/entity/RotatedView.java | 22 +++++++---- .../unicopia/mixin/MixinBrain.java | 31 +++++++++++++++ .../unicopia/mixin/MixinMobEntity.java | 4 +- .../unicopia/mixin/MixinWorld.java | 38 ++++++++++++------- .../unicopia/mixin/MixinWorldChunk.java | 2 +- src/main/resources/unicopia.mixin.json | 1 + 6 files changed, 74 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/MixinBrain.java diff --git a/src/main/java/com/minelittlepony/unicopia/entity/RotatedView.java b/src/main/java/com/minelittlepony/unicopia/entity/RotatedView.java index e2703bb0..dc7c0f69 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/RotatedView.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/RotatedView.java @@ -1,17 +1,23 @@ package com.minelittlepony.unicopia.entity; +import java.util.Stack; + import net.minecraft.util.math.BlockPos; public interface RotatedView { - void setRotationCenter(int y, int increments); + Stack getRotations(); - int getRotationY(); + boolean hasTransform(); - int getRotationIncrements(); + default void pushRotation(int y) { + getRotations().add(y); + } - default void clearRotation() { - setRotationCenter(0, 0); + default void popRotation() { + if (!getRotations().isEmpty()) { + getRotations().pop(); + } } default BlockPos applyRotation(BlockPos pos) { @@ -19,14 +25,14 @@ public interface RotatedView { if (newY == pos.getY()) { return pos; } - return new BlockPos(pos.getX(), applyRotation(pos.getY()), pos.getZ()); + return new BlockPos(pos.getX(), newY, pos.getZ()); } default int applyRotation(int y) { - if (getRotationIncrements() == 0) { + if (!hasTransform() || getRotations().isEmpty()) { return y; } - return y - ((y - getRotationY()) * 2); + return y - ((y - getRotations().peek()) * 2); } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinBrain.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinBrain.java new file mode 100644 index 00000000..a8a92c94 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinBrain.java @@ -0,0 +1,31 @@ +package com.minelittlepony.unicopia.mixin; + +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.entity.RotatedView; +import com.minelittlepony.unicopia.entity.Equine; +import com.minelittlepony.unicopia.entity.Living; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.brain.Brain; +import net.minecraft.server.world.ServerWorld; + +@Mixin(Brain.class) +abstract class MixinBrain { + + @Inject(method = "tick", at = @At("HEAD")) + public void beforeTickAi(ServerWorld world, E entity, CallbackInfo into) { + Equine eq = Equine.of(entity); + + if (eq instanceof Living && eq.getPhysics().isGravityNegative()) { + ((RotatedView)world).pushRotation((int)entity.getY()); + } + } + + @Inject(method = "tick", at = @At("RETURN")) + public void afterTickAi(ServerWorld world, E entity, CallbackInfo into) { + ((RotatedView)world).popRotation(); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinMobEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinMobEntity.java index 25fb8a63..6f2c947d 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinMobEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinMobEntity.java @@ -37,12 +37,12 @@ abstract class MixinMobEntity extends LivingEntity implements PonyContainer eq = Equine.of(this); if (eq instanceof Living && eq.getPhysics().isGravityNegative()) { - ((RotatedView)world).setRotationCenter((int)getY(), 1); + ((RotatedView)world).pushRotation((int)getY()); } } @Inject(method = "tickNewAi", at = @At("RETURN")) public void afterTickAi(CallbackInfo into) { - ((RotatedView)world).clearRotation(); + ((RotatedView)world).popRotation(); } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java index 4d5087f4..b43f55ea 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorld.java @@ -1,18 +1,25 @@ package com.minelittlepony.unicopia.mixin; import java.util.List; +import java.util.Stack; import java.util.function.Predicate; import java.util.stream.Stream; import javax.annotation.Nullable; 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.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.minelittlepony.unicopia.BlockDestructionManager; import com.minelittlepony.unicopia.entity.RotatedView; import com.minelittlepony.unicopia.entity.behaviour.Disguise; +import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import net.minecraft.util.shape.VoxelShape; import net.minecraft.world.World; @@ -23,26 +30,19 @@ abstract class MixinWorld implements WorldAccess, BlockDestructionManager.Source private final BlockDestructionManager destructions = new BlockDestructionManager((World)(Object)this); - private int rotationY; - private int rotationIncrements; + private int recurseCount = 0; + private Stack rotations = new Stack<>(); @Override - public void setRotationCenter(int y, int increments) { - rotationY = y; - rotationIncrements = increments; + public Stack getRotations() { + return rotations; } @Override - public int getRotationY() { - return rotationY; + public boolean hasTransform() { + return recurseCount <= 0; } - @Override - public int getRotationIncrements() { - return rotationIncrements; - } - - @Override public BlockDestructionManager getDestructionManager() { return destructions; @@ -59,4 +59,16 @@ abstract class MixinWorld implements WorldAccess, BlockDestructionManager.Source return WorldAccess.super.getEntityCollisions(entity, box, predicate); } + + @ModifyVariable(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;II)Z", at = @At("HEAD")) + private BlockPos modifyBlockPos(BlockPos pos) { + pos = applyRotation(pos); + recurseCount = Math.max(0, recurseCount) + 1; + return pos; + } + + @Inject(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;II)Z", at = @At("RETURN")) + public void onSetBlockState(BlockPos pos, BlockState state, int flags, int maxUpdateDepth, CallbackInfoReturnable info) { + recurseCount = Math.max(0, recurseCount - 1); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorldChunk.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorldChunk.java index 8fea9604..db443eae 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorldChunk.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinWorldChunk.java @@ -14,7 +14,7 @@ abstract class MixinWorldChunk { @ModifyVariable(method = { "getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;", - "setBlockState(Lnet/minecraft/util/math/BlockPos;)V", + "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;Z)Lnet/minecraft/block/BlockState;", "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", diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index 5378d41b..7cfbfd9d 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -7,6 +7,7 @@ "mixins": [ "MixinBlockEntity", "MixinBlockItem", + "MixinBrain", "MixinFallingBlock", "MixinItem", "MixinItemEntity",