Skip to content

Commit

Permalink
Implemented extensible, category-based Stats system
Browse files Browse the repository at this point in the history
  • Loading branch information
floral-qua-floral committed Oct 26, 2024
1 parent fc0392f commit ed5ae50
Show file tree
Hide file tree
Showing 24 changed files with 394 additions and 289 deletions.
3 changes: 2 additions & 1 deletion src/main/java/com/floralquafloral/MarioPackets.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.floralquafloral;

import com.floralquafloral.mariodata.MarioDataManager;
import com.floralquafloral.mariodata.MarioDataPackets;
import com.floralquafloral.registries.stomp.StompHandler;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
Expand Down Expand Up @@ -64,7 +65,7 @@ public record SyncUseCharacterStatsS2CPayload(boolean useCharacterStats) impleme
);
public static void registerReceiver() {
ClientPlayNetworking.registerGlobalReceiver(ID, (payload, context) ->
MarioQuaMarioClient.useCharacterStats = payload.useCharacterStats);
MarioDataManager.useCharacterStats = payload.useCharacterStats);
}

@Override public Id<? extends CustomPayload> getId() {
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/floralquafloral/MarioQuaMario.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ public class MarioQuaMario implements ModInitializer {
public static final GameRules.Key<GameRules.BooleanRule> USE_CHARACTER_STATS =
GameRuleRegistry.register("qua_mario:useCharacterStats", GameRules.Category.PLAYER,
GameRuleFactory.createBooleanRule(true, (server, booleanRule) -> {
MarioDataManager.useCharacterStats = booleanRule.get();
for(ServerPlayerEntity player : PlayerLookup.all(server)) {
ServerPlayNetworking.send(player, new MarioPackets.SyncUseCharacterStatsS2CPayload(true));
ServerPlayNetworking.send(player, new MarioPackets.SyncUseCharacterStatsS2CPayload(booleanRule.get()));
}
})
);
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/floralquafloral/MarioQuaMarioClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import java.util.List;

public class MarioQuaMarioClient implements ClientModInitializer {
public static boolean useCharacterStats = true;

public static final SimpleOption<Boolean> ALWAYS_FALSE = SimpleOption.ofBoolean("alwaysFalseOption", false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@
public class MarioDataManager {
private static final Map<PlayerEntity, MarioData> SERVER_PLAYERS_DATA = new HashMap<>();
private static final Map<PlayerEntity, MarioData> CLIENT_PLAYERS_DATA = new HashMap<>();
public static boolean useCharacterStats = true;

public static void registerEventListeners() {
ServerLifecycleEvents.SERVER_STARTING.register((server) -> wipePlayerData());
ServerLifecycleEvents.SERVER_STARTED.register((server) -> {
useCharacterStats = server.getGameRules().getBoolean(MarioQuaMario.USE_CHARACTER_STATS);
wipePlayerData();
});

ServerPlayerEvents.AFTER_RESPAWN.register((oldPlayer, newPlayer, alive) -> {
MarioQuaMario.LOGGER.info("Player respawned!"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.floralquafloral.registries.states.action.ParsedAction;
import com.floralquafloral.registries.states.character.ParsedCharacter;
import com.floralquafloral.registries.states.powerup.ParsedPowerUp;
import com.floralquafloral.stats.CharaStat;
import com.floralquafloral.util.CPMIntegration;
import com.floralquafloral.util.MarioSFX;
import net.minecraft.block.BlockState;
Expand Down Expand Up @@ -269,12 +270,14 @@ private void makeSkidSFX(boolean isWall) {
this.mario.setHealth(this.mario.getMaxHealth());
this.powerUp = powerUp;
this.mario.calculateDimensions();
CharaStat.invalidateCache();
}
@Override public ParsedCharacter getCharacter() {
return character;
}
@Override public void setCharacter(ParsedCharacter character) {
this.character = character;
this.mario.calculateDimensions();
CharaStat.invalidateCache();
}
}
37 changes: 14 additions & 23 deletions src/main/java/com/floralquafloral/mixin/PlayerEntityMixin.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
package com.floralquafloral.mixin;

import com.floralquafloral.MarioQuaMario;
import com.floralquafloral.mariodata.MarioData;
import com.floralquafloral.mariodata.client.MarioClientData;
import com.floralquafloral.mariodata.MarioDataManager;
import com.floralquafloral.registries.states.character.ParsedCharacter;
import com.floralquafloral.registries.states.powerup.ParsedPowerUp;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityPose;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.Vec3d;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
Expand Down Expand Up @@ -45,33 +41,28 @@ private void preventVanillaJumpingSwimming(CallbackInfoReturnable<Boolean> cir)
private void getBaseDimensions(EntityPose pose, CallbackInfoReturnable<EntityDimensions> cir) {
MarioData data = MarioDataManager.getMarioData(this);
if(data.isEnabled()) {
// Returns the standing hitbox if being used by Mario on the client side while he can't sneak
// Returns the standing hitbox if being used by Mario while he can't sneak
if(data.getSneakProhibited() && pose == EntityPose.CROUCHING) {
cir.setReturnValue(data.getMario().getBaseDimensions(EntityPose.STANDING));
return;
}

cir.setReturnValue(getModifiedDimensions(pose, cir, data));
}
}
ParsedPowerUp powerUp = data.getPowerUp();
ParsedCharacter character = data.getCharacter();

@Unique
private static @NotNull EntityDimensions getModifiedDimensions(EntityPose pose, CallbackInfoReturnable<EntityDimensions> cir, MarioData data) {
ParsedPowerUp powerUp = data.getPowerUp();
ParsedCharacter character = data.getCharacter();
float widthFactor = powerUp.WIDTH_FACTOR * character.WIDTH_FACTOR;
float heightFactor = powerUp.HEIGHT_FACTOR * character.HEIGHT_FACTOR;
if(pose == EntityPose.CROUCHING) heightFactor *= 0.6F;

float widthFactor = powerUp.WIDTH_FACTOR;
float heightFactor = powerUp.HEIGHT_FACTOR;
if(pose == EntityPose.CROUCHING) heightFactor *= 0.6F;
EntityDimensions resultDimensions = cir.getReturnValue();

EntityDimensions resultDimensions = cir.getReturnValue();

return new EntityDimensions(
resultDimensions.width() * widthFactor,
resultDimensions.height() * heightFactor,
resultDimensions.eyeHeight() * heightFactor,
resultDimensions.attachments(), resultDimensions.fixed()
);
cir.setReturnValue(new EntityDimensions(
resultDimensions.width() * widthFactor,
resultDimensions.height() * heightFactor,
resultDimensions.eyeHeight() * heightFactor,
resultDimensions.attachments(), resultDimensions.fixed()
));
}
}

@Inject(method = "clipAtLedge", at = @At("HEAD"), cancellable = true)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.floralquafloral.registries.states;

import com.floralquafloral.stats.BaseStats;
import com.floralquafloral.stats.StatCategory;

import java.util.EnumMap;
import java.util.Map;
import java.util.Set;

public interface MarioMajorStateDefinition extends MarioStateDefinition {
void populateStatFactors(EnumMap<BaseStats, Double> statFactorMap);
void populateStatModifiers(Map<Set<StatCategory>, Double> modifiers);

float getWidthFactor();
float getHeightFactor();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
package com.floralquafloral.registries.states;

import com.floralquafloral.stats.BaseStats;
import com.floralquafloral.stats.StatCategory;

import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public abstract class ParsedMajorMarioState extends ParsedMarioState {
public final float WIDTH_FACTOR;
public final float HEIGHT_FACTOR;
public final EnumMap<BaseStats, Double> STAT_FACTORS;
public final Map<Set<StatCategory>, Double> STAT_MODIFIERS;

protected ParsedMajorMarioState(MarioMajorStateDefinition definition) {
super(definition);

this.WIDTH_FACTOR = definition.getWidthFactor();
this.HEIGHT_FACTOR = definition.getHeightFactor();
this.STAT_FACTORS = new EnumMap<>(BaseStats.class);
definition.populateStatFactors(this.STAT_FACTORS);
this.STAT_MODIFIERS = new HashMap<>();
definition.populateStatModifiers(this.STAT_MODIFIERS);
// this.STAT_FACTORS = new EnumMap<>(BaseStats.class);
// definition.populateStatFactors(this.STAT_FACTORS);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.floralquafloral.mariodata.client.Input;
import com.floralquafloral.mariodata.client.MarioClientData;
import com.floralquafloral.stats.CharaStat;
import com.floralquafloral.stats.OldCharaStat;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -38,20 +38,20 @@ public abstract static class AerialTransitions {
);
}

private final @NotNull CharaStat GRAVITY = getGravity();
private final @NotNull CharaStat JUMP_GRAVITY = getJumpGravity();
private final @Nullable CharaStat JUMP_CAP = getJumpCap();
private final @NotNull OldCharaStat GRAVITY = getGravity();
private final @NotNull OldCharaStat JUMP_GRAVITY = getJumpGravity();
private final @Nullable OldCharaStat JUMP_CAP = getJumpCap();
//TODO: Make Grounded states use CharaStats as well!

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

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

CharaStat useGravity = aboveJumpCap ? JUMP_GRAVITY : GRAVITY;
OldCharaStat useGravity = aboveJumpCap ? JUMP_GRAVITY : GRAVITY;
yVel += useGravity.getValue(data);
if(aboveJumpCap && !Input.JUMP.isHeld() && !jumpCapped) {
yVel = JUMP_CAP.getValue(data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
import com.floralquafloral.mariodata.MarioData;
import com.floralquafloral.mariodata.client.Input;
import com.floralquafloral.mariodata.client.MarioClientData;
import com.floralquafloral.stats.CharaStat;
import com.floralquafloral.util.MarioSFX;
import net.minecraft.util.math.BlockPos;
import org.joml.Vector2d;

import static com.floralquafloral.MarioQuaMario.LOGGER;

public abstract class GroundedActionDefinition implements ActionDefinition {
public static final CharaStat ZERO = new CharaStat(0.0);

public abstract static class GroundedTransitions {
public static final ActionTransitionDefinition FALL = new ActionTransitionDefinition(
"qua_mario:fall",
Expand Down Expand Up @@ -49,36 +52,37 @@ public abstract static class GroundedTransitions {

public void groundAccel(
MarioClientData data,
double forwardAccel, double forwardTarget, double strafeAccel, double strafeTarget,
double forwardAngleContribution, double strafeAngleContribution, double redirectDelta
CharaStat forwardAccel, CharaStat forwardTarget, CharaStat strafeAccel, CharaStat strafeTarget,
double forwardAngleContribution, double strafeAngleContribution, CharaStat redirectDelta
) {
double slipFactor = getSlipFactor(data);
data.approachAngleAndAccel(
forwardAccel * slipFactor, forwardTarget * Input.getForwardInput(),
strafeAccel * slipFactor, strafeTarget * Input.getStrafeInput(),
forwardAngleContribution, strafeAngleContribution, redirectDelta * slipFactor
forwardAccel.get(data) * slipFactor, forwardTarget.get(data) * Input.getForwardInput(),
strafeAccel.get(data) * slipFactor, strafeTarget.get(data) * Input.getStrafeInput(),
forwardAngleContribution, strafeAngleContribution, redirectDelta.get(data) * slipFactor
);
}

public void applyDrag(
MarioClientData data,
double drag, double dragMin,
CharaStat drag, CharaStat dragMin,
double forwardAngleContribution, double strafeAngleContribution,
double redirection
CharaStat redirection
) {
boolean dragInverted = drag < 0;
double dragValue = drag.get(data);
boolean dragInverted = dragValue < 0;
double slipFactor = getSlipFactor(data);
dragMin *= slipFactor;
if(!dragInverted) drag *= slipFactor;
double dragMinValue = dragMin.get(data) * slipFactor;
if(!dragInverted) dragValue *= slipFactor;


Vector2d deltaVelocities = new Vector2d(
-drag * data.getForwardVel(),
-drag * data.getStrafeVel()
-dragValue * data.getForwardVel(),
-dragValue * data.getStrafeVel()
);
double dragVelocitySquared = deltaVelocities.lengthSquared();
if(dragVelocitySquared != 0 && dragVelocitySquared < dragMin * dragMin)
deltaVelocities.normalize(dragMin);
if(dragVelocitySquared != 0 && dragVelocitySquared < dragMinValue * dragMinValue)
deltaVelocities.normalize(dragMinValue);

if(dragInverted) {
data.setForwardStrafeVel(data.getForwardVel() + deltaVelocities.x, data.getStrafeVel() + deltaVelocities.y);
Expand All @@ -89,7 +93,7 @@ public void applyDrag(
deltaVelocities.y, 0,
forwardAngleContribution,
strafeAngleContribution,
redirection * slipFactor
redirection.get(data) * slipFactor
);
}
}
Expand Down
Loading

0 comments on commit ed5ae50

Please sign in to comment.