updating buff and debuff icons. separated COA classes from WoW classes on the character creation screen

This commit is contained in:
phenom committed 2026-08-16 11:16:51 -04:00
1 parent b5c9bce1aa
commit c00f3211ea
39 files changed
+2037 -208

No files matched your search

+94
View File
@@ -0,0 +1,94 @@
export const PLAYER_JUMP_VELOCITY = 7.2;
export const PLAYER_JUMP_COYOTE_MS = 100;
export const PLAYER_JUMP_BUFFER_MS = 120;
export const PLAYER_JUMP_LANDING_UNLOCK_MS = 80;
export const PLAYER_LANDING_PRESENTATION_MS = 180;
export const PLAYER_GROUND_PROBE_DISTANCE = 0.14;
export const PLAYER_GROUND_MIN_NORMAL_Y = 0.55;
export type CharacterVerticalMotion = "grounded" | "rising" | "falling" | "landing";
export interface PlayerJumpTiming {
lastGroundedAtMs: number;
bufferedUntilMs: number;
jumpedAtMs: number;
lockedUntilLanding: boolean;
}
export interface GroundProbeHit {
readonly timeOfImpact: number;
readonly normal: { readonly y: number };
}
export function createPlayerJumpTiming(nowMs = Number.NEGATIVE_INFINITY): PlayerJumpTiming {
return {
lastGroundedAtMs: nowMs,
bufferedUntilMs: Number.NEGATIVE_INFINITY,
jumpedAtMs: Number.NEGATIVE_INFINITY,
lockedUntilLanding: false,
};
}
export function bufferPlayerJump(timing: PlayerJumpTiming, requestedAtMs: number): void {
if (!Number.isFinite(requestedAtMs)) return;
timing.bufferedUntilMs = requestedAtMs + PLAYER_JUMP_BUFFER_MS;
}
export function cancelBufferedPlayerJump(timing: PlayerJumpTiming): void {
timing.bufferedUntilMs = Number.NEGATIVE_INFINITY;
}
export function isWalkableGroundHit(
hit: GroundProbeHit | null | undefined,
maximumTimeOfImpact: number,
): boolean {
return Boolean(
hit
&& Number.isFinite(hit.timeOfImpact)
&& hit.timeOfImpact >= 0
&& hit.timeOfImpact <= maximumTimeOfImpact
&& Number.isFinite(hit.normal.y)
&& hit.normal.y >= PLAYER_GROUND_MIN_NORMAL_Y,
);
}
/**
* Updates the timing latch and consumes a buffered jump exactly once. The
* upward-velocity guard prevents the ground probe from unlocking the latch on
* the first few frames after launch while the capsule is still near the floor.
*/
export function updatePlayerJumpTiming(
timing: PlayerJumpTiming,
nowMs: number,
grounded: boolean,
verticalVelocity: number,
): boolean {
if (!Number.isFinite(nowMs)) return false;
if (grounded && verticalVelocity <= 0.5) {
timing.lastGroundedAtMs = nowMs;
if (
timing.lockedUntilLanding
&& nowMs - timing.jumpedAtMs >= PLAYER_JUMP_LANDING_UNLOCK_MS
) timing.lockedUntilLanding = false;
}
const buffered = timing.bufferedUntilMs >= nowMs;
const insideCoyoteWindow = nowMs - timing.lastGroundedAtMs <= PLAYER_JUMP_COYOTE_MS;
if (timing.lockedUntilLanding || !buffered || !insideCoyoteWindow) return false;
timing.lockedUntilLanding = true;
timing.jumpedAtMs = nowMs;
timing.bufferedUntilMs = Number.NEGATIVE_INFINITY;
return true;
}
export function characterVerticalMotion(
grounded: boolean,
verticalVelocity: number,
nowMs: number,
landingUntilMs: number,
): CharacterVerticalMotion {
if (grounded) return nowMs < landingUntilMs ? "landing" : "grounded";
return verticalVelocity > 0.15 ? "rising" : "falling";
}