Skip to content

Commit

Permalink
Added aerial state system (Fall and Jump implemented)
Browse files Browse the repository at this point in the history
  • Loading branch information
floral-qua-floral committed Oct 27, 2024
1 parent c94d2c8 commit fefa871
Show file tree
Hide file tree
Showing 10 changed files with 420 additions and 29 deletions.
3 changes: 3 additions & 0 deletions src/main/java/com/floralquafloral/MarioPackets.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.floralquafloral.mariodata.MarioDataManager;
import com.floralquafloral.mariodata.MarioDataPackets;
import com.floralquafloral.registries.stomp.StompHandler;
import com.floralquafloral.util.JumpSoundPlayer;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.PlayerLookup;
Expand All @@ -24,6 +25,7 @@ public static void registerCommon() {
MarioDataPackets.registerCommon();
StompHandler.registerPackets();
VoiceLine.registerPackets();
JumpSoundPlayer.registerPackets();

ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
MarioQuaMario.LOGGER.info("");
Expand All @@ -34,6 +36,7 @@ public static void registerClient() {
MarioDataPackets.registerClient();
StompHandler.registerPacketsClient();
VoiceLine.registerPacketsClient();
JumpSoundPlayer.registerPacketsClient();
}

public static PlayerEntity getPlayerFromInt(ClientPlayNetworking.Context context, int playerID) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

import com.floralquafloral.mariodata.client.Input;
import com.floralquafloral.mariodata.client.MarioClientData;
import com.floralquafloral.stats.OldCharaStat;
import com.floralquafloral.stats.CharaStat;
import com.floralquafloral.stats.StatCategory;
import com.floralquafloral.util.ClientSoundPlayer;
import com.floralquafloral.util.JumpSoundPlayer;
import com.floralquafloral.util.MarioSFX;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import static com.floralquafloral.stats.StatCategory.*;

public abstract class AirborneActionDefinition implements ActionDefinition {
public static boolean jumpCapped;

Expand All @@ -21,9 +27,7 @@ public abstract static class AerialTransitions {
if(isSelf && data instanceof MarioClientData clientData)
clientData.jumpLandingTime = 5;
},
(data, seed) -> {

}
null
);
public static final ActionTransitionDefinition TRIPLE_JUMPABLE_LANDING = new ActionTransitionDefinition(
"qua_mario:basic",
Expand All @@ -32,34 +36,128 @@ public abstract static class AerialTransitions {
if(isSelf && data instanceof MarioClientData clientData)
clientData.doubleJumpLandingTime = 5;
},
(data, seed) -> {
null
);

}
public static final ActionTransitionDefinition GROUND_POUND = new ActionTransitionDefinition(
"qua_mario:ground_pound",
data -> Input.DUCK.isPressed(),
(data, isSelf, seed) -> ClientSoundPlayer.playSound(MarioSFX.GROUND_POUND_PRE, data, seed),
null
);
}

private final @NotNull OldCharaStat GRAVITY = getGravity();
private final @NotNull OldCharaStat JUMP_GRAVITY = getJumpGravity();
private final @Nullable OldCharaStat JUMP_CAP = getJumpCap();
public abstract static class AerialStats {
public static final CharaStat GRAVITY = new CharaStat(-0.115, NORMAL_GRAVITY);
public static final CharaStat TERMINAL_VELOCITY = new CharaStat(-3.25, StatCategory.TERMINAL_VELOCITY);

public static final CharaStat JUMP_GRAVITY = new CharaStat(-0.095, JUMPING_GRAVITY);
public static final CharaStat JUMP_CAP = new CharaStat(0.39, StatCategory.JUMP_CAP);

public static final CharaStat FORWARD_DRIFT_ACCEL = new CharaStat(0.04, DRIFTING, FORWARD, ACCELERATION);
public static final CharaStat FORWARD_DRIFT_SPEED = new CharaStat(0.275, DRIFTING, FORWARD, SPEED);

public static final CharaStat BACKWARD_DRIFT_ACCEL = new CharaStat(0.05, DRIFTING, BACKWARD, ACCELERATION);
public static final CharaStat BACKWARD_DRIFT_SPEED = new CharaStat(0.2, DRIFTING, BACKWARD, SPEED);

public static final CharaStat STRAFE_DRIFT_ACCEL = new CharaStat(0.04, DRIFTING, STRAFE, ACCELERATION);
public static final CharaStat STRAFE_DRIFT_SPEED = new CharaStat(0.2, DRIFTING, STRAFE, SPEED);

public static final CharaStat DRIFT_REDIRECTION = new CharaStat(6.0, DRIFTING, REDIRECTION);
}

private final @NotNull CharaStat ACTION_GRAVITY = getGravity();
private final @Nullable CharaStat ACTION_JUMP_GRAVITY = getJumpGravity();
private final @NotNull CharaStat ACTION_TERMINAL_VELOCITY = getTerminalVelocity();
private final @Nullable CharaStat ACTION_JUMP_CAP = getJumpCap();

