From 440968ccd8b81a0fae9143751c1c73a8178d3429 Mon Sep 17 00:00:00 2001 From: Floral <49110090+floral-qua-floral@users.noreply.github.com> Date: Sun, 15 Dec 2024 20:01:56 -0500 Subject: [PATCH] Further work on Actions implementation --- .../fqf/mario_qua_mario/MarioQuaMarioAPI.java | 5 - .../actions/AirborneActionDefinition.java | 39 ++++ .../actions/AquaticActionDefinition.java | 34 +++ .../actions/GenericActionDefinition.java | 16 ++ .../actions/GroundedActionDefinition.java | 74 ++++++ .../actions/WallboundActionDefinition.java | 50 ++++ .../actions/util/EvaluatorContext.java | 7 + .../IncompleteActionDefinition.java} | 13 +- .../actions/util/SlidingStatus.java | 8 +- .../actions/util/TransitionDefinition.java | 11 +- .../util/TransitionInjectionDefinition.java | 4 +- .../mariodata/IMarioTravelData.java | 28 +++ .../mixin/client/ExampleClientMixin.java | 15 -- ...mario_qua_mario_content.client.mixins.json | 11 - .../mario_qua_mario/MarioQuaMarioContent.java | 5 + .../actions/generic/Debug.java | 83 +++++++ .../actions/generic/DebugSprint.java | 35 +++ .../actions/grounded/SubWalk.java | 79 +++++++ .../mario_qua_mario/mixin/ExampleMixin.java | 15 -- content/src/main/resources/fabric.mod.json | 22 +- .../mario_qua_mario_content.mixins.json | 11 - .../mario_qua_mario/MarioClientHelper.java | 4 + .../mario_qua_mario/MarioQuaMarioClient.java | 5 + .../mariodata/MarioMainClientData.java | 97 +++++++- .../MarioAbstractClientHelper.java | 6 + .../com/fqf/mario_qua_mario/MarioCommand.java | 115 +++++----- .../fqf/mario_qua_mario/MarioQuaMario.java | 6 +- .../mariodata/MarioMoveableData.java | 215 ++++++++++++++++++ .../mariodata/MarioPlayerData.java | 15 +- .../mariodata/MarioServerPlayerData.java | 34 ++- .../mixin/PlayerEntityMixin.java | 16 +- .../registries/RegistryManager.java | 47 +++- .../actions/AbstractParsedAction.java | 119 ++++++++++ .../registries/actions/InitAction.java | 4 +- .../registries/actions/ParsedAction.java | 85 ------- .../actions/ParsedActionHelper.java | 63 +++++ .../registries/actions/ParsedTransition.java | 13 +- .../UniversalActionDefinitionHelper.java | 101 ++++++++ .../actions/parsed/ParsedAirborneAction.java | 47 ++++ .../actions/parsed/ParsedAquaticAction.java | 47 ++++ .../actions/parsed/ParsedGenericAction.java | 46 ++++ .../actions/parsed/ParsedGroundedAction.java | 47 ++++ .../actions/parsed/ParsedWallboundAction.java | 47 ++++ mod/src/main/resources/fabric.mod.json | 3 + 44 files changed, 1495 insertions(+), 252 deletions(-) create mode 100644 api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/AirborneActionDefinition.java create mode 100644 api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/AquaticActionDefinition.java create mode 100644 api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/GenericActionDefinition.java create mode 100644 api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/GroundedActionDefinition.java create mode 100644 api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/WallboundActionDefinition.java create mode 100644 api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/EvaluatorContext.java rename api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/{ActionDefinition.java => util/IncompleteActionDefinition.java} (54%) delete mode 100644 content/src/client/java/com/fqf/mario_qua_mario/mixin/client/ExampleClientMixin.java delete mode 100644 content/src/client/resources/mario_qua_mario_content.client.mixins.json create mode 100644 content/src/main/java/com/fqf/mario_qua_mario/actions/generic/Debug.java create mode 100644 content/src/main/java/com/fqf/mario_qua_mario/actions/generic/DebugSprint.java create mode 100644 content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/SubWalk.java delete mode 100644 content/src/main/java/com/fqf/mario_qua_mario/mixin/ExampleMixin.java delete mode 100644 content/src/main/resources/mario_qua_mario_content.mixins.json create mode 100644 mod/src/client/java/com/fqf/mario_qua_mario/MarioClientHelper.java create mode 100644 mod/src/main/java/com/fqf/mario_qua_mario/MarioAbstractClientHelper.java create mode 100644 mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioMoveableData.java create mode 100644 mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/AbstractParsedAction.java delete mode 100644 mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedAction.java create mode 100644 mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedActionHelper.java create mode 100644 mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/UniversalActionDefinitionHelper.java create mode 100644 mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedAirborneAction.java create mode 100644 mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedAquaticAction.java create mode 100644 mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedGenericAction.java create mode 100644 mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedGroundedAction.java create mode 100644 mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedWallboundAction.java diff --git a/api/src/main/java/com/fqf/mario_qua_mario/MarioQuaMarioAPI.java b/api/src/main/java/com/fqf/mario_qua_mario/MarioQuaMarioAPI.java index b5a10cd..270e295 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/MarioQuaMarioAPI.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/MarioQuaMarioAPI.java @@ -15,9 +15,4 @@ public class MarioQuaMarioAPI implements ModInitializer { public void onInitialize() { LOGGER.info("Mario qua Mario API initializing!"); } - - @Environment(EnvType.CLIENT) - private void testasaur() { - - } } \ No newline at end of file diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/AirborneActionDefinition.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/AirborneActionDefinition.java new file mode 100644 index 0000000..ec4b4b7 --- /dev/null +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/AirborneActionDefinition.java @@ -0,0 +1,39 @@ +package com.fqf.mario_qua_mario.definitions.actions; + +import com.fqf.mario_qua_mario.definitions.actions.util.IncompleteActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionDefinition; +import com.fqf.mario_qua_mario.mariodata.IMarioTravelData; +import com.fqf.mario_qua_mario.util.CharaStat; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public interface AirborneActionDefinition extends IncompleteActionDefinition { + void travelHook(IMarioTravelData data, AirborneActionHelper helper); + + @NotNull List getBasicTransitions(AirborneActionHelper helper); + @NotNull List getInputTransitions(AirborneActionHelper helper); + @NotNull List getWorldCollisionTransitions(AirborneActionHelper helper); + + /** + * Contains a number of methods intended to help with the creation of Airborne Actions. + */ + interface AirborneActionHelper { + void applyGravity( + IMarioTravelData data, + CharaStat gravity, @Nullable CharaStat jumpingGravity, + CharaStat terminalVelocity + ); + + void airborneAccel( + IMarioTravelData data, + CharaStat forwardAccelStat, CharaStat forwardSpeedStat, + CharaStat backwardAccelStat, CharaStat backwardSpeedStat, + CharaStat strafeAccelStat, CharaStat strafeSpeedStat, + double forwardAngleContribution, double strafeAngleContribution, CharaStat redirectStat + ); + + TransitionDefinition makeJumpCapTransition(IncompleteActionDefinition forAction, double capThreshold); + } +} diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/AquaticActionDefinition.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/AquaticActionDefinition.java new file mode 100644 index 0000000..ef61673 --- /dev/null +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/AquaticActionDefinition.java @@ -0,0 +1,34 @@ +package com.fqf.mario_qua_mario.definitions.actions; + +import com.fqf.mario_qua_mario.definitions.actions.util.IncompleteActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionDefinition; +import com.fqf.mario_qua_mario.mariodata.IMarioTravelData; +import com.fqf.mario_qua_mario.util.CharaStat; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public interface AquaticActionDefinition extends IncompleteActionDefinition { + void travelHook(IMarioTravelData data, AquaticActionHelper helper); + + @NotNull List getBasicTransitions(AquaticActionHelper helper); + @NotNull List getInputTransitions(AquaticActionHelper helper); + @NotNull List getWorldCollisionTransitions(AquaticActionHelper helper); + + /** + * Contains a number of methods intended to help with the creation of Aquatic Actions. + */ + interface AquaticActionHelper { + void applyGravity(IMarioTravelData data, CharaStat gravity, CharaStat terminalVelocity); + + void applyWaterDrag(IMarioTravelData data, CharaStat drag, CharaStat dragMin); + + void aquaticAccel( + IMarioTravelData data, + CharaStat forwardAccelStat, CharaStat forwardSpeedStat, + CharaStat backwardAccelStat, CharaStat backwardSpeedStat, + CharaStat strafeAccelStat, CharaStat strafeSpeedStat, + double forwardAngleContribution, double strafeAngleContribution, CharaStat redirectStat + ); + } +} diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/GenericActionDefinition.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/GenericActionDefinition.java new file mode 100644 index 0000000..6c4732b --- /dev/null +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/GenericActionDefinition.java @@ -0,0 +1,16 @@ +package com.fqf.mario_qua_mario.definitions.actions; + +import com.fqf.mario_qua_mario.definitions.actions.util.IncompleteActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionDefinition; +import com.fqf.mario_qua_mario.mariodata.IMarioTravelData; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public interface GenericActionDefinition extends IncompleteActionDefinition { + void travelHook(IMarioTravelData data); + + @NotNull List getBasicTransitions(); + @NotNull List getInputTransitions(); + @NotNull List getWorldCollisionTransitions(); +} diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/GroundedActionDefinition.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/GroundedActionDefinition.java new file mode 100644 index 0000000..67402e6 --- /dev/null +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/GroundedActionDefinition.java @@ -0,0 +1,74 @@ +package com.fqf.mario_qua_mario.definitions.actions; + +import com.fqf.mario_qua_mario.definitions.actions.util.IncompleteActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionDefinition; +import com.fqf.mario_qua_mario.mariodata.IMarioTravelData; +import com.fqf.mario_qua_mario.util.CharaStat; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public interface GroundedActionDefinition extends IncompleteActionDefinition { + void travelHook(IMarioTravelData data, GroundedActionHelper helper); + + @NotNull List getBasicTransitions(GroundedActionHelper helper); + @NotNull List getInputTransitions(GroundedActionHelper helper); + @NotNull List getWorldCollisionTransitions(GroundedActionHelper helper); + + /** + * Contains a number of methods intended to help with the creation of Grounded Actions. Can be cast to any of the + * other ActionHelpers, if for whatever reason you need them. + */ + interface GroundedActionHelper { + /** + * Accelerates Mario using a custom formula. This detaches Mario's ability to gain or lose speed from his + * ability to redirect the angle of existing speed. Unlike a regular entity, Mario's acceleration and + * decceleration is almost always linear, rather than being based on drag. + * + * @param forwardAccelStat The rate at which Mario's forward velocity will change. The absolute value is used. + * @param forwardSpeedStat The forward speed that Mario will try to reach. His acceleration won't overshoot + * this value; if {@code forwardAccelStat} is sufficient to accelerate him past it, + * he'll instead snap to its value. The value of this is scaled by the magnitude of + * Mario's forward input; when using a keyboard, the magnitude is either 0 or 1, + * but if the player is using a controller with an analog stick, it may be values in + * between. + * @param strafeAccelStat The rate at which Mario's sideways velocity will change. The absolute value is used. + * @param strafeSpeedStat The rightwards speed that Mario will try to accelerate towards. Works similarly to + * {@code forwardSpeedStat}. Negative values correspond to leftwards movement. + * @param forwardAngleContribution The forward component of Mario's intended angle of motion. + * @param strafeAngleContribution The rightward component of Mario's intended angle of motion. + * @param redirectStat How far, in degrees, Mario's current motion vector will rotate towards the vector made + * by {@code forwardAngleContribution} and {@code strafeAngleContribution}. This rotation + * occurs before acceleration; even with a {@code redirectStat} of 0 he'll still be able + * to change direction with his acceleration. + */ + void groundAccel( + IMarioTravelData data, + CharaStat forwardAccelStat, CharaStat forwardSpeedStat, + CharaStat strafeAccelStat, CharaStat strafeSpeedStat, + double forwardAngleContribution, double strafeAngleContribution, CharaStat redirectStat + ); + + /** + * Reduces Mario's speed by a portion of his current speed. It is recommended to use this sparingly; + * normal Minecraft entities are subject to drag every tick, but Mario should only experience drag when + * he's in an explicitly sliding-related action (or underwater). Under other circumstances, he should use + * {@link #groundAccel}. + * + * @param drag The fractional portion of Mario's speed that should be lost each tick. For example, a drag of + * 0.1 will result in 10% of Mario's speed being lost per tick. + * @param dragMin The minimum amount of speed lost per tick. Used to ensure Mario comes to a prompt stop + * instead of lingering on very low speed values. + * @param forwardAngleContribution The forward component of Mario's intended angle of motion. + * @param strafeAngleContribution The rightward component of Mario's intended angle of motion. + * @param redirection How far, in degrees, Mario's current motion vector will rotate towards the intended + * direction given by forwardAngleContribution and strafeAngleContribution. + */ + void applyDrag( + IMarioTravelData data, + CharaStat drag, CharaStat dragMin, + double forwardAngleContribution, double strafeAngleContribution, + CharaStat redirection + ); + } +} diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/WallboundActionDefinition.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/WallboundActionDefinition.java new file mode 100644 index 0000000..2b2eb2d --- /dev/null +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/WallboundActionDefinition.java @@ -0,0 +1,50 @@ +package com.fqf.mario_qua_mario.definitions.actions; + +import com.fqf.mario_qua_mario.definitions.actions.util.IncompleteActionDefinition; +import com.fqf.mario_qua_mario.definitions.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 net.minecraft.util.math.Vec3d; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public interface WallboundActionDefinition extends IncompleteActionDefinition { + void travelHook(IMarioTravelData data, WallInfo wall, WallboundActionHelper helper); + + @NotNull List getBasicTransitions(WallboundActionHelper helper); + @NotNull List getInputTransitions(WallboundActionHelper helper); + @NotNull List getWorldCollisionTransitions(WallboundActionHelper helper); + + /** + * Provides some information about the wall Mario is interacting with and his relationship to it. + */ + interface WallInfo { + Vec3d getWallNormal(); + double getNormalYaw(); + + double getTowardsWallInput(); + double getSidleInput(); + + double getSidleVel(); + } + + /** + * Contains a number of methods intended to help with the creation of Wallbound Actions. + */ + interface WallboundActionHelper { + WallInfo getWallInfo(IMarioReadableMotionData data); + + void applyGravity(IMarioTravelData data, CharaStat gravity, CharaStat terminalVelocity); + + void climbWall( + IMarioTravelData data, + CharaStat ascendSpeedStat, CharaStat ascendAccelStat, + CharaStat descendSpeedStat, CharaStat descendAccelStat, + CharaStat sidleSpeedStat, CharaStat sidleAccelStat + ); + + void setSidleVel(IMarioTravelData data, double sidleVel); + } +} diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/EvaluatorContext.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/EvaluatorContext.java new file mode 100644 index 0000000..6ccf1b6 --- /dev/null +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/EvaluatorContext.java @@ -0,0 +1,7 @@ +package com.fqf.mario_qua_mario.definitions.actions.util; + +public enum EvaluatorContext { + CLIENT_ONLY, + SERVER_ONLY, + COMMON +} diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/ActionDefinition.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/IncompleteActionDefinition.java similarity index 54% rename from api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/ActionDefinition.java rename to api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/IncompleteActionDefinition.java index ac1f0d4..30388f6 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/ActionDefinition.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/IncompleteActionDefinition.java @@ -1,16 +1,13 @@ -package com.fqf.mario_qua_mario.definitions.actions; +package com.fqf.mario_qua_mario.definitions.actions.util; import com.fqf.mario_qua_mario.definitions.AttackInterceptingStateDefinition; -import com.fqf.mario_qua_mario.definitions.actions.util.*; -import com.fqf.mario_qua_mario.mariodata.IMarioTravelData; import net.minecraft.util.Identifier; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.List; import java.util.Set; -public interface ActionDefinition extends AttackInterceptingStateDefinition { +public interface IncompleteActionDefinition extends AttackInterceptingStateDefinition { @Nullable String getAnimationName(); @Nullable CameraAnimationSet getCameraAnimations(); @NotNull SlidingStatus getSlidingStatus(); @@ -21,11 +18,5 @@ public interface ActionDefinition extends AttackInterceptingStateDefinition { @Nullable BumpType getBumpType(); @Nullable Identifier getStompTypeID(); - void travelHook(IMarioTravelData data); - - @NotNull List getBasicTransitions(); - @NotNull List getInputTransitions(); - @NotNull List getWorldCollisionTransitions(); - @NotNull Set getTransitionInjections(); } diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/SlidingStatus.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/SlidingStatus.java index 51d9b9e..223878b 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/SlidingStatus.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/SlidingStatus.java @@ -5,11 +5,13 @@ * This does have a server-side effect - if footsteps are suppressed, Sculk Sensors won't be triggered! *

NOT_SLIDING: Vanilla behavior *

NOT_SLIDING_SMOOTH: Footsteps occur, but no view-bobbing. - * + *

*

SLIDING: No footsteps or view-bobbing. Sound effect is highly dependent on speed. *

SKIDDING: No footsteps or view-bobbing. Sound effect mostly ignores speed. *

WALL_SLIDING: No footsteps or view-bobbing. Plays a different sound effect, which completely ignores * horizontal speed. + *

+ *

SLIDING_SILENT: No footsteps or view-bobbing. No sound effect. */ public enum SlidingStatus { NOT_SLIDING, @@ -17,5 +19,7 @@ public enum SlidingStatus { SLIDING, SKIDDING, - WALL_SLIDING + WALL_SLIDING, + + SLIDING_SILENT } diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/TransitionDefinition.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/TransitionDefinition.java index c35958c..089a5c7 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/TransitionDefinition.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/TransitionDefinition.java @@ -1,6 +1,7 @@ package com.fqf.mario_qua_mario.definitions.actions.util; 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 net.minecraft.util.Identifier; import org.jetbrains.annotations.NotNull; @@ -14,22 +15,22 @@ */ public record TransitionDefinition( @NotNull Identifier targetID, - @NotNull Evaluator evaluator, + @NotNull Evaluator evaluator, @NotNull EvaluatorContext context, @Nullable TravelExecutor travelExecutor, @Nullable ClientsExecutor clientsExecutor ) { /** * Alternate constructor provided for convenience */ - public TransitionDefinition(@NotNull Identifier targetID, @NotNull Evaluator evaluator) { - this(targetID, evaluator, null, null); + public TransitionDefinition(@NotNull Identifier targetID, @NotNull Evaluator evaluator, @NotNull EvaluatorContext context) { + this(targetID, evaluator, context, null, null); } /** * Runs on the client-side to test if the associated transition should occur. */ @FunctionalInterface public interface Evaluator { - boolean shouldTransition(IMarioTravelData data); + boolean shouldTransition(IMarioReadableMotionData data); } /** @@ -45,6 +46,6 @@ public TransitionDefinition(@NotNull Identifier targetID, @NotNull Evaluator eva * Runs on the client side for anyone who is in range to see Mario transition. */ @FunctionalInterface public interface ClientsExecutor { - boolean execute(IMarioClientData data, boolean isSelf, long seed); + void execute(IMarioClientData data, boolean isSelf, long seed); } } diff --git a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/TransitionInjectionDefinition.java b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/TransitionInjectionDefinition.java index 2e54b86..3e829f8 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/TransitionInjectionDefinition.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/definitions/actions/util/TransitionInjectionDefinition.java @@ -20,10 +20,10 @@ public enum InjectionPlacement { public enum ActionCategory { ANY, + GENERIC, GROUNDED, AIRBORNE, AQUATIC, - WALL, - UNDEFINED + WALL } } diff --git a/api/src/main/java/com/fqf/mario_qua_mario/mariodata/IMarioTravelData.java b/api/src/main/java/com/fqf/mario_qua_mario/mariodata/IMarioTravelData.java index 64d74cb..fe3332b 100644 --- a/api/src/main/java/com/fqf/mario_qua_mario/mariodata/IMarioTravelData.java +++ b/api/src/main/java/com/fqf/mario_qua_mario/mariodata/IMarioTravelData.java @@ -1,5 +1,11 @@ package com.fqf.mario_qua_mario.mariodata; +import net.minecraft.util.Pair; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + public interface IMarioTravelData extends IMarioReadableMotionData { void setForwardVel(double forward); void setStrafeVel(double strafe); @@ -8,4 +14,26 @@ default void setForwardStrafeVel(double forward, double strafe) { this.setStrafeVel(strafe); } void setYVel(double vertical); + + void approachAngleAndAccel( + double forwardAccel, double forwardTarget, double strafeAccel, double strafeTarget, + double forwardAngleContribution, double strafeAngleContribution, double redirectDelta + ); + + @NotNull MarioTimers getTimers(); + class MarioTimers { + public int actionTimer = 0; + public int jumpLandingTime = 0; + public int doubleJumpLandingTime = 0; + + public boolean jumpCapped = false; + + public boolean actionInterceptedAttack = false; + + public boolean bumpedCeiling = false; + public boolean bumpedFloor = false; + public @Nullable WallBumpReaction bumpedWall = null; + + public record WallBumpReaction(Direction direction, Vec3d originalVelocity) { } + } } diff --git a/content/src/client/java/com/fqf/mario_qua_mario/mixin/client/ExampleClientMixin.java b/content/src/client/java/com/fqf/mario_qua_mario/mixin/client/ExampleClientMixin.java deleted file mode 100644 index 969b2dd..0000000 --- a/content/src/client/java/com/fqf/mario_qua_mario/mixin/client/ExampleClientMixin.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.fqf.mario_qua_mario.mixin.client; - -import net.minecraft.client.MinecraftClient; -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; - -@Mixin(MinecraftClient.class) -public class ExampleClientMixin { - @Inject(at = @At("HEAD"), method = "run") - private void init(CallbackInfo info) { - // This code is injected into the start of MinecraftClient.run()V - } -} \ No newline at end of file diff --git a/content/src/client/resources/mario_qua_mario_content.client.mixins.json b/content/src/client/resources/mario_qua_mario_content.client.mixins.json deleted file mode 100644 index 7871115..0000000 --- a/content/src/client/resources/mario_qua_mario_content.client.mixins.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "required": true, - "package": "com.fqf.mario_qua_mario.mixin.client", - "compatibilityLevel": "JAVA_21", - "client": [ - "ExampleClientMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} \ No newline at end of file diff --git a/content/src/main/java/com/fqf/mario_qua_mario/MarioQuaMarioContent.java b/content/src/main/java/com/fqf/mario_qua_mario/MarioQuaMarioContent.java index 2db11d1..f56ae4e 100644 --- a/content/src/main/java/com/fqf/mario_qua_mario/MarioQuaMarioContent.java +++ b/content/src/main/java/com/fqf/mario_qua_mario/MarioQuaMarioContent.java @@ -2,6 +2,7 @@ import net.fabricmc.api.ModInitializer; +import net.minecraft.util.Identifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -13,4 +14,8 @@ public class MarioQuaMarioContent implements ModInitializer { public void onInitialize() { LOGGER.info("Mario qua Mario Content intializing..."); } + + public static Identifier makeID(String path) { + return Identifier.of("mqm", path); + } } \ No newline at end of file diff --git a/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/Debug.java b/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/Debug.java new file mode 100644 index 0000000..683d425 --- /dev/null +++ b/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/Debug.java @@ -0,0 +1,83 @@ +package com.fqf.mario_qua_mario.actions.generic; + +import com.fqf.mario_qua_mario.MarioQuaMarioContent; +import com.fqf.mario_qua_mario.definitions.actions.GenericActionDefinition; +import com.fqf.mario_qua_mario.definitions.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.IMarioTravelData; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Set; + +public class Debug implements GenericActionDefinition { + @Override public @NotNull Identifier getID() { + return MarioQuaMarioContent.makeID("debug"); + } + + @Override public @Nullable String getAnimationName() { + return null; + } + @Override public @Nullable CameraAnimationSet getCameraAnimations() { + return null; + } + @Override public @NotNull SlidingStatus getSlidingStatus() { + return SlidingStatus.SLIDING_SILENT; + } + + @Override public @NotNull SneakingRule getSneakingRule() { + return SneakingRule.PROHIBIT; + } + @Override public @NotNull SprintingRule getSprintingRule() { + return SprintingRule.ALLOW; + } + + @Override public @Nullable BumpType getBumpType() { + return null; + } + @Override public @Nullable Identifier getStompTypeID() { + return null; + } + + @Override public void clientTick(IMarioClientData data, boolean isSelf) { + + } + @Override public void serverTick(IMarioAuthoritativeData data) { + + } + @Override public void travelHook(IMarioTravelData data) { + MarioQuaMarioContent.LOGGER.info("Debug travelHook uwu! >.<"); + data.getTimers().actionTimer++; + data.setForwardStrafeVel(data.getInputs().getForwardInput() * 0.5, data.getInputs().getStrafeInput() * 0.5); + data.setYVel(data.getInputs().JUMP.isHeld() ? 0.4 : (data.getInputs().DUCK.isHeld() ? -0.4 : (0.03 * Math.sin((double) data.getTimers().actionTimer++ / 16)))); + } + + @Override public @NotNull List getBasicTransitions() { + return List.of( + new TransitionDefinition( + MarioQuaMarioContent.makeID("debug_sprint"), + data -> data.getMario().isSprinting(), EvaluatorContext.CLIENT_ONLY, + null, + (data, isSelf, seed) -> data.playSound(SoundEvents.ENTITY_VEX_CHARGE, seed) + ) + ); + } + @Override public @NotNull List getInputTransitions() { + return List.of(); + } + @Override public @NotNull List getWorldCollisionTransitions() { + return List.of(); + } + + @Override public @NotNull Set getTransitionInjections() { + return Set.of(); + } + + @Override public @NotNull List getUnarmedAttackInterceptions() { + return List.of(); + } +} diff --git a/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/DebugSprint.java b/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/DebugSprint.java new file mode 100644 index 0000000..59c1bad --- /dev/null +++ b/content/src/main/java/com/fqf/mario_qua_mario/actions/generic/DebugSprint.java @@ -0,0 +1,35 @@ +package com.fqf.mario_qua_mario.actions.generic; + +import com.fqf.mario_qua_mario.MarioQuaMarioContent; +import com.fqf.mario_qua_mario.definitions.actions.util.*; +import com.fqf.mario_qua_mario.mariodata.IMarioTravelData; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class DebugSprint extends Debug { + @Override public @NotNull Identifier getID() { + return MarioQuaMarioContent.makeID("debug_sprint"); + } + + @Override public void travelHook(IMarioTravelData data) { + data.setStrafeVel(data.getInputs().getStrafeInput() * 0.5); + + double pitchRadians = Math.toRadians(data.getMario().getPitch()); + data.setForwardVel(data.getInputs().getForwardInput() * Math.cos(pitchRadians)); + data.setYVel(data.getInputs().getForwardInput() * -Math.sin(pitchRadians)); + } + + @Override public @NotNull List getBasicTransitions() { + return List.of( + new TransitionDefinition( + MarioQuaMarioContent.makeID("debug"), + data -> !data.getMario().isSprinting(), EvaluatorContext.CLIENT_ONLY, + null, + (data, isSelf, seed) -> data.playSound(SoundEvents.ENTITY_ALLAY_AMBIENT_WITH_ITEM, seed) + ) + ); + } +} 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 new file mode 100644 index 0000000..88598e9 --- /dev/null +++ b/content/src/main/java/com/fqf/mario_qua_mario/actions/grounded/SubWalk.java @@ -0,0 +1,79 @@ +package com.fqf.mario_qua_mario.actions.grounded; + +import com.fqf.mario_qua_mario.MarioQuaMarioContent; +import com.fqf.mario_qua_mario.definitions.actions.AirborneActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.GenericActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.GroundedActionDefinition; +import com.fqf.mario_qua_mario.definitions.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.IMarioTravelData; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Set; + +public class SubWalk implements GroundedActionDefinition { + @Override public @NotNull Identifier getID() { + return MarioQuaMarioContent.makeID("sub_walk"); + } + + @Override public @Nullable String getAnimationName() { + return null; + } + @Override public @Nullable CameraAnimationSet getCameraAnimations() { + return null; + } + @Override public @NotNull SlidingStatus getSlidingStatus() { + return SlidingStatus.SLIDING_SILENT; + } + + @Override public @NotNull SneakingRule getSneakingRule() { + return SneakingRule.PROHIBIT; + } + @Override public @NotNull SprintingRule getSprintingRule() { + return SprintingRule.ALLOW; + } + + @Override public @Nullable BumpType getBumpType() { + return null; + } + @Override public @Nullable Identifier getStompTypeID() { + return null; + } + + @Override public void clientTick(IMarioClientData data, boolean isSelf) { + + } + @Override public void serverTick(IMarioAuthoritativeData data) { + + } + @Override public void travelHook(IMarioTravelData data, GroundedActionHelper helper) { + + } + + @Override public @NotNull List getBasicTransitions(GroundedActionHelper helper) { + return List.of( + + ); + } + @Override public @NotNull List getInputTransitions(GroundedActionHelper helper) { + return List.of( + + ); + } + @Override public @NotNull List getWorldCollisionTransitions(GroundedActionHelper helper) { + return List.of(); + } + + @Override public @NotNull Set getTransitionInjections() { + return Set.of(); + } + + @Override public @NotNull List getUnarmedAttackInterceptions() { + return List.of(); + } +} diff --git a/content/src/main/java/com/fqf/mario_qua_mario/mixin/ExampleMixin.java b/content/src/main/java/com/fqf/mario_qua_mario/mixin/ExampleMixin.java deleted file mode 100644 index 9fee9b0..0000000 --- a/content/src/main/java/com/fqf/mario_qua_mario/mixin/ExampleMixin.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.fqf.mario_qua_mario.mixin; - -import net.minecraft.server.MinecraftServer; -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; - -@Mixin(MinecraftServer.class) -public class ExampleMixin { - @Inject(at = @At("HEAD"), method = "loadWorld") - private void init(CallbackInfo info) { - // This code is injected into the start of MinecraftServer.loadWorld()V - } -} \ No newline at end of file diff --git a/content/src/main/resources/fabric.mod.json b/content/src/main/resources/fabric.mod.json index e68a413..264a0ca 100644 --- a/content/src/main/resources/fabric.mod.json +++ b/content/src/main/resources/fabric.mod.json @@ -15,6 +15,20 @@ "icon": "assets/mario_qua_mario_content/icon.png", "environment": "*", "entrypoints": { + "mqm-generic-actions": [ + "com.fqf.mario_qua_mario.actions.generic.Debug", + "com.fqf.mario_qua_mario.actions.generic.DebugSprint" + ], + "mqm-grounded-actions": [ + "com.fqf.mario_qua_mario.actions.grounded.SubWalk" + ], + "mqm-airborne-actions": [ + ], + "mqm-aquatic-actions": [ + ], + "mqm-wallbound-actions": [ + ], + "main": [ "com.fqf.mario_qua_mario.MarioQuaMarioContent" ], @@ -25,13 +39,7 @@ "com.fqf.mario_qua_mario.MarioQuaMarioContentDataGenerator" ] }, - "mixins": [ - "mario_qua_mario_content.mixins.json", - { - "config": "mario_qua_mario_content.client.mixins.json", - "environment": "client" - } - ], + "mixins": [], "depends": { "fabricloader": ">=0.16.9", "minecraft": "~1.21", diff --git a/content/src/main/resources/mario_qua_mario_content.mixins.json b/content/src/main/resources/mario_qua_mario_content.mixins.json deleted file mode 100644 index c924f66..0000000 --- a/content/src/main/resources/mario_qua_mario_content.mixins.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "required": true, - "package": "com.fqf.mario_qua_mario.mixin", - "compatibilityLevel": "JAVA_21", - "mixins": [ - "ExampleMixin" - ], - "injectors": { - "defaultRequire": 1 - } -} \ No newline at end of file diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/MarioClientHelper.java b/mod/src/client/java/com/fqf/mario_qua_mario/MarioClientHelper.java new file mode 100644 index 0000000..e5b9aa2 --- /dev/null +++ b/mod/src/client/java/com/fqf/mario_qua_mario/MarioClientHelper.java @@ -0,0 +1,4 @@ +package com.fqf.mario_qua_mario; + +public class MarioClientHelper extends MarioAbstractClientHelper { +} diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/MarioQuaMarioClient.java b/mod/src/client/java/com/fqf/mario_qua_mario/MarioQuaMarioClient.java index 5c7b9d5..8614914 100644 --- a/mod/src/client/java/com/fqf/mario_qua_mario/MarioQuaMarioClient.java +++ b/mod/src/client/java/com/fqf/mario_qua_mario/MarioQuaMarioClient.java @@ -1,10 +1,15 @@ package com.fqf.mario_qua_mario; import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; public class MarioQuaMarioClient implements ClientModInitializer { + // This is in the client sources + @Override public void onInitializeClient() { MarioQuaMario.LOGGER.info("Mario qua Mario Client initializing..."); + + MarioAbstractClientHelper.instance = new MarioClientHelper(); } } \ No newline at end of file diff --git a/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/MarioMainClientData.java b/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/MarioMainClientData.java index 7916fb3..e4a8dd2 100644 --- a/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/MarioMainClientData.java +++ b/mod/src/client/java/com/fqf/mario_qua_mario/mariodata/MarioMainClientData.java @@ -1,10 +1,12 @@ package com.fqf.mario_qua_mario.mariodata; +import net.minecraft.client.input.Input; import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.entity.MovementType; import net.minecraft.entity.player.PlayerEntity; import org.jetbrains.annotations.Nullable; -public class MarioMainClientData extends MarioPlayerData implements IMarioClientDataImpl { +public class MarioMainClientData extends MarioMoveableData implements IMarioClientDataImpl { private static MarioMainClientData instance; public static @Nullable MarioMainClientData getInstance() { return instance; @@ -28,6 +30,99 @@ public MarioMainClientData(ClientPlayerEntity mario) { @Override public void tick() { + this.INPUTS.updateButtons(); + } + + @Override + public boolean travelHook(double forwardInput, double strafeInput) { + this.INPUTS.updateAnalog(forwardInput, strafeInput); + this.getAction().travelHook(this); + this.applyModifiedVelocity(); + this.getMario().move(MovementType.SELF, this.getMario().getVelocity()); + return true; + } + + private final RealInputs INPUTS = new RealInputs(); + @Override public MarioInputs getInputs() { + return this.INPUTS; + } + + private class RealInputs extends MarioInputs { + private final ClientButton JUMP_CLIENT; + private final ClientButton DUCK_CLIENT; + private final ClientButton SPIN_CLIENT; + + private final ClientButton LEFT; + private final ClientButton RIGHT; + + public RealInputs() { + super(new ClientButton(), new ClientButton(), new ClientButton()); + this.JUMP_CLIENT = (ClientButton) this.JUMP; + this.DUCK_CLIENT = (ClientButton) this.DUCK; + this.SPIN_CLIENT = (ClientButton) this.SPIN; + + this.LEFT = new ClientButton(); + this.RIGHT = new ClientButton(); + } + + private static class ClientButton implements MarioButton { + private boolean isHeld = false; + private int pressBuffer = 0; + + @Override public boolean isHeld() { + return isHeld; + } + @Override public boolean isPressed() { + return this.isPressedNoUnbuffer() && this.unbuffer(); + } + public boolean isPressedNoUnbuffer() { + return this.pressBuffer > 0; + } + + private boolean unbuffer() { + this.pressBuffer = 0; + return true; + } + + private void update(boolean isHeld) { + this.update(isHeld, isHeld); + } + private void update(boolean isHeld, boolean isPressed) { + if(isHeld && isPressed && !this.isHeld) + this.pressBuffer = 3; + else + this.pressBuffer--; + this.isHeld = isHeld; + } + } + + @Override public boolean isReal() { + return true; + } + double forwardInput; + @Override public double getForwardInput() { + return this.forwardInput; + } + double strafeInput; + @Override public double getStrafeInput() { + return this.strafeInput; + } + + private void updateButtons() { + ClientPlayerEntity mario = getMario(); + Input inputs = mario.input; + + this.LEFT.update(inputs.pressingLeft); + this.RIGHT.update(inputs.pressingRight); + this.JUMP_CLIENT.update(inputs.jumping); + this.DUCK_CLIENT.update(inputs.sneaking || mario.isInSneakingPose(), inputs.sneaking); + this.SPIN_CLIENT.update(LEFT.isHeld && RIGHT.isHeld, + LEFT.isPressedNoUnbuffer() && RIGHT.isPressedNoUnbuffer()); + } + private void updateAnalog(double forwardInput, double strafeInput) { + this.forwardInput = forwardInput; + this.strafeInput = strafeInput; + } } } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/MarioAbstractClientHelper.java b/mod/src/main/java/com/fqf/mario_qua_mario/MarioAbstractClientHelper.java new file mode 100644 index 0000000..56f30a4 --- /dev/null +++ b/mod/src/main/java/com/fqf/mario_qua_mario/MarioAbstractClientHelper.java @@ -0,0 +1,6 @@ +package com.fqf.mario_qua_mario; + +public abstract class MarioAbstractClientHelper { + public static MarioAbstractClientHelper instance = new MarioAbstractClientHelper() { + }; +} diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/MarioCommand.java b/mod/src/main/java/com/fqf/mario_qua_mario/MarioCommand.java index ea5a6d4..87425ff 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/MarioCommand.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/MarioCommand.java @@ -10,14 +10,12 @@ import net.minecraft.command.argument.BlockPosArgumentType; import net.minecraft.command.argument.EntityArgumentType; import net.minecraft.command.argument.RegistryEntryReferenceArgumentType; -import net.minecraft.entity.Entity; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ServerWorld; import net.minecraft.text.Text; -import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -import net.minecraft.util.math.random.RandomSeed; + +import java.util.Locale; import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; @@ -26,63 +24,68 @@ public class MarioCommand { public static void registerMarioCommand() { CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(literal("mario") - .then(literal("setEnabled") - .then(argument("enabled", BoolArgumentType.bool()) - .executes(context -> setEnabled(context, false)) - .then(argument("target", EntityArgumentType.player()) - .requires(source -> source.hasPermissionLevel(2)) - .executes(context -> setEnabled(context, true)) - ) + .then(literal("set") + .then(literal("enabled") + .then(argument("enabled", BoolArgumentType.bool()) + .requires(source -> source.hasPermissionLevel(0)) + .executes(context -> setEnabled(context, false)) + .then(argument("target", EntityArgumentType.player()) + .requires(source -> source.hasPermissionLevel(2)) + .executes(context -> setEnabled(context, true)) + ) + ) ) - ) - .then(literal("setAction") - .requires(source -> source.hasPermissionLevel(2)) - .then(argument("action", RegistryEntryReferenceArgumentType.registryEntry(registryAccess, RegistryManager.ACTIONS_KEY)) - .executes(context -> setAction(context, false)) - .then(argument("target", EntityArgumentType.player()) - .executes(context -> setAction(context, true)) - ) + .then(literal("action") + .requires(source -> source.hasPermissionLevel(2)) + .then(argument("action", RegistryEntryReferenceArgumentType.registryEntry(registryAccess, RegistryManager.ACTIONS_KEY)) + .executes(context -> setAction(context, false)) + .then(argument("target", EntityArgumentType.player()) + .executes(context -> setAction(context, true)) + ) + ) ) - ) - .then(literal("setPowerUp") - .requires(source -> source.hasPermissionLevel(2)) - .then(argument("power", RegistryEntryReferenceArgumentType.registryEntry(registryAccess, RegistryManager.POWER_UPS_KEY)) - .executes(context -> setPowerUp(context, false)) - .then(argument("target", EntityArgumentType.player()) - .executes(context -> setPowerUp(context, true)) - ) + .then(literal("powerUp") + .requires(source -> source.hasPermissionLevel(2)) + .then(argument("power", RegistryEntryReferenceArgumentType.registryEntry(registryAccess, RegistryManager.POWER_UPS_KEY)) + .executes(context -> setPowerUp(context, false)) + .then(argument("target", EntityArgumentType.player()) + .executes(context -> setPowerUp(context, true)) + ) + ) ) - ) - .then(literal("setCharacter") - .requires(source -> source.hasPermissionLevel(2)) - .then(argument("character", RegistryEntryReferenceArgumentType.registryEntry(registryAccess, RegistryManager.CHARACTERS_KEY)) - .executes(context -> setCharacter(context, false)) - .then(argument("target", EntityArgumentType.player()) - .executes(context -> setCharacter(context, true)) - ) + .then(literal("character") + .requires(source -> source.hasPermissionLevel(2)) + .then(argument("character", RegistryEntryReferenceArgumentType.registryEntry(registryAccess, RegistryManager.CHARACTERS_KEY)) + .executes(context -> setCharacter(context, false)) + .then(argument("target", EntityArgumentType.player()) + .executes(context -> setCharacter(context, true)) + ) + ) ) ) - .then(literal("executeStomp") - .requires(source -> source.hasPermissionLevel(2)) - .then(argument("stomp", RegistryEntryReferenceArgumentType.registryEntry(registryAccess, RegistryManager.STOMP_TYPES_KEY)) - .then(argument("goomba", EntityArgumentType.entity()) - .executes(context -> executeStomp(context, false)) - .then(argument("target", EntityArgumentType.player()) - .executes(context -> executeStomp(context, true)) + .then(literal("perform") + .then(literal("stomp") + .requires(source -> source.hasPermissionLevel(2)) + .then(argument("stomp", RegistryEntryReferenceArgumentType.registryEntry(registryAccess, RegistryManager.STOMP_TYPES_KEY)) + .then(argument("goomba", EntityArgumentType.entity()) + .executes(context -> executeStomp(context, false)) + .then(argument("target", EntityArgumentType.player()) + .executes(context -> executeStomp(context, true)) + ) + ) ) - ) ) - ) - .then(literal("executeBump") - .requires(source -> source.hasPermissionLevel(2)) - .then(argument("position", BlockPosArgumentType.blockPos()) - .executes(context -> executeBump(context, false, Direction.UP, 4)) - .then(makeBumpDirectionFork("up", Direction.UP)) - .then(makeBumpDirectionFork("down", Direction.DOWN)) - .then(makeBumpDirectionFork("north", Direction.NORTH)) - .then(makeBumpDirectionFork("south", Direction.SOUTH)) - .then(makeBumpDirectionFork("east", Direction.EAST)) - .then(makeBumpDirectionFork("west", Direction.WEST)) + .then(literal("bump") + .requires(source -> source.hasPermissionLevel(2)) + .then(argument("position", BlockPosArgumentType.blockPos()) + .executes(context -> executeBump(context, false, Direction.UP, 4)) + .then(makeBumpDirectionFork(Direction.UP)) + .then(makeBumpDirectionFork(Direction.DOWN)) + .then(makeBumpDirectionFork(Direction.NORTH)) + .then(makeBumpDirectionFork(Direction.SOUTH)) + .then(makeBumpDirectionFork(Direction.EAST)) + .then(makeBumpDirectionFork(Direction.WEST)) + ) ) ) ) @@ -156,8 +159,8 @@ private static int executeBump(CommandContext context, bool return 0; } - private static LiteralArgumentBuilder makeBumpDirectionFork(String name, Direction direction) { - return literal(name) + private static LiteralArgumentBuilder makeBumpDirectionFork(Direction direction) { + return literal(direction.name().toLowerCase(Locale.ROOT)) .executes(context -> executeBump(context, false, direction, 4)) .then(argument("strength", IntegerArgumentType.integer()) .executes(context -> executeBump(context, false, direction, null)) diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/MarioQuaMario.java b/mod/src/main/java/com/fqf/mario_qua_mario/MarioQuaMario.java index 8a23f33..ee96b33 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/MarioQuaMario.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/MarioQuaMario.java @@ -1,5 +1,6 @@ package com.fqf.mario_qua_mario; +import com.fqf.mario_qua_mario.registries.RegistryManager; import net.fabricmc.api.ModInitializer; import net.minecraft.util.Identifier; @@ -8,17 +9,18 @@ public class MarioQuaMario implements ModInitializer { public static final String MOD_ID = "mario_qua_mario"; - public static final String MOD_ID_SHORT = "mqm"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); @Override public void onInitialize() { LOGGER.info("Mario qua Mario initializing..."); + RegistryManager.registerAll(); + MarioCommand.registerMarioCommand(); } public static Identifier makeID(String path) { - return Identifier.of(MOD_ID_SHORT, path); + return Identifier.of("mqm", path); } } \ No newline at end of file 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 new file mode 100644 index 0000000..967a0c1 --- /dev/null +++ b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioMoveableData.java @@ -0,0 +1,215 @@ +package com.fqf.mario_qua_mario.mariodata; + +import com.fqf.mario_qua_mario.definitions.actions.WallboundActionDefinition; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import org.jetbrains.annotations.NotNull; +import org.joml.Vector2d; + +public abstract class MarioMoveableData extends MarioPlayerData implements IMarioTravelData { + private final MarioVelocities VELOCITIES = new MarioVelocities(); + private class MarioVelocities { + private double forward; + private double strafe; + private double vertical; + private double negativeSineYaw; + private double cosineYaw; + private boolean isGenerated; + private boolean isDirty; + + private MarioVelocities ensure() { + if(this.isGenerated) return this; + this.isGenerated = true; + + // Calculate forward and sideways vector components + double yawRad = Math.toRadians(getMario().getYaw()); + this.negativeSineYaw = -Math.sin(yawRad); + this.cosineYaw = Math.cos(yawRad); + + // Calculate current forwards and sideways velocity + Vec3d currentVel = getMario().getVelocity(); + this.forward = currentVel.x * negativeSineYaw + currentVel.z * cosineYaw; + this.strafe = currentVel.x * cosineYaw + currentVel.z * -negativeSineYaw; + this.vertical = currentVel.y; + + return this; + } + private MarioVelocities ensureDirty() { + this.isDirty = true; + return this.ensure(); + } + private void apply() { + if(!this.isGenerated || !this.isDirty) return; + getMario().setVelocity(this.forward * this.negativeSineYaw + this.strafe * this.cosineYaw, + this.vertical, this.forward * this.cosineYaw + this.strafe * -this.negativeSineYaw); + } + } + + @Override public double getForwardVel() { + return this.VELOCITIES.ensure().forward; + } + @Override public double getStrafeVel() { + return this.VELOCITIES.ensure().strafe; + } + @Override public double getYVel() { + if(this.VELOCITIES.isGenerated) return this.VELOCITIES.vertical; + else return this.getMario().getVelocity().y; + } + + @Override public void setForwardVel(double forward) { + VELOCITIES.ensureDirty().forward = forward; + } + @Override public void setStrafeVel(double strafe) { + this.VELOCITIES.ensureDirty().strafe = strafe; + } + @Override public void setYVel(double vertical) { + if(vertical > 0) this.getMario().fallDistance = 0; + if(this.VELOCITIES.isGenerated) this.VELOCITIES.ensureDirty().vertical = vertical; + else { + Vec3d oldVel = this.getMario().getVelocity(); + this.getMario().setVelocity(oldVel.x, vertical, oldVel.z); + } + } + + public void applyModifiedVelocity() { + this.VELOCITIES.apply(); + this.VELOCITIES.isDirty = false; + this.VELOCITIES.isGenerated = false; + } + + @Override public void approachAngleAndAccel( + double forwardAccel, double forwardTarget, double strafeAccel, double strafeTarget, + double forwardAngleContribution, double strafeAngleContribution, double redirectDelta + ) { + Vector2d redirectedVel; + + double forwardVel = getForwardVel(); + double strafeVel = getStrafeVel(); + + if (redirectDelta == 0 || (forwardAngleContribution == 0 && strafeAngleContribution == 0) || + (MathHelper.approximatelyEquals(forwardVel, 0) && MathHelper.approximatelyEquals(strafeVel, 0))) { + redirectedVel = new Vector2d(forwardVel, strafeVel); + } else { + Vector2d currentVel = new Vector2d(forwardVel, strafeVel); + Vector2d intendedAngle = new Vector2d(forwardAngleContribution, strafeAngleContribution); + + if (redirectDelta > 0) redirectedVel = MarioMoveableData.slerp(currentVel, intendedAngle, redirectDelta); + else + redirectedVel = intendedAngle.normalize(currentVel.length()); // redirectAngle < 0 for instant redirection + } + + Vector2d newVel; + if (forwardAccel == 0 && strafeAccel == 0) { + // If we're only redirecting then we're done here, no need to calculate acceleration & apply speed cap + newVel = redirectedVel; + } else { + // Ensure forwardAccel and strafeAccel are positive + forwardAccel = Math.abs(forwardAccel); + strafeAccel = Math.abs(strafeAccel); + + // Calculate which way to accelerate + double forwardAccelDir, strafeAccelDir; + double forwardDifference = forwardTarget - redirectedVel.x; + if (MathHelper.approximatelyEquals(forwardDifference, 0)) + forwardAccelDir = 0; + else if (forwardAccel < Math.abs(forwardDifference)) + forwardAccelDir = Math.signum(forwardDifference); + else { + forwardAccelDir = 0; + redirectedVel.x = forwardTarget; + } + double strafeDifference = strafeTarget - redirectedVel.y; + if (MathHelper.approximatelyEquals(strafeDifference, 0)) + strafeAccelDir = 0; + else if (strafeAccel < Math.abs(strafeDifference)) + strafeAccelDir = Math.signum(strafeDifference); + else { + strafeAccelDir = 0; + redirectedVel.y = strafeTarget; + } + + // Calculate the acceleration vector and normalize it, so the player won't get extra acceleration by strafing + Vector2d accelVector = new Vector2d( + forwardAccel * forwardAccelDir, + strafeAccel * strafeAccelDir + ); + if (accelVector.x != 0 || accelVector.y != 0) { + double accelVectorMaxLength = Math.max(forwardAccel, strafeAccel); + if (accelVector.lengthSquared() > accelVectorMaxLength * accelVectorMaxLength) + accelVector.normalize(accelVectorMaxLength); + } + + // Calculate the new velocity + newVel = new Vector2d( + redirectedVel.x + accelVector.x, + redirectedVel.y + accelVector.y + ); + + // Calculate & apply soft speed cap + double speedCap = Math.max(Math.abs(forwardTarget), Math.abs(strafeTarget)); + double speedCapSquared = speedCap * speedCap; + double oldVelLengthSquared = Vector2d.lengthSquared(forwardVel, strafeVel); + + if (newVel.lengthSquared() > oldVelLengthSquared) { + if (oldVelLengthSquared > speedCapSquared) + newVel.normalize(Vector2d.length(forwardVel, strafeVel)); + else if (newVel.lengthSquared() > speedCapSquared) + newVel.normalize(speedCap); + } + } + + // Apply the new velocities + setForwardStrafeVel(newVel.x, newVel.y); + } + + private static Vector2d slerp(Vector2d currentVelocity, Vector2d intendedAngle, double turnSpeedDegrees) { + // Convert turnSpeed to radians + double turnSpeedRadians = Math.toRadians(turnSpeedDegrees); + + // Normalize the input vectors (slerp typically operates on normalized vectors) + Vector2d currentDir = new Vector2d(currentVelocity).normalize(); + Vector2d intendedDir = new Vector2d(intendedAngle).normalize(); + + // Calculate the angle between the two vectors using the dot product + double dotProduct = currentDir.dot(intendedDir); + // Clamp the dot product to ensure it's within the valid range for acos [-1, 1] + dotProduct = MathHelper.clamp(dotProduct, 0.0, 1.0); + + // Calculate the angle between the vectors + double angleBetween = Math.acos(dotProduct); + + // If the angle is very small, just return the current velocity (no need to slerp) + if(Math.abs(angleBetween) < MathHelper.EPSILON || MathHelper.approximatelyEquals(angleBetween, MathHelper.PI)) + return new Vector2d(currentVelocity); + + // Calculate the fraction of the way we want to rotate (clamp to 0.0 to 1.0) + double t = Math.min(1.0, turnSpeedRadians / angleBetween); + + // Slerp calculation + double sinTotal = Math.sin(angleBetween); + double ratioA = Math.sin((1 - t) * angleBetween) / sinTotal; + double ratioB = Math.sin(t * angleBetween) / sinTotal; + + // Compute the new direction as a weighted sum of the two directions + Vector2d newDir = new Vector2d( + currentDir.x * ratioA + intendedDir.x * ratioB, + currentDir.y * ratioA + intendedDir.y * ratioB + ); + + // Maintain the original magnitude of the velocity + newDir.mul(currentVelocity.length()); + + return newDir; // Return the interpolated direction with original magnitude + } + + private final MarioTimers TIMERS = new MarioTimers(); + @Override public @NotNull MarioTimers getTimers() { + return this.TIMERS; + } + + public WallboundActionDefinition.WallInfo getWallInfo() { + return null; + } + + public abstract boolean travelHook(double forwardInput, double strafeInput); +} 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 7841bb4..655961b 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 @@ -1,7 +1,8 @@ package com.fqf.mario_qua_mario.mariodata; import com.fqf.mario_qua_mario.MarioQuaMario; -import com.fqf.mario_qua_mario.registries.actions.ParsedAction; +import com.fqf.mario_qua_mario.registries.RegistryManager; +import com.fqf.mario_qua_mario.registries.actions.AbstractParsedAction; import com.fqf.mario_qua_mario.util.CharaStat; import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.player.PlayerEntity; @@ -13,7 +14,9 @@ public abstract class MarioPlayerData implements IMarioData { protected MarioPlayerData() { this.enabled = false; + this.setEnabledInternal(true); this.action = null; + this.setActionInternal(RegistryManager.ACTIONS.get(MarioQuaMario.makeID("debug"))); // this.powerUp = null; // this.character = null; } @@ -35,14 +38,14 @@ public void setEnabledInternal(boolean enabled) { this.enabled = enabled; } - private ParsedAction action; + private AbstractParsedAction action; @Override public Identifier getActionID() { - return null; + return this.getAction().ID; } - public ParsedAction getAction() { + public AbstractParsedAction getAction() { return this.action; } - public void setActionInternal(ParsedAction action) { + public void setActionInternal(AbstractParsedAction action) { this.action = action; } @@ -62,7 +65,7 @@ public void setActionInternal(ParsedAction action) { } @Override public double getStatMultiplier(CharaStat stat) { - return 0; + return 1; } @Override public int getBumpStrengthModifier() { diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioServerPlayerData.java b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioServerPlayerData.java index 460a680..7744776 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioServerPlayerData.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/mariodata/MarioServerPlayerData.java @@ -4,7 +4,7 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.Identifier; -public class MarioServerPlayerData extends MarioPlayerData implements IMarioAuthoritativeData { +public class MarioServerPlayerData extends MarioMoveableData implements IMarioAuthoritativeData { private ServerPlayerEntity mario; public MarioServerPlayerData(ServerPlayerEntity mario) { super(); @@ -63,4 +63,36 @@ public boolean isClient() { public void tick() { } + + @Override + public boolean travelHook(double forwardInput, double strafeInput) { + return false; + } + + @Override public MarioInputs getInputs() { + return PHONY_INPUTS; + } + + private static final MarioInputs PHONY_INPUTS; + static { + MarioInputs.MarioButton phonyButton = new MarioInputs.MarioButton() { + @Override public boolean isPressed() { + return false; + } + @Override public boolean isHeld() { + return false; + } + }; + PHONY_INPUTS = new MarioInputs(phonyButton, phonyButton, phonyButton) { + @Override public double getForwardInput() { + return 0; + } + @Override public double getStrafeInput() { + return 0; + } + @Override public boolean isReal() { + return false; + } + }; + } } 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 db16172..7ca2490 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,21 +1,25 @@ package com.fqf.mario_qua_mario.mixin; -import com.fqf.mario_qua_mario.MarioQuaMario; -import com.fqf.mario_qua_mario.mariodata.MarioPlayerData; +import com.fqf.mario_qua_mario.mariodata.MarioMoveableData; import com.fqf.mario_qua_mario.mariodata.injections.MarioDataHolder; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.text.Text; 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; @Mixin(PlayerEntity.class) public abstract class PlayerEntityMixin implements MarioDataHolder { - @Inject(method = "travel", at = @At("HEAD")) + @Inject(method = "tick", at = @At("HEAD")) + private void tickHook(CallbackInfo ci) { + this.mqm$getMarioData().tick(); + } + + @Inject(method = "travel", at = @At("HEAD"), cancellable = true) private void travelHook(Vec3d movementInput, CallbackInfo ci) { - mqm$getMarioData().isClient(); + if(this.mqm$getMarioData() instanceof MarioMoveableData moveableData + && moveableData.travelHook(movementInput.z, movementInput.x)) + ci.cancel(); } } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/RegistryManager.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/RegistryManager.java index bba59f3..1b36269 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/registries/RegistryManager.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/RegistryManager.java @@ -1,7 +1,11 @@ package com.fqf.mario_qua_mario.registries; import com.fqf.mario_qua_mario.MarioQuaMario; -import com.fqf.mario_qua_mario.registries.actions.ParsedAction; +import com.fqf.mario_qua_mario.definitions.actions.*; +import com.fqf.mario_qua_mario.definitions.actions.util.IncompleteActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionInjectionDefinition; +import com.fqf.mario_qua_mario.registries.actions.AbstractParsedAction; +import com.fqf.mario_qua_mario.registries.actions.ParsedActionHelper; import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; import net.fabricmc.fabric.api.event.registry.RegistryAttribute; import net.fabricmc.loader.api.FabricLoader; @@ -10,13 +14,25 @@ import net.minecraft.registry.RegistryKey; import net.minecraft.util.Identifier; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Set; public class RegistryManager { - public static void register() { + public static void registerAll() { + registerStompTypes(); + registerActions(); + registerPowerUps(); + registerCharacters(); + + Registry.register(STOMP_TYPES, MarioQuaMario.makeID("stomp"), "BOING!"); Registry.register(STOMP_TYPES, MarioQuaMario.makeID("ground_pound"), "POW!"); +// Registry.register(ACTIONS, MarioQuaMario.makeID("stomp"), null); +// Registry.register(ACTIONS, MarioQuaMario.makeID("ground_pound"), null); + Registry.register(POWER_UPS, MarioQuaMario.makeID("super"), "wahoo!"); Registry.register(POWER_UPS, MarioQuaMario.makeID("small"), "owch!"); @@ -30,9 +46,9 @@ public static void register() { .attribute(RegistryAttribute.SYNCED) .buildAndRegister(); - public static final RegistryKey> ACTIONS_KEY = + public static final RegistryKey> ACTIONS_KEY = RegistryKey.ofRegistry(MarioQuaMario.makeID("actions")); - public static final Registry ACTIONS = FabricRegistryBuilder.createSimple(ACTIONS_KEY) + public static final Registry ACTIONS = FabricRegistryBuilder.createSimple(ACTIONS_KEY) .attribute(RegistryAttribute.SYNCED) .buildAndRegister(); @@ -48,16 +64,35 @@ public static void register() { .attribute(RegistryAttribute.SYNCED) .buildAndRegister(); - public static List getEntrypoints(String key, Class clazz) { + public static List getEntrypoints(String key, Class clazz) { return FabricLoader.getInstance().getEntrypointContainers(key, clazz).stream().map(EntrypointContainer::getEntrypoint).toList(); } + public static void registerThing(Registry registry, Thing thing) { + Registry.register(registry, thing.ID, thing); + } + private static void registerStompTypes() { } private static void registerActions() { - + List actionDefinitions = new ArrayList<>(); + actionDefinitions.addAll(getEntrypoints("mqm-generic-actions", GenericActionDefinition.class)); + actionDefinitions.addAll(getEntrypoints("mqm-grounded-actions", GroundedActionDefinition.class)); + actionDefinitions.addAll(getEntrypoints("mqm-airborne-actions", AirborneActionDefinition.class)); + actionDefinitions.addAll(getEntrypoints("mqm-aquatic-actions", AquaticActionDefinition.class)); + actionDefinitions.addAll(getEntrypoints("mqm-wallbound-actions", WallboundActionDefinition.class)); + + HashMap> allInjections = new HashMap<>(); + for(IncompleteActionDefinition definition : actionDefinitions) { + registerThing(ACTIONS, ParsedActionHelper.parseAction(definition, allInjections)); + } + + // Now all actions are registered; we need to parse their transitions + for(AbstractParsedAction action : ACTIONS) { + action.parseTransitions(allInjections); + } } private static void registerPowerUps() { diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/AbstractParsedAction.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/AbstractParsedAction.java new file mode 100644 index 0000000..b98e8d2 --- /dev/null +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/AbstractParsedAction.java @@ -0,0 +1,119 @@ +package com.fqf.mario_qua_mario.registries.actions; + +import com.fqf.mario_qua_mario.MarioQuaMario; +import com.fqf.mario_qua_mario.definitions.actions.util.IncompleteActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.*; +import com.fqf.mario_qua_mario.mariodata.MarioMoveableData; +import com.fqf.mario_qua_mario.registries.ParsedMarioThing; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public abstract class AbstractParsedAction extends ParsedMarioThing { + protected final IncompleteActionDefinition DEFINITION; + + public final Identifier ID; + + public final @Nullable String ANIMATION; + public final @Nullable CameraAnimationSet CAMERA_ANIMATIONS; + public final SlidingStatus SLIDING_STATUS; + + public final SneakingRule SNEAKING_RULE; + public final SprintingRule SPRINTING_RULE; + + public final @Nullable BumpType BUMP_TYPE; +// public final @Nullable ParsedStompType STOMP_TYPE; + + public final List ALL_TRANSITIONS; + + public final Map TRANSITIONS_FROM_TARGETS; + public final EnumMap> CLIENT_TRANSITIONS; + public final EnumMap> SERVER_TRANSITIONS; + + public AbstractParsedAction(IncompleteActionDefinition definition, HashMap> allInjections) { + super(definition); + this.DEFINITION = definition; + + this.ID = definition.getID(); + this.ANIMATION = definition.getAnimationName(); + this.CAMERA_ANIMATIONS = definition.getCameraAnimations(); + this.SLIDING_STATUS = definition.getSlidingStatus(); + + this.SNEAKING_RULE = definition.getSneakingRule(); + this.SPRINTING_RULE = definition.getSprintingRule(); + + this.BUMP_TYPE = definition.getBumpType(); + + this.ALL_TRANSITIONS = new ArrayList<>(); + this.TRANSITIONS_FROM_TARGETS = new HashMap<>(); + this.CLIENT_TRANSITIONS = new EnumMap<>(TransitionPhase.class); + this.SERVER_TRANSITIONS = new EnumMap<>(TransitionPhase.class); + + for(TransitionInjectionDefinition injection : definition.getTransitionInjections()) { + allInjections.putIfAbsent(injection.injectNearTransitionsTo(), new HashSet<>()); + allInjections.get(injection.injectNearTransitionsTo()).add(injection); + } + } + + protected abstract List getBasicTransitions(); + protected abstract List getInputTransitions(); + protected abstract List getWorldCollisionTransitions(); + + public void parseTransitions(HashMap> allInjections) { + this.parseTransitions(TransitionPhase.BASIC, this.getBasicTransitions(), allInjections); + this.parseTransitions(TransitionPhase.INPUT, this.getInputTransitions(), allInjections); + this.parseTransitions(TransitionPhase.WORLD_COLLISION, this.getWorldCollisionTransitions(), allInjections); + } + private void parseTransitions( + TransitionPhase phase, List transitions, + HashMap> allInjections + ) { + this.CLIENT_TRANSITIONS.putIfAbsent(phase, new ArrayList<>()); + List buildingClientList = this.CLIENT_TRANSITIONS.get(phase); + List buildingServerList = this.SERVER_TRANSITIONS.get(phase); + + for(TransitionDefinition definition : transitions) { + Set relevantInjections = new HashSet<>(allInjections.getOrDefault(definition.targetID(), Set.of())); + relevantInjections.removeIf(injection -> injection.category() != TransitionInjectionDefinition.ActionCategory.ANY && injection.category() != this.getCategory()); + + this.conditionallyInjectTransitions(buildingClientList, buildingServerList, relevantInjections, + TransitionInjectionDefinition.InjectionPlacement.BEFORE, definition); + MarioQuaMario.LOGGER.info("Parsing transition into {}", definition.targetID()); + addTransitionToLists(buildingClientList, buildingServerList, definition); + this.conditionallyInjectTransitions(buildingClientList, buildingServerList, relevantInjections, + TransitionInjectionDefinition.InjectionPlacement.AFTER, definition); + } + } + private void conditionallyInjectTransitions( + List buildingClientList, + List buildingServerList, + Set relevantInjections, + TransitionInjectionDefinition.InjectionPlacement placement, + TransitionDefinition originalTransition + ) { + for(TransitionInjectionDefinition injection : relevantInjections) { + if(injection.placement() == placement) { + addTransitionToLists(buildingClientList, buildingServerList, injection.injectedTransitionCreator().makeTransition(originalTransition)); + } + } + } + + private void addTransitionToLists( + List client, List server, + TransitionDefinition definition + ) { + ParsedTransition transition = new ParsedTransition(definition); + this.ALL_TRANSITIONS.add(transition); + if(this.TRANSITIONS_FROM_TARGETS.containsKey(transition.targetAction())) + MarioQuaMario.LOGGER.warn("Action {} has multiple transitions into {}! This is likely to cause issues!", + this.ID, transition.targetAction().ID); + else this.TRANSITIONS_FROM_TARGETS.put(transition.targetAction(), transition); + if(definition.context() != EvaluatorContext.CLIENT_ONLY) server.add(transition); + if(definition.context() != EvaluatorContext.SERVER_ONLY) client.add(transition); + } + + abstract public void travelHook(MarioMoveableData data); + + abstract protected TransitionInjectionDefinition.ActionCategory getCategory(); +} diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/InitAction.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/InitAction.java index ab0a42c..980cf5c 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/InitAction.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/InitAction.java @@ -1,7 +1,7 @@ package com.fqf.mario_qua_mario.registries.actions; import com.fqf.mario_qua_mario.MarioQuaMario; -import com.fqf.mario_qua_mario.definitions.actions.ActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.GenericActionDefinition; import com.fqf.mario_qua_mario.definitions.actions.util.*; import com.fqf.mario_qua_mario.mariodata.IMarioAuthoritativeData; import com.fqf.mario_qua_mario.mariodata.IMarioClientData; @@ -13,7 +13,7 @@ import java.util.List; import java.util.Set; -public class InitAction implements ActionDefinition { +public class InitAction implements GenericActionDefinition { @Override public @NotNull Identifier getID() { return MarioQuaMario.makeID("init"); } diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedAction.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedAction.java deleted file mode 100644 index 82805b9..0000000 --- a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedAction.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.fqf.mario_qua_mario.registries.actions; - -import com.fqf.mario_qua_mario.definitions.actions.ActionDefinition; -import com.fqf.mario_qua_mario.definitions.actions.util.*; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.Nullable; - -import java.util.*; - -public class ParsedAction { - private final ActionDefinition DEFINITION; - - public final Identifier ID; - - public final @Nullable String ANIMATION; - public final @Nullable CameraAnimationSet CAMERA_ANIMATIONS; - public final SlidingStatus SLIDING_STATUS; - - public final SneakingRule SNEAKING_RULE; - public final SprintingRule SPRINTING_RULE; - - public final @Nullable BumpType BUMP_TYPE; -// public final @Nullable ParsedStompType STOMP_TYPE; - - public final EnumMap> TRANSITIONS; - - public ParsedAction(ActionDefinition definition, HashMap> allInjections) { - this.DEFINITION = definition; - - this.ID = definition.getID(); - this.ANIMATION = definition.getAnimationName(); - this.CAMERA_ANIMATIONS = definition.getCameraAnimations(); - this.SLIDING_STATUS = definition.getSlidingStatus(); - - this.SNEAKING_RULE = definition.getSneakingRule(); - this.SPRINTING_RULE = definition.getSprintingRule(); - - this.BUMP_TYPE = definition.getBumpType(); - - this.TRANSITIONS = new EnumMap<>(TransitionPhase.class); - - for(TransitionInjectionDefinition injection : definition.getTransitionInjections()) { - allInjections.putIfAbsent(injection.injectNearTransitionsTo(), new HashSet<>()); - allInjections.get(injection.injectNearTransitionsTo()).add(injection); - } - } - - public void parseTransitions(HashMap> allInjections) { - this.parseTransitions(TransitionPhase.BASIC, this.DEFINITION.getBasicTransitions(), allInjections); - this.parseTransitions(TransitionPhase.INPUT, this.DEFINITION.getInputTransitions(), allInjections); - this.parseTransitions(TransitionPhase.WORLD_COLLISION, this.DEFINITION.getWorldCollisionTransitions(), allInjections); - } - private void parseTransitions( - TransitionPhase phase, List transitions, - HashMap> allInjections - ) { - this.TRANSITIONS.putIfAbsent(phase, new ArrayList<>()); - List buildingTransitionList = this.TRANSITIONS.get(phase); - - for(TransitionDefinition definition : transitions) { - Set relevantInjections = new HashSet<>(allInjections.get(definition.targetID())); - relevantInjections.removeIf(injection -> !this.isOfCategory(injection.category())); - - this.conditionallyInjectTransitions(buildingTransitionList, relevantInjections, - TransitionInjectionDefinition.InjectionPlacement.BEFORE, definition); - buildingTransitionList.add(new ParsedTransition(definition)); - } - } - private void conditionallyInjectTransitions( - List buildingTransitionList, - Set relevantInjections, - TransitionInjectionDefinition.InjectionPlacement placement, - TransitionDefinition originalTransition - ) { - for(TransitionInjectionDefinition injection : relevantInjections) { - if(injection.placement() == placement) { - buildingTransitionList.add(new ParsedTransition(injection.injectedTransitionCreator().makeTransition(originalTransition))); - } - } - } - - private boolean isOfCategory(TransitionInjectionDefinition.ActionCategory category) { - return true; - } -} diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedActionHelper.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedActionHelper.java new file mode 100644 index 0000000..038ce68 --- /dev/null +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedActionHelper.java @@ -0,0 +1,63 @@ +package com.fqf.mario_qua_mario.registries.actions; + +import com.fqf.mario_qua_mario.MarioQuaMario; +import com.fqf.mario_qua_mario.definitions.actions.*; +import com.fqf.mario_qua_mario.definitions.actions.util.IncompleteActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionInjectionDefinition; +import com.fqf.mario_qua_mario.mariodata.IMarioClientData; +import com.fqf.mario_qua_mario.mariodata.IMarioData; +import com.fqf.mario_qua_mario.mariodata.MarioMoveableData; +import com.fqf.mario_qua_mario.registries.actions.parsed.*; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.random.RandomSeed; + +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +public class ParsedActionHelper { + public static AbstractParsedAction parseAction( + IncompleteActionDefinition definition, + HashMap> allInjections + ) { + return switch (definition) { + case GenericActionDefinition def -> new ParsedGenericAction(def, allInjections); + case GroundedActionDefinition def -> new ParsedGroundedAction(def, allInjections); + case AirborneActionDefinition def -> new ParsedAirborneAction(def, allInjections); + case AquaticActionDefinition def -> new ParsedAquaticAction(def, allInjections); + case WallboundActionDefinition def -> new ParsedWallboundAction(def, allInjections); + default -> null; + }; + } + + public static void attemptTransitions(MarioMoveableData data, TransitionPhase phase) { + for(ParsedTransition transition : data.isClient() ? data.getAction().CLIENT_TRANSITIONS.get(phase) : data.getAction().SERVER_TRANSITIONS.get(phase)) { + if(transition.evaluator().shouldTransition(data)) { + long seed = data.getMario().getRandom().nextLong(); + executeTransition(data, transition, seed); + + if(!data.isClient()) { + // Send S2C transition packet + // If fullyNetworked(), then send the packet to Mario too + } + else if(transition.fullyNetworked()) { + // Send C2S transition packet + } + } + } + } + + public static void executeTransition(IMarioData data, ParsedTransition transition, long seed) { + MarioQuaMario.LOGGER.info("Executing transition for {} on {}:\n\t{} -> {}", + data.getMario().getName().getString(), + data.isClient() ? "CLIENT" : "SERVER", + data.getActionID(), + transition.targetAction().ID + ); + + if(data instanceof MarioMoveableData moveableData && transition.travelExecutor() != null) + transition.travelExecutor().execute(moveableData); + if(data instanceof IMarioClientData clientData && transition.clientsExecutor() != null) + transition.clientsExecutor().execute(clientData, data.getMario().isMainPlayer(), seed); + } +} diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedTransition.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedTransition.java index 097bd23..a3cd831 100644 --- a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedTransition.java +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/ParsedTransition.java @@ -1,20 +1,27 @@ package com.fqf.mario_qua_mario.registries.actions; +import com.fqf.mario_qua_mario.definitions.actions.util.EvaluatorContext; import com.fqf.mario_qua_mario.definitions.actions.util.TransitionDefinition; import com.fqf.mario_qua_mario.registries.RegistryManager; -import net.minecraft.util.Identifier; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Objects; public record ParsedTransition( - @NotNull ParsedAction targetID, + @NotNull AbstractParsedAction targetAction, @NotNull TransitionDefinition.Evaluator evaluator, + boolean fullyNetworked, @Nullable TransitionDefinition.TravelExecutor travelExecutor, @Nullable TransitionDefinition.ClientsExecutor clientsExecutor ) { public ParsedTransition(TransitionDefinition definition) { - this(Objects.requireNonNull(RegistryManager.ACTIONS.get(definition.targetID())), definition.evaluator(), definition.travelExecutor(), definition.clientsExecutor()); + this( + Objects.requireNonNull(RegistryManager.ACTIONS.get(definition.targetID())), + definition.evaluator(), + definition.context() != EvaluatorContext.COMMON, + definition.travelExecutor(), + definition.clientsExecutor() + ); } } 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 new file mode 100644 index 0000000..bd431e6 --- /dev/null +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/UniversalActionDefinitionHelper.java @@ -0,0 +1,101 @@ +package com.fqf.mario_qua_mario.registries.actions; + +import com.fqf.mario_qua_mario.definitions.actions.*; +import com.fqf.mario_qua_mario.definitions.actions.util.IncompleteActionDefinition; +import com.fqf.mario_qua_mario.definitions.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.mariodata.MarioMoveableData; +import com.fqf.mario_qua_mario.util.CharaStat; +import org.jetbrains.annotations.Nullable; + +public class UniversalActionDefinitionHelper implements + GroundedActionDefinition.GroundedActionHelper, + AirborneActionDefinition.AirborneActionHelper, + AquaticActionDefinition.AquaticActionHelper, + WallboundActionDefinition.WallboundActionHelper { + public static final UniversalActionDefinitionHelper INSTANCE = new UniversalActionDefinitionHelper(); + private UniversalActionDefinitionHelper() {} + + @Override + public void groundAccel( + IMarioTravelData data, + CharaStat forwardAccelStat, CharaStat forwardSpeedStat, + CharaStat strafeAccelStat, CharaStat strafeSpeedStat, + double forwardAngleContribution, double strafeAngleContribution, CharaStat redirectStat + ) { + + } + + @Override + public void applyDrag( + IMarioTravelData data, + CharaStat drag, CharaStat dragMin, + double forwardAngleContribution, double strafeAngleContribution, CharaStat redirection + ) { + + } + + @Override public void applyGravity( + IMarioTravelData data, + CharaStat gravity, @Nullable CharaStat jumpingGravity, + CharaStat terminalVelocity + ) { + + } + + @Override public void airborneAccel( + IMarioTravelData data, + CharaStat forwardAccelStat, CharaStat forwardSpeedStat, + CharaStat backwardAccelStat, CharaStat backwardSpeedStat, + CharaStat strafeAccelStat, CharaStat strafeSpeedStat, + double forwardAngleContribution, double strafeAngleContribution, CharaStat redirectStat + ) { + + } + + @Override + public TransitionDefinition makeJumpCapTransition(IncompleteActionDefinition forAction, double capThreshold) { + return null; + } + + @Override + public void applyGravity(IMarioTravelData data, CharaStat gravity, CharaStat terminalVelocity) { + + } + + @Override + public void applyWaterDrag(IMarioTravelData data, CharaStat drag, CharaStat dragMin) { + + } + + @Override + public void aquaticAccel( + IMarioTravelData data, + CharaStat forwardAccelStat, CharaStat forwardSpeedStat, + CharaStat backwardAccelStat, CharaStat backwardSpeedStat, + CharaStat strafeAccelStat, CharaStat strafeSpeedStat, + double forwardAngleContribution, double strafeAngleContribution, CharaStat redirectStat + ) { + + } + + @Override + public WallboundActionDefinition.WallInfo getWallInfo(IMarioReadableMotionData data) { + return ((MarioMoveableData) data).getWallInfo(); + } + + @Override public void climbWall( + IMarioTravelData data, + CharaStat ascendSpeedStat,CharaStat ascendAccelStat, + CharaStat descendSpeedStat, CharaStat descendAccelStat, + CharaStat sidleSpeedStat, CharaStat sidleAccelStat + ) { + + } + + @Override + public void setSidleVel(IMarioTravelData data, double sidleVel) { + + } +} diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedAirborneAction.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedAirborneAction.java new file mode 100644 index 0000000..ca24d78 --- /dev/null +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedAirborneAction.java @@ -0,0 +1,47 @@ +package com.fqf.mario_qua_mario.registries.actions.parsed; + +import com.fqf.mario_qua_mario.definitions.actions.AirborneActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionInjectionDefinition; +import com.fqf.mario_qua_mario.mariodata.MarioMoveableData; +import com.fqf.mario_qua_mario.registries.actions.AbstractParsedAction; +import com.fqf.mario_qua_mario.registries.actions.UniversalActionDefinitionHelper; +import net.minecraft.util.Identifier; + +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +public class ParsedAirborneAction extends AbstractParsedAction { + private final AirborneActionDefinition AIRBORNE_DEFINITION; + + public ParsedAirborneAction(AirborneActionDefinition definition, HashMap> allInjections) { + super(definition, allInjections); + this.AIRBORNE_DEFINITION = definition; + } + + @Override + public void travelHook(MarioMoveableData data) { + this.AIRBORNE_DEFINITION.travelHook(data, UniversalActionDefinitionHelper.INSTANCE); + } + + @Override + protected TransitionInjectionDefinition.ActionCategory getCategory() { + return TransitionInjectionDefinition.ActionCategory.AIRBORNE; + } + + @Override + protected List getBasicTransitions() { + return this.AIRBORNE_DEFINITION.getBasicTransitions(UniversalActionDefinitionHelper.INSTANCE); + } + + @Override + protected List getInputTransitions() { + return this.AIRBORNE_DEFINITION.getInputTransitions(UniversalActionDefinitionHelper.INSTANCE); + } + + @Override + protected List getWorldCollisionTransitions() { + return this.AIRBORNE_DEFINITION.getWorldCollisionTransitions(UniversalActionDefinitionHelper.INSTANCE); + } +} diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedAquaticAction.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedAquaticAction.java new file mode 100644 index 0000000..81e0e55 --- /dev/null +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedAquaticAction.java @@ -0,0 +1,47 @@ +package com.fqf.mario_qua_mario.registries.actions.parsed; + +import com.fqf.mario_qua_mario.definitions.actions.AquaticActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionInjectionDefinition; +import com.fqf.mario_qua_mario.mariodata.MarioMoveableData; +import com.fqf.mario_qua_mario.registries.actions.AbstractParsedAction; +import com.fqf.mario_qua_mario.registries.actions.UniversalActionDefinitionHelper; +import net.minecraft.util.Identifier; + +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +public class ParsedAquaticAction extends AbstractParsedAction { + private final AquaticActionDefinition AQUATIC_DEFINITION; + + public ParsedAquaticAction(AquaticActionDefinition definition, HashMap> allInjections) { + super(definition, allInjections); + this.AQUATIC_DEFINITION = definition; + } + + @Override + public void travelHook(MarioMoveableData data) { + this.AQUATIC_DEFINITION.travelHook(data, UniversalActionDefinitionHelper.INSTANCE); + } + + @Override + protected TransitionInjectionDefinition.ActionCategory getCategory() { + return TransitionInjectionDefinition.ActionCategory.AQUATIC; + } + + @Override + protected List getBasicTransitions() { + return this.AQUATIC_DEFINITION.getBasicTransitions(UniversalActionDefinitionHelper.INSTANCE); + } + + @Override + protected List getInputTransitions() { + return this.AQUATIC_DEFINITION.getInputTransitions(UniversalActionDefinitionHelper.INSTANCE); + } + + @Override + protected List getWorldCollisionTransitions() { + return this.AQUATIC_DEFINITION.getWorldCollisionTransitions(UniversalActionDefinitionHelper.INSTANCE); + } +} \ No newline at end of file diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedGenericAction.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedGenericAction.java new file mode 100644 index 0000000..9f87a08 --- /dev/null +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedGenericAction.java @@ -0,0 +1,46 @@ +package com.fqf.mario_qua_mario.registries.actions.parsed; + +import com.fqf.mario_qua_mario.definitions.actions.GenericActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionInjectionDefinition; +import com.fqf.mario_qua_mario.mariodata.MarioMoveableData; +import com.fqf.mario_qua_mario.registries.actions.AbstractParsedAction; +import net.minecraft.util.Identifier; + +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +public class ParsedGenericAction extends AbstractParsedAction { + private final GenericActionDefinition GENERIC_DEFINITION; + + public ParsedGenericAction(GenericActionDefinition definition, HashMap> allInjections) { + super(definition, allInjections); + this.GENERIC_DEFINITION = definition; + } + + @Override + public void travelHook(MarioMoveableData data) { + this.GENERIC_DEFINITION.travelHook(data); + } + + @Override + protected TransitionInjectionDefinition.ActionCategory getCategory() { + return TransitionInjectionDefinition.ActionCategory.GENERIC; + } + + @Override + protected List getBasicTransitions() { + return this.GENERIC_DEFINITION.getBasicTransitions(); + } + + @Override + protected List getInputTransitions() { + return this.GENERIC_DEFINITION.getInputTransitions(); + } + + @Override + protected List getWorldCollisionTransitions() { + return this.GENERIC_DEFINITION.getWorldCollisionTransitions(); + } +} diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedGroundedAction.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedGroundedAction.java new file mode 100644 index 0000000..eb62507 --- /dev/null +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedGroundedAction.java @@ -0,0 +1,47 @@ +package com.fqf.mario_qua_mario.registries.actions.parsed; + +import com.fqf.mario_qua_mario.definitions.actions.GroundedActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionInjectionDefinition; +import com.fqf.mario_qua_mario.mariodata.MarioMoveableData; +import com.fqf.mario_qua_mario.registries.actions.AbstractParsedAction; +import com.fqf.mario_qua_mario.registries.actions.UniversalActionDefinitionHelper; +import net.minecraft.util.Identifier; + +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +public class ParsedGroundedAction extends AbstractParsedAction { + private final GroundedActionDefinition GROUNDED_DEFINITION; + + public ParsedGroundedAction(GroundedActionDefinition definition, HashMap> allInjections) { + super(definition, allInjections); + this.GROUNDED_DEFINITION = definition; + } + + @Override + public void travelHook(MarioMoveableData data) { + this.GROUNDED_DEFINITION.travelHook(data, UniversalActionDefinitionHelper.INSTANCE); + } + + @Override + protected TransitionInjectionDefinition.ActionCategory getCategory() { + return TransitionInjectionDefinition.ActionCategory.GROUNDED; + } + + @Override + protected List getBasicTransitions() { + return this.GROUNDED_DEFINITION.getBasicTransitions(UniversalActionDefinitionHelper.INSTANCE); + } + + @Override + protected List getInputTransitions() { + return this.GROUNDED_DEFINITION.getInputTransitions(UniversalActionDefinitionHelper.INSTANCE); + } + + @Override + protected List getWorldCollisionTransitions() { + return this.GROUNDED_DEFINITION.getWorldCollisionTransitions(UniversalActionDefinitionHelper.INSTANCE); + } +} diff --git a/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedWallboundAction.java b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedWallboundAction.java new file mode 100644 index 0000000..7e6a7ea --- /dev/null +++ b/mod/src/main/java/com/fqf/mario_qua_mario/registries/actions/parsed/ParsedWallboundAction.java @@ -0,0 +1,47 @@ +package com.fqf.mario_qua_mario.registries.actions.parsed; + +import com.fqf.mario_qua_mario.definitions.actions.WallboundActionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionDefinition; +import com.fqf.mario_qua_mario.definitions.actions.util.TransitionInjectionDefinition; +import com.fqf.mario_qua_mario.mariodata.MarioMoveableData; +import com.fqf.mario_qua_mario.registries.actions.AbstractParsedAction; +import com.fqf.mario_qua_mario.registries.actions.UniversalActionDefinitionHelper; +import net.minecraft.util.Identifier; + +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +public class ParsedWallboundAction extends AbstractParsedAction { + private final WallboundActionDefinition WALLBOUND_DEFINITION; + + public ParsedWallboundAction(WallboundActionDefinition definition, HashMap> allInjections) { + super(definition, allInjections); + this.WALLBOUND_DEFINITION = definition; + } + + @Override + public void travelHook(MarioMoveableData data) { + this.WALLBOUND_DEFINITION.travelHook(data, data.getWallInfo(), UniversalActionDefinitionHelper.INSTANCE); + } + + @Override + protected TransitionInjectionDefinition.ActionCategory getCategory() { + return TransitionInjectionDefinition.ActionCategory.WALL; + } + + @Override + protected List getBasicTransitions() { + return this.WALLBOUND_DEFINITION.getBasicTransitions(UniversalActionDefinitionHelper.INSTANCE); + } + + @Override + protected List getInputTransitions() { + return this.WALLBOUND_DEFINITION.getInputTransitions(UniversalActionDefinitionHelper.INSTANCE); + } + + @Override + protected List getWorldCollisionTransitions() { + return this.WALLBOUND_DEFINITION.getWorldCollisionTransitions(UniversalActionDefinitionHelper.INSTANCE); + } +} diff --git a/mod/src/main/resources/fabric.mod.json b/mod/src/main/resources/fabric.mod.json index 6cc53b6..13ecd30 100644 --- a/mod/src/main/resources/fabric.mod.json +++ b/mod/src/main/resources/fabric.mod.json @@ -15,6 +15,9 @@ "icon": "assets/mario_qua_mario/icon.png", "environment": "*", "entrypoints": { + "mqm-miscellaneous-actions": [ + ], + "main": [ "com.fqf.mario_qua_mario.MarioQuaMario" ],