From 04310126b70d409150f658a8232f4a95aa85b72e Mon Sep 17 00:00:00 2001 From: Floral <49110090+floral-qua-floral@users.noreply.github.com> Date: Sat, 30 Nov 2024 16:48:49 -0500 Subject: [PATCH] Preparing to move most Entity Mixins into PlayerEntityMixin --- .../com/floralquafloral/StompableEntity.java | 17 -- .../mixin/EntityStompabilityMixin.java | 45 ++++-- .../mixin/StompableEntity.java | 28 ++++ .../mariodata/MarioPlayerData.java | 1 + .../floralquafloral/mixin/EntityMixin.java | 148 ++++++++---------- .../mixin/PlayerEntityMixin.java | 58 ++++++- .../tags/damage_type/basic_stomps.json | 6 + mod/src/main/resources/qua_mario.mixins.json | 1 - 8 files changed, 193 insertions(+), 111 deletions(-) delete mode 100644 api/src/main/java/com/floralquafloral/StompableEntity.java create mode 100644 api/src/main/java/com/floralquafloral/mixin/StompableEntity.java create mode 100644 mod/src/main/resources/data/qua_mario/tags/damage_type/basic_stomps.json diff --git a/api/src/main/java/com/floralquafloral/StompableEntity.java b/api/src/main/java/com/floralquafloral/StompableEntity.java deleted file mode 100644 index cd5b9fd..0000000 --- a/api/src/main/java/com/floralquafloral/StompableEntity.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.floralquafloral; - -import net.minecraft.entity.damage.DamageSource; -import net.minecraft.util.Identifier; - -public interface StompableEntity { - StompResult qua_mario$stomp(Identifier stompType, DamageSource damageSource, float amount); - - enum StompResult { - NORMAL, - PAINFUL, - GLANCING, - RESISTED, - FAIL_IF_BASIC, - FAIL - } -} diff --git a/api/src/main/java/com/floralquafloral/mixin/EntityStompabilityMixin.java b/api/src/main/java/com/floralquafloral/mixin/EntityStompabilityMixin.java index 8215574..a80c808 100644 --- a/api/src/main/java/com/floralquafloral/mixin/EntityStompabilityMixin.java +++ b/api/src/main/java/com/floralquafloral/mixin/EntityStompabilityMixin.java @@ -1,25 +1,52 @@ package com.floralquafloral.mixin; -import com.floralquafloral.StompableEntity; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; -import net.minecraft.entity.MovementType; +import net.minecraft.entity.Saddleable; import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.damage.DamageType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.vehicle.AbstractMinecartEntity; +import net.minecraft.entity.vehicle.MinecartEntity; +import net.minecraft.entity.vehicle.VehicleEntity; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.tag.TagKey; import net.minecraft.util.Identifier; -import net.minecraft.util.math.Vec3d; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.Unique; +@SuppressWarnings("UnusedMixin") @Mixin(Entity.class) public abstract class EntityStompabilityMixin implements StompableEntity { @Shadow public abstract EntityType getType(); - @Override public StompResult qua_mario$stomp(Identifier stompType, DamageSource damageSource, float amount) { -// if(getType().isIn()) + @Shadow public abstract boolean damage(DamageSource source, float amount); - return StompResult.NORMAL; + @Unique private static final TagKey> UNSTOMPABLE_ENTITIES = + TagKey.of(RegistryKeys.ENTITY_TYPE, Identifier.of("qua_mario:unstompable")); + @Unique private static final TagKey> HURTS_TO_STOMP_ENTITIES = + TagKey.of(RegistryKeys.ENTITY_TYPE, Identifier.of("qua_mario:hurts_to_stomp")); + @Unique private static final TagKey> IMMUNE_TO_BASIC_STOMP_ENTITIES = + TagKey.of(RegistryKeys.ENTITY_TYPE, Identifier.of("qua_mario:immune_to_basic_stomp")); + + @Unique private static final TagKey BASIC_STOMPS = + TagKey.of(RegistryKeys.DAMAGE_TYPE, Identifier.of("qua_mario:basic_stomps")); + + @Override public StompResult qua_mario$stomp(PlayerEntity mario, Identifier stompType, DamageSource damageSource, float amount) { + Entity self = (Entity) (Object) this; + + if(self instanceof VehicleEntity || (self instanceof Saddleable saddleable && saddleable.isSaddled())) + if((!(self instanceof MinecartEntity minecart) || minecart.getMinecartType() == AbstractMinecartEntity.Type.RIDEABLE)) + if(mario.startRiding(self, false)) + return StompResult.MOUNT; + + if(getType().isIn(UNSTOMPABLE_ENTITIES)) return StompResult.FAIL; + if(getType().isIn(HURTS_TO_STOMP_ENTITIES)) return StompResult.PAINFUL; + if(getType().isIn(IMMUNE_TO_BASIC_STOMP_ENTITIES) && damageSource.isIn(BASIC_STOMPS)) return StompResult.FAIL; + + boolean damaged = damage(damageSource, amount); + if(damaged) return StompResult.NORMAL; + else return StompResult.FAIL; } } diff --git a/api/src/main/java/com/floralquafloral/mixin/StompableEntity.java b/api/src/main/java/com/floralquafloral/mixin/StompableEntity.java new file mode 100644 index 0000000..95a7b95 --- /dev/null +++ b/api/src/main/java/com/floralquafloral/mixin/StompableEntity.java @@ -0,0 +1,28 @@ +package com.floralquafloral.mixin; + +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.Identifier; + +public interface StompableEntity { + StompResult qua_mario$stomp(PlayerEntity mario, Identifier stompType, DamageSource damageSource, float amount); + + /** + * NORMAL - The Stomp behaves normally. Would be returned by a Goomba. + * PAINFUL - Trying to Stomp this entity hurts Mario. Would be returned by a Spiny or a Piranha Plant. + * GLANCING - Used internally. Returning this is not recommended. + * RESISTED - Mario bounces off this entity without hurting it. Would be returned by a Wiggler after the first time it's been stomped. + * FAIL_IF_BASIC - Mario passes through the entity unless he's Ground Pounding. Would be returned by a Blockhopper (look it up). + * FAIL - Mario can't stomp this entity. Would be returned by a Boo. + * MOUNT - Trying to Stomp this entity instead Mounts it. Would be returned by Yoshi. + */ + enum StompResult { + NORMAL, + PAINFUL, + GLANCING, + RESISTED, + FAIL_IF_BASIC, + FAIL, + MOUNT + } +} diff --git a/mod/src/main/java/com/floralquafloral/mariodata/MarioPlayerData.java b/mod/src/main/java/com/floralquafloral/mariodata/MarioPlayerData.java index 987799c..6a36afa 100644 --- a/mod/src/main/java/com/floralquafloral/mariodata/MarioPlayerData.java +++ b/mod/src/main/java/com/floralquafloral/mariodata/MarioPlayerData.java @@ -67,6 +67,7 @@ public MarioPlayerData(PlayerEntity mario) { isEnabled() && !this.mario.getAbilities().flying && !this.mario.isFallFlying() + && !this.mario.isUsingRiptide() // && !mario.hasVehicle() // && !mario.isClimbing() ); diff --git a/mod/src/main/java/com/floralquafloral/mixin/EntityMixin.java b/mod/src/main/java/com/floralquafloral/mixin/EntityMixin.java index 754ff42..ddbd72f 100644 --- a/mod/src/main/java/com/floralquafloral/mixin/EntityMixin.java +++ b/mod/src/main/java/com/floralquafloral/mixin/EntityMixin.java @@ -1,7 +1,6 @@ package com.floralquafloral.mixin; import com.floralquafloral.MarioQuaMario; -import com.floralquafloral.StompableEntity; import com.floralquafloral.mariodata.MarioDataManager; import com.floralquafloral.mariodata.MarioPlayerData; import com.floralquafloral.mariodata.moveable.MarioMainClientData; @@ -13,13 +12,11 @@ import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.llamalad7.mixinextras.sugar.Local; import net.minecraft.block.BlockState; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityPose; import net.minecraft.entity.MovementType; -import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtElement; @@ -47,14 +44,6 @@ @Mixin(Entity.class) public class EntityMixin { - @Inject(at = @At("HEAD"), method = "setSwimming(Z)V", cancellable = true) - private void setSwimming(boolean swimming, CallbackInfo ci) { - Entity entity = (Entity) (Object) this; - if(swimming && entity instanceof PlayerEntity player && MarioDataManager.getMarioData(player).isEnabled()) { - ci.cancel(); - } - } - @Inject(at = @At("HEAD"), method = "isInSneakingPose", cancellable = true) private void isInSneakingPose(CallbackInfoReturnable cir) { if((Entity) (Object) this instanceof PlayerEntity player) { @@ -66,7 +55,6 @@ private void isInSneakingPose(CallbackInfoReturnable cir) { @Inject(method = "setPose", at = @At("HEAD"), cancellable = true) private void preventSettingSneakPose(EntityPose pose, CallbackInfo ci) { if((Entity) (Object) this instanceof PlayerEntity player && pose == EntityPose.CROUCHING) { -// MarioQuaMario.LOGGER.info("setPose called on player! Pose == {}", pose); if(MarioDataManager.getMarioData(player).isSneakProhibited()) { if(player.getPose() == EntityPose.CROUCHING) @@ -136,74 +124,74 @@ private void executeStompsOnServer(MovementType movementType, Vec3d movement, Ca } } - @WrapOperation(method = "findCollisionsForMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getBlockCollisions(Lnet/minecraft/entity/Entity;Lnet/minecraft/util/math/Box;)Ljava/lang/Iterable;")) - private static Iterable bumpBlocksOnCollision(World world, Entity entity, Box movingEntityBoundingBox, Operation> original) { - // This doesn't work! Fix it! - if(false && entity instanceof ClientPlayerEntity) { - MarioMainClientData data = MarioMainClientData.getInstance(); - if(data != null) { - Vec3d marioImmutableVelocity = data.getMario().getVelocity(); // is this adequate? - Vector3d marioVelocity = new Vector3d(marioImmutableVelocity.x, marioImmutableVelocity.y, marioImmutableVelocity.z); - - boolean bumpCeilings = true || marioVelocity.y != 0 && data.getAction().BUMPING_RULE.CEILINGS != 0; - boolean bumpFloors = true || marioVelocity.y != 0 && data.getAction().BUMPING_RULE.FLOORS != 0; - boolean bumpWalls = true || (marioVelocity.x != 0 || marioVelocity.z != 0) && data.getAction().BUMPING_RULE.WALLS != 0; - Iterable> blockCollisions = - () -> new BlockCollisionSpliterator<>(world, entity, movingEntityBoundingBox, false, (pos, voxelShape) -> new Pair<>(pos, voxelShape)); - - EnumMap> bumpBlocks = new EnumMap<>(Direction.class); - for(Direction direction : Direction.values()) { - bumpBlocks.put(direction, new HashSet<>()); - } - - Box marioBoundingBox = entity.getBoundingBox(); - - for(Pair collidedBlock : blockCollisions) { - if((bumpCeilings || bumpFloors) && collidedBlock.getRight().calculateMaxDistance(Direction.Axis.Y, marioBoundingBox, marioVelocity.y) != 0) { - if(bumpCeilings && marioVelocity.y > 0) { - // Mario was moving up and bumped this block on the Y axis! - bumpBlocks.get(Direction.UP).add(collidedBlock.getLeft().toImmutable()); - } - else if(bumpFloors && marioVelocity.y < 0) { - // Mario was moving down and bumped this block on the Y axis! - bumpBlocks.get(Direction.DOWN).add(collidedBlock.getLeft().toImmutable()); - } - } - else if(bumpWalls) { - boolean xAxisFirst = Math.abs(marioVelocity.x) > Math.abs(marioVelocity.z); - if(xAxisFirst && collidedBlock.getRight().calculateMaxDistance(Direction.Axis.X, marioBoundingBox, marioVelocity.x) != 0) { - MarioQuaMario.LOGGER.info("Collided along X axis: {}", collidedBlock.getRight().calculateMaxDistance(Direction.Axis.X, marioBoundingBox, marioVelocity.x)); - if(marioVelocity.x > 0) - bumpBlocks.get(Direction.EAST).add(collidedBlock.getLeft().toImmutable()); - else - bumpBlocks.get(Direction.WEST).add(collidedBlock.getLeft().toImmutable()); - } - else if(collidedBlock.getRight().calculateMaxDistance(Direction.Axis.Z, marioBoundingBox, marioVelocity.z) != 0) { - if(marioVelocity.z > 0) - bumpBlocks.get(Direction.SOUTH).add(collidedBlock.getLeft().toImmutable()); - else - bumpBlocks.get(Direction.NORTH).add(collidedBlock.getLeft().toImmutable()); - } - else if(!xAxisFirst && collidedBlock.getRight().calculateMaxDistance(Direction.Axis.X, marioBoundingBox, marioVelocity.x) != 0) { - MarioQuaMario.LOGGER.info("Collided along X axis: {}", collidedBlock.getRight().calculateMaxDistance(Direction.Axis.X, marioBoundingBox, marioVelocity.x)); - if(marioVelocity.x > 0) - bumpBlocks.get(Direction.EAST).add(collidedBlock.getLeft().toImmutable()); - else - bumpBlocks.get(Direction.WEST).add(collidedBlock.getLeft().toImmutable()); - } - } - } - - for(Direction direction : Direction.values()) { - Set bumpBlocksInThisDirection = bumpBlocks.get(direction); - if(!bumpBlocksInThisDirection.isEmpty()) - MarioQuaMario.LOGGER.info("BUMP {}:\t{}\t{}", direction.getName(), bumpBlocksInThisDirection.size(), bumpBlocksInThisDirection); - } - } - } - - return original.call(world, entity, movingEntityBoundingBox); - } +// @WrapOperation(method = "findCollisionsForMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getBlockCollisions(Lnet/minecraft/entity/Entity;Lnet/minecraft/util/math/Box;)Ljava/lang/Iterable;")) +// private static Iterable bumpBlocksOnCollision(World world, Entity entity, Box movingEntityBoundingBox, Operation> original) { +// // This doesn't work! Fix it! +// if(false && entity instanceof ClientPlayerEntity) { +// MarioMainClientData data = MarioMainClientData.getInstance(); +// if(data != null) { +// Vec3d marioImmutableVelocity = data.getMario().getVelocity(); // is this adequate? +// Vector3d marioVelocity = new Vector3d(marioImmutableVelocity.x, marioImmutableVelocity.y, marioImmutableVelocity.z); +// +// boolean bumpCeilings = true || marioVelocity.y != 0 && data.getAction().BUMPING_RULE.CEILINGS != 0; +// boolean bumpFloors = true || marioVelocity.y != 0 && data.getAction().BUMPING_RULE.FLOORS != 0; +// boolean bumpWalls = true || (marioVelocity.x != 0 || marioVelocity.z != 0) && data.getAction().BUMPING_RULE.WALLS != 0; +// Iterable> blockCollisions = +// () -> new BlockCollisionSpliterator<>(world, entity, movingEntityBoundingBox, false, (pos, voxelShape) -> new Pair<>(pos, voxelShape)); +// +// EnumMap> bumpBlocks = new EnumMap<>(Direction.class); +// for(Direction direction : Direction.values()) { +// bumpBlocks.put(direction, new HashSet<>()); +// } +// +// Box marioBoundingBox = entity.getBoundingBox(); +// +// for(Pair collidedBlock : blockCollisions) { +// if((bumpCeilings || bumpFloors) && collidedBlock.getRight().calculateMaxDistance(Direction.Axis.Y, marioBoundingBox, marioVelocity.y) != 0) { +// if(bumpCeilings && marioVelocity.y > 0) { +// // Mario was moving up and bumped this block on the Y axis! +// bumpBlocks.get(Direction.UP).add(collidedBlock.getLeft().toImmutable()); +// } +// else if(bumpFloors && marioVelocity.y < 0) { +// // Mario was moving down and bumped this block on the Y axis! +// bumpBlocks.get(Direction.DOWN).add(collidedBlock.getLeft().toImmutable()); +// } +// } +// else if(bumpWalls) { +// boolean xAxisFirst = Math.abs(marioVelocity.x) > Math.abs(marioVelocity.z); +// if(xAxisFirst && collidedBlock.getRight().calculateMaxDistance(Direction.Axis.X, marioBoundingBox, marioVelocity.x) != 0) { +// MarioQuaMario.LOGGER.info("Collided along X axis: {}", collidedBlock.getRight().calculateMaxDistance(Direction.Axis.X, marioBoundingBox, marioVelocity.x)); +// if(marioVelocity.x > 0) +// bumpBlocks.get(Direction.EAST).add(collidedBlock.getLeft().toImmutable()); +// else +// bumpBlocks.get(Direction.WEST).add(collidedBlock.getLeft().toImmutable()); +// } +// else if(collidedBlock.getRight().calculateMaxDistance(Direction.Axis.Z, marioBoundingBox, marioVelocity.z) != 0) { +// if(marioVelocity.z > 0) +// bumpBlocks.get(Direction.SOUTH).add(collidedBlock.getLeft().toImmutable()); +// else +// bumpBlocks.get(Direction.NORTH).add(collidedBlock.getLeft().toImmutable()); +// } +// else if(!xAxisFirst && collidedBlock.getRight().calculateMaxDistance(Direction.Axis.X, marioBoundingBox, marioVelocity.x) != 0) { +// MarioQuaMario.LOGGER.info("Collided along X axis: {}", collidedBlock.getRight().calculateMaxDistance(Direction.Axis.X, marioBoundingBox, marioVelocity.x)); +// if(marioVelocity.x > 0) +// bumpBlocks.get(Direction.EAST).add(collidedBlock.getLeft().toImmutable()); +// else +// bumpBlocks.get(Direction.WEST).add(collidedBlock.getLeft().toImmutable()); +// } +// } +// } +// +// for(Direction direction : Direction.values()) { +// Set bumpBlocksInThisDirection = bumpBlocks.get(direction); +// if(!bumpBlocksInThisDirection.isEmpty()) +// MarioQuaMario.LOGGER.info("BUMP {}:\t{}\t{}", direction.getName(), bumpBlocksInThisDirection.size(), bumpBlocksInThisDirection); +// } +// } +// } +// +// return original.call(world, entity, movingEntityBoundingBox); +// } // @WrapOperation(method = "checkBlockCollision", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;onEntityCollision(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/Entity;)V")) // private void executeBumpsOnClient(BlockState instance, World world, BlockPos blockPos, Entity entity, Operation original) { diff --git a/mod/src/main/java/com/floralquafloral/mixin/PlayerEntityMixin.java b/mod/src/main/java/com/floralquafloral/mixin/PlayerEntityMixin.java index 1dc3134..01f4c5d 100644 --- a/mod/src/main/java/com/floralquafloral/mixin/PlayerEntityMixin.java +++ b/mod/src/main/java/com/floralquafloral/mixin/PlayerEntityMixin.java @@ -6,11 +6,13 @@ import com.floralquafloral.registries.states.character.ParsedCharacter; import com.floralquafloral.registries.states.powerup.ParsedPowerUp; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; -import net.minecraft.entity.EntityDimensions; -import net.minecraft.entity.EntityPose; -import net.minecraft.entity.LivingEntity; +import net.minecraft.block.BlockState; +import net.minecraft.entity.*; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -19,11 +21,57 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(PlayerEntity.class) -public abstract class PlayerEntityMixin { +public abstract class PlayerEntityMixin extends LivingEntity { + private PlayerEntityMixin(EntityType entityType, World world) { + super(entityType, world); + } + @Shadow public float strideDistance; @Shadow public float prevStrideDistance; + @Override public void setSwimming(boolean swimming) { + if(swimming && MarioDataManager.getMarioData(this).isEnabled()) return; + super.setSwimming(swimming); + } + + @Override + public boolean isInSneakingPose() { + return super.isInSneakingPose(); + } + + @Override + public void setPose(EntityPose pose) { + super.setPose(pose); + } + + @Override + protected void playStepSound(BlockPos pos, BlockState state) { + super.playStepSound(pos, state); + } + + @Override + public void move(MovementType movementType, Vec3d movement) { + super.move(movementType, movement); + } + + @Override + public boolean startRiding(Entity entity, boolean force) { + boolean startedRiding = super.startRiding(entity, force); + + return startedRiding; + } + + @Override + public void readNbt(NbtCompound nbt) { + super.readNbt(nbt); + } + + @Override + public NbtCompound writeNbt(NbtCompound nbt) { + return super.writeNbt(nbt); + } + @Inject(method = "travel", at = @At("HEAD"), cancellable = true) private void travelHook(Vec3d movementInput, CallbackInfo ci) { MarioPlayerData data = MarioDataManager.getMarioData(this); @@ -102,4 +150,6 @@ public void changeDismounting(CallbackInfoReturnable cir) { private boolean preventLivingEntityJump(LivingEntity instance) { return !MarioDataManager.getMarioData(this).useMarioPhysics(); } + + } diff --git a/mod/src/main/resources/data/qua_mario/tags/damage_type/basic_stomps.json b/mod/src/main/resources/data/qua_mario/tags/damage_type/basic_stomps.json new file mode 100644 index 0000000..7344655 --- /dev/null +++ b/mod/src/main/resources/data/qua_mario/tags/damage_type/basic_stomps.json @@ -0,0 +1,6 @@ +{ + "values": [ + "qua_mario:stomp", + "qua_mario:spin_jump" + ] +} \ No newline at end of file diff --git a/mod/src/main/resources/qua_mario.mixins.json b/mod/src/main/resources/qua_mario.mixins.json index 37c8f5b..6d2a4a9 100644 --- a/mod/src/main/resources/qua_mario.mixins.json +++ b/mod/src/main/resources/qua_mario.mixins.json @@ -5,7 +5,6 @@ "mixins": [ "DamageSourceMixin", "EntityMixin", - "EntityStompabilityMixin", "LivingEntityMixin", "PlayerEntityMixin", "RedstoneViewMixin"