protected abstract @NotNull OldCharaStat getGravity();
protected abstract @NotNull OldCharaStat getJumpGravity();
protected abstract @Nullable OldCharaStat getJumpCap();
protected abstract @NotNull CharaStat getGravity();
protected abstract @Nullable CharaStat getJumpGravity();
protected abstract @NotNull CharaStat getTerminalVelocity();
protected abstract @Nullable CharaStat getJumpCap();

@Override public final void selfTick(MarioClientData data) {
double yVel = data.getYVel();
boolean aboveJumpCap = JUMP_CAP != null && yVel > JUMP_CAP.getValue(data);
double terminalVelocity = ACTION_TERMINAL_VELOCITY.get(data);

if(yVel > terminalVelocity) {
boolean aboveJumpCap = ACTION_JUMP_CAP != null && ACTION_JUMP_GRAVITY != null && yVel > ACTION_JUMP_CAP.get(data);

CharaStat useGravity = aboveJumpCap ? ACTION_JUMP_GRAVITY : ACTION_GRAVITY;
yVel += useGravity.get(data);

OldCharaStat useGravity = aboveJumpCap ? JUMP_GRAVITY : GRAVITY;
yVel += useGravity.getValue(data);
if(aboveJumpCap && !Input.JUMP.isHeld() && !jumpCapped) {
yVel = JUMP_CAP.getValue(data);
jumpCapped = true;
if(!jumpCapped) {
if(!aboveJumpCap) {
jumpCapped = true;
JumpSoundPlayer.fadeJumpSfx(data);
}
else if(!Input.JUMP.isHeld()) {
yVel = ACTION_JUMP_CAP.get(data);
jumpCapped = true;
JumpSoundPlayer.fadeJumpSfx(data);
}
}

data.setYVel(Math.max(terminalVelocity, yVel));
}

data.setYVel(yVel);
aerialSelfTick();
aerialSelfTick(data);
}

public abstract void aerialSelfTick();
public abstract void aerialSelfTick(MarioClientData data);

public static void airborneAccel(
MarioClientData data,
CharaStat accelStat, CharaStat speedStat,
CharaStat strafeAccelStat, CharaStat strafeSpeedStat,
double forwardAngleContribution, double strafeAngleContribution, CharaStat redirectStat
) {
double forwardInput = Input.getForwardInput();
double strafeInput = Input.getStrafeInput();
double forwardVel = data.getForwardVel();
double strafeVel = data.getStrafeVel();

double accelValue, strafeAccelValue;

if(forwardInput != 0 && (Math.signum(forwardVel) != Math.signum(forwardInput) || Math.abs(forwardVel) < Math.abs(speedStat.get(data))))
accelValue = accelStat.get(data) * forwardInput;
else accelValue = 0;

if(strafeInput != 0 && (Math.signum(strafeVel) != Math.signum(strafeInput) || Math.abs(strafeVel) < Math.abs(strafeSpeedStat.get(data))))
strafeAccelValue = strafeAccelStat.get(data) * strafeInput;
else strafeAccelValue = 0;

data.approachAngleAndAccel(
accelValue, speedStat.get(data) * Math.signum(forwardInput),
strafeAccelValue, strafeSpeedStat.get(data) * Math.signum(strafeInput),
forwardAngleContribution * forwardInput,
strafeAngleContribution * strafeInput,
redirectStat.get(data)
);
}
public static void airborneAccel(
MarioClientData data,
CharaStat forwardAccelStat, CharaStat forwardSpeedStat,
CharaStat backwardAccelStat, CharaStat backwardSpeedStat,
CharaStat strafeAccelStat, CharaStat strafeSpeedStat,
double forwardAngleContribution, double strafeAngleContribution, CharaStat redirectStat
) {
// Unlike when on the ground, when Mario is in midair, neutral inputs don't cause him to accelerate towards 0.
// He only accelerates when actively making an input, and will always try to accelerate in that direction, never backwards.
boolean forwards = Input.getForwardInput() >= 0;
airborneAccel(data,
forwards ? forwardAccelStat : backwardAccelStat,
forwards ? forwardSpeedStat : backwardSpeedStat,
strafeAccelStat, strafeSpeedStat,
forwardAngleContribution, strafeAngleContribution, redirectStat
);
}
public static void airborneAccel(MarioClientData data) {
airborneAccel(data,
AerialStats.FORWARD_DRIFT_ACCEL, AerialStats.FORWARD_DRIFT_SPEED,
AerialStats.BACKWARD_DRIFT_ACCEL, AerialStats.BACKWARD_DRIFT_SPEED,
AerialStats.STRAFE_DRIFT_ACCEL, AerialStats.STRAFE_DRIFT_SPEED,
Input.getForwardInput(), Input.getStrafeInput(), AerialStats.DRIFT_REDIRECTION
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@
import com.floralquafloral.mariodata.MarioData;
import com.floralquafloral.mariodata.client.Input;
import com.floralquafloral.mariodata.client.MarioClientData;
import com.floralquafloral.registries.states.action.baseactions.airborne.Jump;
import com.floralquafloral.registries.states.action.baseactions.grounded.PRun;
import com.floralquafloral.stats.CharaStat;
import com.floralquafloral.util.ClientSoundPlayer;
import com.floralquafloral.util.JumpSoundPlayer;
import com.floralquafloral.util.MarioSFX;
import net.minecraft.sound.SoundCategory;
import net.minecraft.util.math.BlockPos;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector2d;

import static com.floralquafloral.MarioQuaMario.LOGGER;
Expand All @@ -17,32 +21,45 @@ public abstract class GroundedActionDefinition implements ActionDefinition {
public static final CharaStat ZERO = new CharaStat(0.0);

public abstract static class GroundedTransitions {
public static void performJump(MarioData data, CharaStat velocityStat, @Nullable CharaStat addendStat,
long seed, boolean playSound) {
if(data.getMario().isMainPlayer() || !data.getMario().getWorld().isClient) {
double jumpVel = velocityStat.get(data);
if(addendStat != null)
jumpVel += Math.max(0.0, data.getForwardVel() / PRun.P_SPEED.get(data)) * addendStat.get(data);

data.setYVel(jumpVel);
}

if(data.getMario().getWorld().isClient && playSound) JumpSoundPlayer.playJumpSfx(data, seed);
}

public static final ActionTransitionDefinition FALL = new ActionTransitionDefinition(
"qua_mario:fall",
(data) -> !data.getMario().isOnGround()
);

public static final ActionTransitionDefinition JUMP = new ActionTransitionDefinition(
"qua_mario:jump",
(data) -> Input.DUCK.isHeld()
// double threshold = DUCK_SLIDE_THRESHOLD.get(data);
// return Input.DUCK.isHeld() && Vector2d.lengthSquared(data.getForwardVel(), data.getStrafeVel()) > threshold * threshold;
(data) -> Input.JUMP.isPressed(),
(data, isSelf, seed) -> performJump(data, Jump.JUMP_VEL, Jump.JUMP_ADDEND, seed, true),
(data, seed) -> performJump(data, Jump.JUMP_VEL, Jump.JUMP_ADDEND, seed, false)
);

public static final ActionTransitionDefinition DUCK_WADDLE = new ActionTransitionDefinition(
"qua_mario:duck_waddle",
(data) -> Input.DUCK.isHeld(),
(data, isSelf, seed) -> {
// Play duck voiceline
ClientSoundPlayer.playSound(MarioSFX.DUCK, data, seed);
ClientSoundPlayer.playSound(MarioSFX.DUCK, data, 0.5F, 1.0F, seed);
VoiceLine.DUCK.play(data, seed);
},
null
);
}

@Override public final void selfTick(MarioClientData data) {
data.setYVel(data.getYVel() - 0.05);
data.setYVel(data.getYVel() - 0.01);
AirborneActionDefinition.jumpCapped = false;
this.groundedSelfTick(data);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.floralquafloral.registries.states.action.baseactions.airborne;

import com.floralquafloral.MarioQuaMario;
import com.floralquafloral.mariodata.MarioPlayerData;
import com.floralquafloral.mariodata.client.MarioClientData;
import com.floralquafloral.registries.states.action.AirborneActionDefinition;
import com.floralquafloral.stats.CharaStat;
import net.minecraft.util.Identifier;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public class Fall extends AirborneActionDefinition {
@Override public @NotNull Identifier getID() {
return Identifier.of(MarioQuaMario.MOD_ID, "fall");
}
@Override public @Nullable String getAnimationName() {
return "";
}

@Override public SneakLegalityRule getSneakLegalityRule() {
return SneakLegalityRule.PROHIBIT;
}
@Override public SlidingStatus getConstantSlidingStatus() {
return SlidingStatus.NOT_SLIDING;
}
@Override public @Nullable Identifier getStompType() {
return Identifier.of("qua_mario", "stomp");
}

@Override protected @NotNull CharaStat getGravity() {
return AerialStats.GRAVITY;
}
@Override protected @Nullable CharaStat getJumpGravity() {
return null;
}
@Override protected @NotNull CharaStat getTerminalVelocity() {
return AerialStats.TERMINAL_VELOCITY;
}
@Override protected @Nullable CharaStat getJumpCap() {
return null;
}

@Override public void aerialSelfTick(MarioClientData data) {
airborneAccel(data);
}

@Override public void otherClientsTick(MarioPlayerData data) {

}

@Override public void serverTick(MarioPlayerData data) {

}

@Override public List<ActionTransitionDefinition> getPreTickTransitions() {
return List.of(
AerialTransitions.BASIC_LANDING
);
}

@Override public List<ActionTransitionDefinition> getPostTickTransitions() {
return List.of();
}

@Override public List<ActionTransitionDefinition> getPostMoveTransitions() {
return List.of();
}

@Override public List<ActionTransitionInjection> getTransitionInjections() {
return List.of();
}
}
Loading

0 comments on commit fefa871

Please sign in to comment.