From d40b45a110d8037c50a64565a6eaf258e0143b5f Mon Sep 17 00:00:00 2001 From: Floral <49110090+floral-qua-floral@users.noreply.github.com> Date: Mon, 23 Dec 2024 14:50:13 -0500 Subject: [PATCH] More mixins; useMarioPhysics from old version --- .../actions/GroundedActionDefinition.java | 3 + .../actions/util/EvaluatorEnvironment.java | 3 +- .../mariodata/IMarioReadableMotionData.java | 3 + .../fqf/mario_qua_mario/util/CharaStat.java | 16 ++- .../actions/grounded/SubWalk.java | 99 ++++++++++++++++++- .../actions/grounded/WalkRun.java | 78 +++++++++++++++ content/src/main/resources/fabric.mod.json | 3 +- .../injections/MarioMainClientDataHolder.java | 3 +- .../MarioOtherClientDataHolder.java | 3 +- .../mixin/client/ClientPlayerEntityMixin.java | 26 +++++ .../packets/MarioClientPacketHelper.java | 2 + .../mario_qua_mario.client.mixins.json | 1 + .../mariodata/MarioMoveableData.java | 6 ++ .../mariodata/MarioPlayerData.java | 13 ++- .../mariodata/injections/MarioDataHolder.java | 5 +- .../injections/MarioServerDataHolder.java | 3 +- .../mixin/PlayerEntityMixin.java | 89 +++++++++++++++-- .../packets/MarioDataPackets.java | 6 +- .../UniversalActionDefinitionHelper.java | 46 +++++++++ 19 files changed, 375 insertions(+), 33 deletions(-) create mode 100644 content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/WalkRun.java create mode 100644 mod/src/client/java/com/fqf/mario_qua_mario/mixin/client/ClientPlayerEntityMixin.java diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/states/actions/GroundedActionDefinition.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/states/actions/GroundedActionDefinition.java index 272217f..a82cc84 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/definitions/states/actions/GroundedActionDefinition.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/states/actions/GroundedActionDefinition.java @@ -2,6 +2,7 @@ import com.fqf.mario_qua_mario.definitions.states.actions.util.IncompleteActionDefinition; import com.fqf.mario_qua_mario.definitions.states.actions.util.TransitionDefinition; +import com.fqf.mario_qua_mario.mariodata.IMarioReadableMotionData; import com.fqf.mario_qua_mario.mariodata.IMarioTravelData; import com.fqf.mario_qua_mario.util.CharaStat; import org.jetbrains.annotations.NotNull; @@ -70,5 +71,7 @@ void applyDrag( double forwardAngleContribution, double strafeAngleContribution, CharaStat redirection ); + + double getSlipFactor(IMarioReadableMotionData data); } } diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/states/actions/util/EvaluatorEnvironment.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/states/actions/util/EvaluatorEnvironment.java index 38f2864..d347bb2 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/definitions/states/actions/util/EvaluatorEnvironment.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/states/actions/util/EvaluatorEnvironment.java @@ -3,5 +3,6 @@ public enum EvaluatorEnvironment { CLIENT_ONLY, SERVER_ONLY, - COMMON + COMMON, + CLIENT_CHECKED } diff --git a/api/src/main/java/com/fqf/mario_qua_mario/mariodata/IMarioReadableMotionData.java b/api/src/main/java/com/fqf/mario_qua_mario/mariodata/IMarioReadableMotionData.java index 4c8d854..7060932 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/mariodata/IMarioReadableMotionData.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/mariodata/IMarioReadableMotionData.java @@ -5,6 +5,9 @@ public interface IMarioReadableMotionData extends IMarioData { double getStrafeVel(); double getYVel(); + double getHorizVel(); + double getHorizVelSquared(); + MarioInputs getInputs(); abstract class MarioInputs { diff --git a/api/src/main/java/com/fqf/mario_qua_mario/util/CharaStat.java b/api/src/main/java/com/fqf/mario_qua_mario/util/CharaStat.java index 6551546..23a3af7 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/util/CharaStat.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/util/CharaStat.java @@ -9,18 +9,20 @@ * This is used for movement, speed thresholds, and damage calculations. */ public class CharaStat { - public final double BASE; + public static final CharaStat ZERO = new CharaStat(0); + + public final double BASE_VALUE; public final Set CATEGORIES; - public CharaStat(double base, StatCategory... categories) { - this(base, Set.of(categories)); + public CharaStat(double baseValue, StatCategory... categories) { + this(baseValue, Set.of(categories)); } public CharaStat variate(double multiplier) { - return new CharaStat(this.BASE * multiplier, this.CATEGORIES); + return new CharaStat(this.BASE_VALUE * multiplier, this.CATEGORIES); } private CharaStat(double base, Set categorySet) { - this.BASE = base; + this.BASE_VALUE = base; this.CATEGORIES = categorySet; } @@ -30,6 +32,10 @@ public double get(IMarioData data) { public double getAsThreshold(IMarioData data) { return this.get(data) * 0.96; } + public double getAsSquaredThreshold(IMarioData data) { + double threshold = this.getAsThreshold(data); + return threshold * threshold; + } public double getAsLimit(IMarioData data) { return this.get(data) * 1.015; } diff --git a/content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/SubWalk.java b/content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/SubWalk.java index 0d9a38b..95f7c80 100644 --- a/content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/SubWalk.java +++ b/content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/SubWalk.java @@ -6,6 +6,7 @@ import com.fqf.mario_qua_mario.mariodata.IMarioAuthoritativeData; import com.fqf.mario_qua_mario.mariodata.IMarioClientData; import com.fqf.mario_qua_mario.mariodata.IMarioTravelData; +import com.fqf.mario_qua_mario.util.CharaStat; import net.minecraft.util.Identifier; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -13,6 +14,8 @@ import java.util.List; import java.util.Set; +import static com.fqf.mario_qua_mario.util.StatCategory.*; + public class SubWalk implements GroundedActionDefinition { @Override public @NotNull Identifier getID() { return MarioQuaMarioContent.makeID("sub_walk"); @@ -25,14 +28,14 @@ public class SubWalk implements GroundedActionDefinition { return null; } @Override public @NotNull SlidingStatus getSlidingStatus() { - return SlidingStatus.SLIDING_SILENT; + return SlidingStatus.NOT_SLIDING; } @Override public @NotNull SneakingRule getSneakingRule() { return SneakingRule.PROHIBIT; } @Override public @NotNull SprintingRule getSprintingRule() { - return SprintingRule.ALLOW; + return SprintingRule.PROHIBIT; } @Override public @Nullable BumpType getBumpType() { @@ -42,6 +45,25 @@ public class SubWalk implements GroundedActionDefinition { return null; } + public static final CharaStat WALK_ACCEL = new CharaStat(0.045, WALKING, FORWARD, ACCELERATION); + public static final CharaStat WALK_STANDSTILL_ACCEL = new CharaStat(0.125, WALKING, FORWARD, ACCELERATION, FRICTION); + public static final CharaStat WALK_STANDSTILL_THRESHOLD = new CharaStat(0.12, WALKING, THRESHOLD); + public static final CharaStat WALK_SPEED = new CharaStat(0.275, WALKING, SPEED, FORWARD); + public static final CharaStat WALK_REDIRECTION = new CharaStat(0.0, WALKING, FORWARD, REDIRECTION); + + public static final CharaStat OVERWALK_ACCEL = new CharaStat(0.028, WALKING, FORWARD, OVERSPEED_CORRECTION); + + public static final CharaStat IDLE_DEACCEL = new CharaStat(0.075, WALKING, FRICTION); + + public static final CharaStat BACKPEDAL_ACCEL = new CharaStat(0.055, WALKING, BACKWARD, ACCELERATION); + public static final CharaStat BACKPEDAL_SPEED = new CharaStat(0.225, WALKING, BACKWARD, SPEED); + public static final CharaStat BACKPEDAL_REDIRECTION = new CharaStat(0.0, WALKING, BACKWARD, REDIRECTION); + public static final CharaStat OVERBACKPEDAL_ACCEL = new CharaStat(0.04, WALKING, BACKWARD, OVERSPEED_CORRECTION); + public static final CharaStat UNDERBACKPEDAL_ACCEL = new CharaStat(0.055, WALKING, BACKWARD, ACCELERATION, FRICTION); + + public static final CharaStat STRAFE_ACCEL = new CharaStat(0.065, WALKING, STRAFE, ACCELERATION); + public static final CharaStat STRAFE_SPEED = new CharaStat(0.275, WALKING, STRAFE, SPEED); + @Override public void clientTick(IMarioClientData data, boolean isSelf) { } @@ -49,12 +71,81 @@ public class SubWalk implements GroundedActionDefinition { } @Override public void travelHook(IMarioTravelData data, GroundedActionHelper helper) { - + if(data.getInputs().getForwardInput() > 0) { + if(data.getForwardVel() > WALK_SPEED.getAsLimit(data)) { + // Overwalk + helper.groundAccel(data, + OVERWALK_ACCEL, WALK_SPEED, + STRAFE_ACCEL, STRAFE_SPEED, + data.getInputs().getForwardInput(), data.getInputs().getStrafeInput(), + WALK_REDIRECTION + ); + } + else if(data.getForwardVel() <= WALK_STANDSTILL_THRESHOLD.getAsThreshold(data)) { + // Walk accel from low velocity + helper.groundAccel(data, + WALK_STANDSTILL_ACCEL, WALK_SPEED, + STRAFE_ACCEL, STRAFE_SPEED, + data.getInputs().getForwardInput(), data.getInputs().getStrafeInput(), + WALK_REDIRECTION + ); + } + else { + // Walk accel + helper.groundAccel(data, + WALK_ACCEL, WALK_SPEED, + STRAFE_ACCEL, STRAFE_SPEED, + data.getInputs().getForwardInput(), data.getInputs().getStrafeInput(), + WALK_REDIRECTION + ); + } + } + else if(data.getInputs().getForwardInput() < 0) { + if(data.getForwardVel() > 0) { + // Under-backpedal + helper.groundAccel(data, + UNDERBACKPEDAL_ACCEL, BACKPEDAL_SPEED, + STRAFE_ACCEL, STRAFE_SPEED, + data.getInputs().getForwardInput(), data.getInputs().getStrafeInput(), + BACKPEDAL_REDIRECTION + ); + } + else if(data.getForwardVel() < BACKPEDAL_SPEED.getAsLimit(data)) { + // Over-backpedal + helper.groundAccel(data, + OVERBACKPEDAL_ACCEL, BACKPEDAL_SPEED, + STRAFE_ACCEL, STRAFE_SPEED, + data.getInputs().getForwardInput(), data.getInputs().getStrafeInput(), + BACKPEDAL_REDIRECTION + ); + } + else { + // Backpedal Accel + helper.groundAccel(data, + BACKPEDAL_ACCEL, BACKPEDAL_SPEED, + STRAFE_ACCEL, STRAFE_SPEED, + data.getInputs().getForwardInput(), data.getInputs().getStrafeInput(), + BACKPEDAL_REDIRECTION + ); + } + } + else { + // Idle deaccel + helper.groundAccel(data, + IDLE_DEACCEL, CharaStat.ZERO, + STRAFE_ACCEL, STRAFE_SPEED, + 0.0, 0.0, CharaStat.ZERO + ); + } } @Override public @NotNull List getBasicTransitions(GroundedActionHelper helper) { return List.of( - + new TransitionDefinition( + MarioQuaMarioContent.makeID("walk_run"), + WalkRun::meetsWalkRunRequirement, + EvaluatorEnvironment.CLIENT_ONLY + ) ); } @Override public @NotNull List getInputTransitions(GroundedActionHelper helper) { diff --git a/content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/WalkRun.java b/content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/WalkRun.java new file mode 100644 index 0000000..dd8f7c5 --- /dev/null +++ b/content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/WalkRun.java @@ -0,0 +1,78 @@ +package com.fqf.mario_qua_mario.actions.grounded; + +import com.fqf.mario_qua_mario.MarioQuaMarioContent; +import com.fqf.mario_qua_mario.definitions.states.actions.GroundedActionDefinition; +import com.fqf.mario_qua_mario.definitions.states.actions.util.*; +import com.fqf.mario_qua_mario.mariodata.IMarioAuthoritativeData; +import com.fqf.mario_qua_mario.mariodata.IMarioClientData; +import com.fqf.mario_qua_mario.mariodata.IMarioReadableMotionData; +import com.fqf.mario_qua_mario.mariodata.IMarioTravelData; +import com.fqf.mario_qua_mario.util.CharaStat; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Set; + +import static com.fqf.mario_qua_mario.util.StatCategory.*; +import static com.fqf.mario_qua_mario.util.StatCategory.OVERSPEED_CORRECTION; + +public class WalkRun extends SubWalk implements GroundedActionDefinition { + @Override public @NotNull Identifier getID() { + return MarioQuaMarioContent.makeID("walk_run"); + } + + @Override public @NotNull SprintingRule getSprintingRule() { + return SprintingRule.ALLOW; + } + + public static final CharaStat RUN_ACCEL = new CharaStat(0.0175, RUNNING, FORWARD, ACCELERATION); + public static final CharaStat RUN_SPEED = new CharaStat(0.55, RUNNING, FORWARD, SPEED); + public static final CharaStat RUN_REDIRECTION = new CharaStat(2.76, RUNNING, FORWARD, REDIRECTION); + public static final CharaStat OVERRUN_ACCEL = new CharaStat(0.0175, RUNNING, FORWARD, OVERSPEED_CORRECTION); + + public static boolean meetsWalkRunRequirement(IMarioReadableMotionData data) { + return data.getInputs().getForwardInput() > 0 && + data.getForwardVel() > WALK_STANDSTILL_THRESHOLD.get(data) && + data.getHorizVelSquared() > WALK_SPEED.getAsSquaredThreshold(data); + } + + @Override public void travelHook(IMarioTravelData data, GroundedActionHelper helper) { + if(data.getMario().isSprinting()) { + if(data.getForwardVel() > RUN_SPEED.getAsLimit(data)) { + // Overrun + helper.groundAccel(data, + OVERRUN_ACCEL, RUN_SPEED, + STRAFE_ACCEL, STRAFE_SPEED, + data.getInputs().getForwardInput(), data.getInputs().getStrafeInput() * 0.8, + RUN_REDIRECTION + ); + } + else { + // Run Accel + helper.groundAccel(data, + RUN_ACCEL, RUN_SPEED, + STRAFE_ACCEL, STRAFE_SPEED, + data.getInputs().getForwardInput(), data.getInputs().getStrafeInput(), + RUN_REDIRECTION + ); + } + } + else super.travelHook(data, helper); + } + + @Override public @NotNull List getBasicTransitions(GroundedActionHelper helper) { + return List.of( + new TransitionDefinition( + MarioQuaMarioContent.makeID("sub_walk"), + data -> !meetsWalkRunRequirement(data), + EvaluatorEnvironment.CLIENT_ONLY + ) + ); + } + + @Override public @NotNull Set getTransitionInjections() { + return Set.of(); + } +} diff --git a/content/src/main/resources/fabric.mod.json b/content/src/main/resources/fabric.mod.json index 9fbc4cf..b463d01 100644 --- a/content/src/main/resources/fabric.mod.json +++ b/content/src/main/resources/fabric.mod.json @@ -20,7 +20,8 @@ "com.fqf.mario_qua_mario.actions.generic.DebugSprint" ], "mqm-grounded-actions": [ - "com.fqf.mario_qua_mario.actions.grounded.SubWalk" + "com.fqf.mario_qua_mario.actions.grounded.SubWalk", + "com.fqf.mario_qua_mario.actions.grounded.WalkRun" ], "mqm-airborne-actions": [ ], diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioMainClientDataHolder.java b/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioMainClientDataHolder.java index 03ab6ee..e69b2e3 100644 --- a/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioMainClientDataHolder.java +++ b/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioMainClientDataHolder.java @@ -4,8 +4,7 @@ import org.jetbrains.annotations.NotNull; public interface MarioMainClientDataHolder extends MarioDataHolder { - @SuppressWarnings("DataFlowIssue") @Override default @NotNull MarioMainClientData mqm$getMarioData() { - return null; + throw new AssertionError("MarioMainClientDataHolder default method called?!"); } } diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioOtherClientDataHolder.java b/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioOtherClientDataHolder.java index 134ab62..eabd624 100644 --- a/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioOtherClientDataHolder.java +++ b/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/injections/MarioOtherClientDataHolder.java @@ -4,8 +4,7 @@ import org.jetbrains.annotations.NotNull; public interface MarioOtherClientDataHolder extends MarioDataHolder { - @SuppressWarnings("DataFlowIssue") @Override default @NotNull MarioOtherClientData mqm$getMarioData() { - return null; + throw new AssertionError("MarioOtherClientDataHolder default method called?!"); } } diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/mixin/client/ClientPlayerEntityMixin.java b/mod/src/client/java/com/fqf/mario_qua_mario/mixin/client/ClientPlayerEntityMixin.java new file mode 100644 index 0000000..3b47a1e --- /dev/null +++ b/mod/src/client/java/com/fqf/mario_qua_mario/mixin/client/ClientPlayerEntityMixin.java @@ -0,0 +1,26 @@ +package com.fqf.mario_qua_mario.mixin.client; + +import com.fqf.mario_qua_mario.definitions.states.actions.util.SprintingRule; +import com.fqf.mario_qua_mario.mariodata.injections.MarioMainClientDataHolder; +import com.mojang.authlib.GameProfile; +import net.minecraft.client.network.AbstractClientPlayerEntity; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.client.world.ClientWorld; +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.CallbackInfoReturnable; + +@Mixin(ClientPlayerEntity.class) +public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity implements MarioMainClientDataHolder { + public ClientPlayerEntityMixin(ClientWorld world, GameProfile profile) { + super(world, profile); + throw new AssertionError("Mixin constructor?!"); + } + + @Inject(method = "canSprint", at = @At("HEAD"), cancellable = true) + private void preventSprinting(CallbackInfoReturnable cir) { + if(mqm$getMarioData().doMarioTravel() && mqm$getMarioData().getAction().SPRINTING_RULE == SprintingRule.PROHIBIT) + cir.setReturnValue(false); + } +} diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/packets/MarioClientPacketHelper.java b/mod/src/client/java/com/fqf/mario_qua_mario/packets/MarioClientPacketHelper.java index 931e430..90c2c9c 100644 --- a/mod/src/client/java/com/fqf/mario_qua_mario/packets/MarioClientPacketHelper.java +++ b/mod/src/client/java/com/fqf/mario_qua_mario/packets/MarioClientPacketHelper.java @@ -1,6 +1,7 @@ package com.fqf.mario_qua_mario.packets; import com.fqf.mario_qua_mario.MarioClientHelperManager; +import com.fqf.mario_qua_mario.MarioQuaMario; import com.fqf.mario_qua_mario.registries.RegistryManager; import com.fqf.mario_qua_mario.registries.actions.AbstractParsedAction; import com.fqf.mario_qua_mario.registries.actions.ParsedActionHelper; @@ -55,6 +56,7 @@ public static PlayerEntity getMarioFromID(ClientPlayNetworking.Context context, @Override public void setActionC2S(AbstractParsedAction fromAction, AbstractParsedAction toAction, long seed) { + MarioQuaMario.LOGGER.info("Sending setActionC2S Packet for {}->{}", fromAction.ID, toAction.ID); ClientPlayNetworking.send(new MarioDataPackets.SetActionC2SPayload(fromAction.getIntID(), toAction.getIntID(), seed)); } } diff --git a/mod/src/client/resources/mario_qua_mario.client.mixins.json b/mod/src/client/resources/mario_qua_mario.client.mixins.json index 055ce31..4f20efe 100644 --- a/mod/src/client/resources/mario_qua_mario.client.mixins.json +++ b/mod/src/client/resources/mario_qua_mario.client.mixins.json @@ -4,6 +4,7 @@ "compatibilityLevel": "JAVA_21", "client": [ "ClientPlayerEntityMarioDataMixin", + "ClientPlayerEntityMixin", "InGameHudMixin", "OtherClientPlayerEntityMarioDataMixin" ], diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioMoveableData.java b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioMoveableData.java index 7c8db1e..98e29b3 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioMoveableData.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioMoveableData.java @@ -59,6 +59,12 @@ private void apply() { if(this.VELOCITIES.isGenerated) return this.VELOCITIES.vertical; else return this.getMario().getVelocity().y; } + @Override public double getHorizVel() { + return this.getMario().getVelocity().horizontalLength(); + } + @Override public double getHorizVelSquared() { + return this.getMario().getVelocity().horizontalLengthSquared(); + } @Override public void setForwardVel(double forward) { VELOCITIES.ensureDirty().forward = forward; diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioPlayerData.java b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioPlayerData.java index efe077b..2cb4b1d 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioPlayerData.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioPlayerData.java @@ -62,8 +62,9 @@ public AbstractParsedAction getAction() { public boolean setAction(@Nullable AbstractParsedAction fromAction, AbstractParsedAction toAction, long seed, boolean forced, boolean fromCommand) { if(!this.getAction().equals(fromAction) && !forced && !fromCommand) { // Check if we were recently in fromAction. If not, return false. - if(this.RECENT_ACTIONS.stream().noneMatch(pair -> pair.getLeft().equals(fromAction))) { - MarioQuaMario.LOGGER.info("Rejected action transition because we weren't in {} recently!", fromAction); + if(fromAction == null || this.RECENT_ACTIONS.stream().noneMatch(pair -> pair.getLeft().equals(fromAction))) { + Identifier fromActionID = fromAction == null ? null : fromAction.ID; + MarioQuaMario.LOGGER.info("TRANSITION REJECTED:\nCurrent action: {}\nFrom action: {}\nTo action: {}", this.getActionID(), fromActionID, toAction.ID); return false; } } @@ -135,7 +136,7 @@ public void tick() { } @Override public double getStat(CharaStat stat) { - return stat.BASE * this.getStatMultiplier(stat); + return stat.BASE_VALUE * this.getStatMultiplier(stat); } @Override public double getStatMultiplier(CharaStat stat) { @@ -150,4 +151,10 @@ public void tick() { private boolean recentlyInAction(AbstractParsedAction action) { return true; } + + public boolean doMarioTravel() { + return this.isEnabled() && !this.getMario().getAbilities().flying && !this.getMario().isFallFlying() && !this.getMario().isUsingRiptide(); + } + + public boolean attemptDismount; } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioDataHolder.java b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioDataHolder.java index 2e1a383..6b0761e 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioDataHolder.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioDataHolder.java @@ -4,11 +4,10 @@ import org.jetbrains.annotations.NotNull; public interface MarioDataHolder { - @SuppressWarnings("DataFlowIssue") default @NotNull MarioPlayerData mqm$getMarioData() { - return null; + throw new AssertionError("MarioDataHolder default method called?!"); }; default void mqm$setMarioData(MarioPlayerData replacementData) { - + throw new AssertionError("MarioDataHolder default method called?!"); }; } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioServerDataHolder.java b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioServerDataHolder.java index 8189647..ff39e8d 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioServerDataHolder.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/injections/MarioServerDataHolder.java @@ -4,8 +4,7 @@ import org.jetbrains.annotations.NotNull; public interface MarioServerDataHolder extends MarioDataHolder { - @SuppressWarnings("DataFlowIssue") @Override default @NotNull MarioServerPlayerData mqm$getMarioData() { - return null; + throw new AssertionError("MarioServerDataHolder default method called?!"); }; } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/mixin/PlayerEntityMixin.java b/mod/src/main/java/com/fqf/mario_qua_mario/mixin/PlayerEntityMixin.java index 3cc7d99..3c1a717 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/mixin/PlayerEntityMixin.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/mixin/PlayerEntityMixin.java @@ -1,13 +1,20 @@ package com.fqf.mario_qua_mario.mixin; import com.fqf.mario_qua_mario.MarioQuaMario; +import com.fqf.mario_qua_mario.definitions.states.actions.util.SlidingStatus; +import com.fqf.mario_qua_mario.definitions.states.actions.util.SneakingRule; import com.fqf.mario_qua_mario.mariodata.MarioMoveableData; import com.fqf.mario_qua_mario.mariodata.MarioPlayerData; import com.fqf.mario_qua_mario.mariodata.injections.MarioDataHolder; +import com.fqf.mario_qua_mario.registries.power_granting.ParsedCharacter; +import com.fqf.mario_qua_mario.registries.power_granting.ParsedPowerUp; import com.fqf.mario_qua_mario.util.MarioGamerules; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import net.minecraft.block.BlockState; +import net.minecraft.entity.EntityDimensions; +import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.damage.DamageSource; @@ -17,12 +24,20 @@ 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; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(PlayerEntity.class) public abstract class PlayerEntityMixin extends LivingEntity implements MarioDataHolder { + @Shadow public abstract EntityDimensions getBaseDimensions(EntityPose pose); + + @Shadow public float strideDistance; + + @Shadow public float prevStrideDistance; + private PlayerEntityMixin(EntityType entityType, World world) { super(entityType, world); } @@ -35,6 +50,7 @@ private void tickHook(CallbackInfo ci) { @Inject(method = "travel", at = @At("HEAD"), cancellable = true) private void travelHook(Vec3d movementInput, CallbackInfo ci) { if(this.mqm$getMarioData() instanceof MarioMoveableData moveableData + && moveableData.doMarioTravel() && moveableData.travelHook(movementInput.z, movementInput.x)) ci.cancel(); } @@ -55,6 +71,71 @@ protected void playStepSounds(BlockPos pos, BlockState state) { }; } + @WrapMethod(method = "damage") + private boolean damageHook(DamageSource source, float amount, Operation original) { + float factor; + if(mqm$getMarioData().isEnabled()) factor = (float) getWorld().getGameRules().get(MarioGamerules.INCOMING_DAMAGE_MULTIPLIER).get(); + else factor = 1F; + return original.call(source, amount * factor); + } + + @Inject(method = "shouldSwimInFluids", at = @At("HEAD"), cancellable = true) + private void preventVanillaSwimming(CallbackInfoReturnable cir) { + if(mqm$getMarioData().doMarioTravel()) + cir.setReturnValue(false); + } + + @Inject(method = "getBaseDimensions", at = @At("RETURN"), cancellable = true) + private void alterMarioHitbox(EntityPose pose, CallbackInfoReturnable cir) { + MarioPlayerData data = mqm$getMarioData(); + if(data.isEnabled()) { + // Return the standing hitbox if we're trying to evaluate Mario's sneaking hitbox while he can't sneak + if(pose == EntityPose.CROUCHING && data.getAction().SNEAKING_RULE == SneakingRule.PROHIBIT) + cir.setReturnValue(getBaseDimensions(EntityPose.STANDING)); + else { + ParsedPowerUp powerUp = data.getPowerUp(); + ParsedCharacter character = data.getCharacter(); + + float widthFactor = powerUp.WIDTH_FACTOR * character.WIDTH_FACTOR; + float heightFactor = powerUp.HEIGHT_FACTOR * character.HEIGHT_FACTOR; + if(pose == EntityPose.CROUCHING) heightFactor *= 0.6F; + + EntityDimensions normalDimensions = cir.getReturnValue(); + + cir.setReturnValue(new EntityDimensions( + normalDimensions.width() * widthFactor, + normalDimensions.height() * heightFactor, + normalDimensions.eyeHeight() * heightFactor, + normalDimensions.attachments().scale(widthFactor, heightFactor, widthFactor), normalDimensions.fixed() + )); + } + } + } + + @Inject(method = "clipAtLedge", at = @At("HEAD"), cancellable = true) + private void slideOffLedges(CallbackInfoReturnable cir) { + MarioPlayerData data = mqm$getMarioData(); + if(data.doMarioTravel() && data.getAction().SNEAKING_RULE == SneakingRule.SLIP) + cir.setReturnValue(false); + } + + @Inject(method = "tickMovement", at = @At("TAIL")) + private void preventViewBobbing(CallbackInfo ci) { + MarioPlayerData data = mqm$getMarioData(); + if(data.isClient() && data.getAction().SLIDING_STATUS != SlidingStatus.NOT_SLIDING) + strideDistance = prevStrideDistance * 0.6F; + } + +// @Inject(method = "shouldDismount", at = @At("HEAD")) +// private void changeDismounting(CallbackInfoReturnable cir) { +// MarioPlayerData data = mqm$getMarioData(); +// } + + @WrapWithCondition(method = "jump", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;jump()V")) + private boolean preventLivingEntityJump(LivingEntity instance) { + return !mqm$getMarioData().doMarioTravel(); + } + @Override public void writeCustomDataToNbt(NbtCompound nbt) { super.writeCustomDataToNbt(nbt); @@ -73,12 +154,4 @@ public void writeCustomDataToNbt(NbtCompound nbt) { nbt.put(MarioQuaMario.MOD_DATA_KEY, persistentData); } - - @WrapMethod(method = "damage") - private boolean damageHook(DamageSource source, float amount, Operation original) { - float factor; - if(mqm$getMarioData().isEnabled()) factor = (float) getWorld().getGameRules().get(MarioGamerules.INCOMING_DAMAGE_MULTIPLIER).get(); - else factor = 1F; - return original.call(source, amount * factor); - } } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/packets/MarioDataPackets.java b/mod/src/main/java/com/fqf/mario_qua_mario/packets/MarioDataPackets.java index ed3c1cc..2a9285f 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/packets/MarioDataPackets.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/packets/MarioDataPackets.java @@ -5,6 +5,7 @@ import com.fqf.mario_qua_mario.registries.actions.ParsedActionHelper; import com.fqf.mario_qua_mario.registries.power_granting.ParsedCharacter; import com.fqf.mario_qua_mario.registries.power_granting.ParsedPowerUp; +import com.fqf.mario_qua_mario.util.MarioGamerules; import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.minecraft.network.RegistryByteBuf; @@ -76,9 +77,10 @@ protected record SetActionC2SPayload(int fromAction, int toAction, long seed) im ); public static void receive(SetActionC2SPayload payload, ServerPlayNetworking.Context context) { - AbstractParsedAction fromAction = ParsedActionHelper.get(payload.toAction()); + AbstractParsedAction fromAction = ParsedActionHelper.get(payload.fromAction()); AbstractParsedAction toAction = ParsedActionHelper.get(payload.toAction()); - if(context.player().mqm$getMarioData().setAction(fromAction, toAction, payload.seed, false, false)) { + boolean rejectInvalid = context.player().getWorld().getGameRules().getBoolean(MarioGamerules.REJECT_INVALID_ACTION_TRANSITIONS); + if(context.player().mqm$getMarioData().setAction(fromAction, toAction, payload.seed, !rejectInvalid, false)) { MarioPackets.sendToTrackers(context.player(), new ActionTransitionS2CPayload( context.player().getId(), payload.fromAction, diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/UniversalActionDefinitionHelper.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/UniversalActionDefinitionHelper.java index fb5b010..e0a281c 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/UniversalActionDefinitionHelper.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/UniversalActionDefinitionHelper.java @@ -10,7 +10,9 @@ import com.fqf.mario_qua_mario.mariodata.IMarioTravelData; import com.fqf.mario_qua_mario.mariodata.MarioMoveableData; import com.fqf.mario_qua_mario.util.CharaStat; +import net.minecraft.util.math.BlockPos; import org.jetbrains.annotations.Nullable; +import org.joml.Vector2d; public class UniversalActionDefinitionHelper implements GroundedActionDefinition.GroundedActionHelper, @@ -27,7 +29,13 @@ public void groundAccel( CharaStat strafeAccelStat, CharaStat strafeSpeedStat, double forwardAngleContribution, double strafeAngleContribution, CharaStat redirectStat ) { + double slipFactor = getSlipFactor(data); + data.approachAngleAndAccel( + forwardAccelStat.get(data) * slipFactor, forwardSpeedStat.get(data) * data.getInputs().getForwardInput(), + strafeAccelStat.get(data) * slipFactor, strafeSpeedStat.get(data) * data.getInputs().getStrafeInput(), + forwardAngleContribution, strafeAngleContribution, redirectStat.get(data) * slipFactor + ); } @Override @@ -36,7 +44,45 @@ public void applyDrag( CharaStat drag, CharaStat dragMin, double forwardAngleContribution, double strafeAngleContribution, CharaStat redirection ) { + double dragValue = drag.get(data); + boolean dragInverted = dragValue < 0; + double slipFactor = getSlipFactor(data); + double dragMinValue = dragMin.get(data) * slipFactor; + if(!dragInverted) dragValue *= slipFactor; + + + Vector2d deltaVelocities = new Vector2d( + -dragValue * data.getForwardVel(), + -dragValue * data.getStrafeVel() + ); + double dragVelocitySquared = deltaVelocities.lengthSquared(); + if(dragVelocitySquared != 0 && dragVelocitySquared < dragMinValue * dragMinValue) + deltaVelocities.normalize(dragMinValue); + + if(dragInverted) { + data.setForwardStrafeVel(data.getForwardVel() + deltaVelocities.x, data.getStrafeVel() + deltaVelocities.y); + } + else { + data.approachAngleAndAccel( + deltaVelocities.x, 0, + deltaVelocities.y, 0, + forwardAngleContribution, + strafeAngleContribution, + redirection.get(data) * slipFactor + ); + } + } + @Override + public double getSlipFactor(IMarioReadableMotionData data) { + return Math.pow(0.6 / getFloorSlipperiness(data), 3); + } + private static float getFloorSlipperiness(IMarioReadableMotionData data) { + if(data.getMario().isOnGround()) { + BlockPos blockPos = data.getMario().getVelocityAffectingPos(); + return data.getMario().getWorld().getBlockState(blockPos).getBlock().getSlipperiness(); + } + return 0.6F; } @Override public void applyGravity(