Skip to content

Commit

Permalink
Moved most of EntityMixin to PlayerEntityMixin; moved Stomping to new…
Browse files Browse the repository at this point in the history
… ServerPlayerEntityMixin. Working on Interface Injection.
  • Loading branch information
floral-qua-floral committed Nov 30, 2024
1 parent 0431012 commit 8915398
Show file tree
Hide file tree
Showing 13 changed files with 181 additions and 113 deletions.
10 changes: 9 additions & 1 deletion api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
id 'maven-publish'
}

version = '1.0.0' // API version
version = project.api_version
group = project.maven_group

dependencies {
Expand All @@ -13,6 +13,14 @@ dependencies {
modCompileOnly "net.fabricmc:fabric-loader:${project.loader_version}"
}

processResources {
inputs.property "version", project.api_version

filesMatching("fabric.mod.json") {
expand "version": project.api_version
}
}

publishing {
publications {
mavenJava(MavenPublication) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.floralquafloral.mixin;
package com.floralquafloral;

import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerEntity;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.floralquafloral.mixin;

import com.floralquafloral.StompableEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.Saddleable;
Expand All @@ -16,23 +17,8 @@
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;

@SuppressWarnings("UnusedMixin")
@Mixin(Entity.class)
public abstract class EntityStompabilityMixin implements StompableEntity {
@Shadow public abstract EntityType<?> getType();

@Shadow public abstract boolean damage(DamageSource source, float amount);

@Unique private static final TagKey<EntityType<?>> UNSTOMPABLE_ENTITIES =
TagKey.of(RegistryKeys.ENTITY_TYPE, Identifier.of("qua_mario:unstompable"));
@Unique private static final TagKey<EntityType<?>> HURTS_TO_STOMP_ENTITIES =
TagKey.of(RegistryKeys.ENTITY_TYPE, Identifier.of("qua_mario:hurts_to_stomp"));
@Unique private static final TagKey<EntityType<?>> IMMUNE_TO_BASIC_STOMP_ENTITIES =
TagKey.of(RegistryKeys.ENTITY_TYPE, Identifier.of("qua_mario:immune_to_basic_stomp"));

@Unique private static final TagKey<DamageType> 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;

Expand All @@ -46,7 +32,21 @@ public abstract class EntityStompabilityMixin implements StompableEntity {
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;
}

@Shadow public abstract EntityType<?> getType();
@Shadow public abstract boolean damage(DamageSource source, float amount);

@Unique private static final TagKey<EntityType<?>> UNSTOMPABLE_ENTITIES =
TagKey.of(RegistryKeys.ENTITY_TYPE, Identifier.of("qua_mario:unstompable"));
@Unique private static final TagKey<EntityType<?>> HURTS_TO_STOMP_ENTITIES =
TagKey.of(RegistryKeys.ENTITY_TYPE, Identifier.of("qua_mario:hurts_to_stomp"));
@Unique private static final TagKey<EntityType<?>> IMMUNE_TO_BASIC_STOMP_ENTITIES =
TagKey.of(RegistryKeys.ENTITY_TYPE, Identifier.of("qua_mario:immune_to_basic_stomp"));

@Unique private static final TagKey<DamageType> BASIC_STOMPS =
TagKey.of(RegistryKeys.DAMAGE_TYPE, Identifier.of("qua_mario:basic_stomps"));
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions api/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"schemaVersion": 1,
"id": "qua_mario_api",
"version": "1.0.0",
"name": "Mario qua Mario API",
"description": "The API for the Mario qua Mario mod. Used for registering Actions, Power-ups, Characters, Stomp Types, and more!",
"authors": [
"Floral qua Floral"
],
"contact": {
"sources": "https://github.com/floral-qua-floral/marioQuaMario",
"issues": "https://github.com/floral-qua-floral/marioQuaMario/issues"
},
"license": "CC0-1.0",
"icon": "assets/qua_mario/icon.png",
"environment": "*",
"entrypoints": {
},
"mixins": [
"qua_mario_api.mixins.json"
],
"depends": {
"fabricloader": ">=0.16.7",
"minecraft": "~1.21",
"java": ">=21",
"fabric-api": "*"
},
"suggests": {
"another-mod": "*"
},

"custom": {
"loom:injected_interfaces": {
"net/minecraft/entity/Entity.java": ["com/floralquafloral/StompableEntity"]
}
}
}
13 changes: 13 additions & 0 deletions api/src/main/resources/qua_mario_api.mixins.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"required": true,
"package": "com.floralquafloral.mixin",
"compatibilityLevel": "JAVA_21",
"mixins": [
"EntityStompabilityMixin"
],
"injectors": {
"defaultRequire": 1
},
"client": [
]
}
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ loader_version=0.16.7

# Mod Properties
mod_version=1.0.0
api_version=1.0.0
maven_group=com.floralquafloral
archives_base_name=qua_mario

Expand Down
1 change: 1 addition & 0 deletions mod/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ jar {

loom {
accessWidenerPath = file("src/main/resources/qua_mario.accesswidener")

}

// configure the maven publication
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
import net.minecraft.world.BlockCollisionSpliterator;
import org.jetbrains.annotations.NotNull;

import java.util.HashSet;
import java.util.Set;

public class MarioMainClientData extends MarioMoveableData implements MarioClientSideDataImplementation {
private static MarioMainClientData instance;
public static MarioMainClientData getInstance() {
Expand Down Expand Up @@ -121,14 +124,14 @@ public void setAction(ParsedAction action, long seed) {
if (bumpingRule.FLOORS > 0) getTimers().bumpedFloor = BumpManager.attemptBumpBlocks(
this,
marioClient.clientWorld,
getBumpPositions(storedBoundingBox.stretch(0, storedVelocity.y, 0)),
getBumpPositions(storedBoundingBox.stretch(0, storedVelocity.y, 0), Direction.DOWN),
Direction.DOWN,
bumpingRule.FLOORS
);
} else if (bumpingRule.CEILINGS > 0) getTimers().bumpedCeiling = BumpManager.attemptBumpBlocks(
this,
marioClient.clientWorld,
getBumpPositions(storedBoundingBox.stretch(0, storedVelocity.y, 0)),
getBumpPositions(storedBoundingBox.stretch(0, storedVelocity.y, 0), Direction.UP),
Direction.UP,
bumpingRule.CEILINGS
);
Expand Down Expand Up @@ -161,13 +164,19 @@ public void setAction(ParsedAction action, long seed) {
return !marioClient.hasVehicle();
}

private Iterable<BlockPos> getBumpPositions(Box boundingBox) {
return () -> new BlockCollisionSpliterator<>(
private Set<BlockPos> getBumpPositions(Box boundingBox, Direction direction) {
Iterable<BlockPos> iterable = () -> new BlockCollisionSpliterator<>(
marioClient.getWorld(),
marioClient,
boundingBox,
false,
(pos, voxelShape) -> pos.toImmutable());

HashSet<BlockPos> positions = new HashSet<>();
for(BlockPos position : iterable) positions.add(position);
Set<BlockPos> allPositionsChecked = new HashSet<>(positions);
positions.removeIf(blockPos -> allPositionsChecked.contains(blockPos.offset(direction.getOpposite())));
return positions;
}

private void attemptHorizontalBump(Direction direction, Box storedBoundingBox, Vec3d storedVelocity, int bumpStrength) {
Expand All @@ -176,7 +185,7 @@ private void attemptHorizontalBump(Direction direction, Box storedBoundingBox, V
if(BumpManager.attemptBumpBlocks(
this,
marioClient.clientWorld,
getBumpPositions(storedBoundingBox.stretch(isXAxis ? storedVelocity.x : 0, 0, isXAxis ? 0 : storedVelocity.z)),
getBumpPositions(storedBoundingBox.stretch(isXAxis ? storedVelocity.x : 0, 0, isXAxis ? 0 : storedVelocity.z), direction),
direction,
bumpStrength
)) {
Expand Down
81 changes: 0 additions & 81 deletions mod/src/main/java/com/floralquafloral/mixin/EntityMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,26 +44,6 @@

@Mixin(Entity.class)
public class EntityMixin {
@Inject(at = @At("HEAD"), method = "isInSneakingPose", cancellable = true)
private void isInSneakingPose(CallbackInfoReturnable<Boolean> cir) {
if((Entity) (Object) this instanceof PlayerEntity player) {
if(MarioDataManager.getMarioData(player).isSneakProhibited())
cir.setReturnValue(false);
}
}

@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) {
if(MarioDataManager.getMarioData(player).isSneakProhibited()) {

if(player.getPose() == EntityPose.CROUCHING)
player.setPose(EntityPose.STANDING);
ci.cancel();
}
}
}

@Inject(method = "playStepSounds", at = @At("HEAD"), cancellable = true)
private void preventStepSounds(BlockPos pos, BlockState state, CallbackInfo ci) {
if(((Entity) (Object) this) instanceof PlayerEntity player) {
Expand All @@ -73,57 +53,6 @@ private void preventStepSounds(BlockPos pos, BlockState state, CallbackInfo ci)
}
}

@Unique public final double CLIPPING_LENIENCY = 0.2;

@WrapMethod(method = "move")
private void jumpBlockEdgeClipping(MovementType movementType, Vec3d movement, Operation<Void> original) {
if((Entity) (Object) this instanceof PlayerEntity mario && (movementType == MovementType.SELF || movementType == MovementType.PLAYER)) {
MarioPlayerData data = MarioDataManager.getMarioData(mario);

if(movement.y > 0 && data.useMarioPhysics()) {
// If Mario's horizontal velocity is responsible for him clipping a ceiling, then just cancel his horizontal movement
if(
(movement.x != 0 || movement.z != 0)
&& mario.getWorld().isSpaceEmpty(mario, mario.getBoundingBox().offset(movement.x, 0, movement.z))
&& !mario.getWorld().isSpaceEmpty(mario, mario.getBoundingBox().offset(movement))) {
mario.move(movementType, new Vec3d(0, movement.y, 0));
return;
}

if(!mario.getWorld().isSpaceEmpty(mario, mario.getBoundingBox().offset(0, movement.y, 0))) {
Box stretchedBox = mario.getBoundingBox().stretch(0, movement.y, 0);
if(mario.getWorld().isSpaceEmpty(mario, stretchedBox.offset(CLIPPING_LENIENCY, 0, 0)))
mario.move(MovementType.SELF, new Vec3d(CLIPPING_LENIENCY, 0, 0));
if(mario.getWorld().isSpaceEmpty(mario, stretchedBox.offset(-CLIPPING_LENIENCY, 0, 0)))
mario.move(MovementType.SELF, new Vec3d(-CLIPPING_LENIENCY, 0, 0));
if(mario.getWorld().isSpaceEmpty(mario, stretchedBox.offset(0, 0, CLIPPING_LENIENCY)))
mario.move(MovementType.SELF, new Vec3d(0, 0, CLIPPING_LENIENCY));
if(mario.getWorld().isSpaceEmpty(mario, stretchedBox.offset(0, 0, -CLIPPING_LENIENCY)))
mario.move(MovementType.SELF, new Vec3d(0, 0, -CLIPPING_LENIENCY));
}
}
}
original.call(movementType, movement);
}

@Unique
private static boolean shouldStompHook = true;

@Inject(method = "move", at = @At("HEAD"), cancellable = true)
private void executeStompsOnServer(MovementType movementType, Vec3d movement, CallbackInfo ci) {
if((Entity) (Object) this instanceof ServerPlayerEntity mario && shouldStompHook) {
MarioPlayerData data = MarioDataManager.getMarioData(mario);
if(data.useMarioPhysics()) {
ParsedAction action = data.getAction();
if(action.STOMP != null) {
shouldStompHook = false;
if(action.STOMP.attempt((MarioServerData) data, movement)) ci.cancel();
shouldStompHook = true;
}
}
}
}

// @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<VoxelShape> bumpBlocksOnCollision(World world, Entity entity, Box movingEntityBoundingBox, Operation<Iterable<VoxelShape>> original) {
// // This doesn't work! Fix it!
Expand Down Expand Up @@ -210,16 +139,6 @@ private void executeStompsOnServer(MovementType movementType, Vec3d movement, Ca
// }
// }

@Inject(method = "startRiding(Lnet/minecraft/entity/Entity;Z)Z", at = @At("HEAD"))
private void setMountedAction(Entity entity, boolean force, CallbackInfoReturnable<Boolean> cir) {
if((Entity) (Object) this instanceof PlayerEntity mario) {
MarioPlayerData data = MarioDataManager.getMarioData(mario);

data.attemptDismount = false;
data.setActionTransitionless(RegistryManager.ACTIONS.get(Identifier.of("qua_mario:mounted")));
}
}

@Unique private final String MOD_DATA_NAME = MarioQuaMario.MOD_ID + ".data";

@Inject(method = "writeNbt", at = @At("HEAD"))
Expand Down
Loading

0 comments on commit 8915398

Please sign in to comment.