forked from phenom/healer-man
updating buff and debuff icons. separated COA classes from WoW classes on the character creation screen
This commit is contained in:
1 parent
b5c9bce1aa
commit
c00f3211ea
39 files changed
+2037
-208
No files matched your search
+90
-9
@@ -13,7 +13,12 @@ import { useShellStore } from "../app/shellStore";
|
||||
import type { CharacterProfile } from "../app/types";
|
||||
import { CharacterModel } from "../avatar/CharacterModel";
|
||||
import { ProceduralAvatar } from "../avatar/ProceduralAvatar";
|
||||
import { consumeMouseLook, readInputSnapshot } from "../game/inputManager";
|
||||
import {
|
||||
clearJumpRequest,
|
||||
consumeJumpRequest,
|
||||
consumeMouseLook,
|
||||
readInputSnapshot,
|
||||
} from "../game/inputManager";
|
||||
import { useCombatStore } from "../game/combatStore";
|
||||
import type { CharacterCombatAnimationEvent } from "../game/combatAnimation";
|
||||
import {
|
||||
@@ -33,6 +38,18 @@ import {
|
||||
isBelowDungeonRecoveryPlane,
|
||||
isBelowManastormRecoveryPlane,
|
||||
} from "../game/playerRecovery";
|
||||
import {
|
||||
PLAYER_GROUND_PROBE_DISTANCE,
|
||||
PLAYER_JUMP_VELOCITY,
|
||||
PLAYER_LANDING_PRESENTATION_MS,
|
||||
bufferPlayerJump,
|
||||
cancelBufferedPlayerJump,
|
||||
characterVerticalMotion,
|
||||
createPlayerJumpTiming,
|
||||
isWalkableGroundHit,
|
||||
updatePlayerJumpTiming,
|
||||
type CharacterVerticalMotion,
|
||||
} from "../game/playerJump";
|
||||
import { activeManastormStageAssetPackage } from "../game/manastormStageLoader";
|
||||
import { useGameStore } from "../game/store";
|
||||
|
||||
@@ -62,6 +79,7 @@ interface PlayerControllerProps extends PlayerRigRefs {
|
||||
identity: CharacterProfile | null;
|
||||
equipmentItems: readonly InventoryItem[];
|
||||
movingRef: React.MutableRefObject<boolean>;
|
||||
verticalMotionRef: React.MutableRefObject<CharacterVerticalMotion>;
|
||||
animationEventRef: React.MutableRefObject<CharacterCombatAnimationEvent | null>;
|
||||
}
|
||||
|
||||
@@ -85,6 +103,7 @@ function PlayerController({
|
||||
identity,
|
||||
equipmentItems,
|
||||
movingRef,
|
||||
verticalMotionRef,
|
||||
animationEventRef,
|
||||
}: PlayerControllerProps) {
|
||||
const paused = useGameStore((state) => state.paused);
|
||||
@@ -98,11 +117,24 @@ function PlayerController({
|
||||
const spawn = useGameStore((state) => state.activeSpawn);
|
||||
const dungeon = requireDungeonDefinition(activeDungeonId);
|
||||
const lastReported = useRef<[number, number, number]>([...spawn.footPosition]);
|
||||
const { rapier, world } = useRapier();
|
||||
const groundRay = useMemo(
|
||||
() => new rapier.Ray({ x: 0, y: 0, z: 0 }, { x: 0, y: -1, z: 0 }),
|
||||
[rapier],
|
||||
);
|
||||
const jumpTimingRef = useRef(createPlayerJumpTiming());
|
||||
const wasGroundedRef = useRef(true);
|
||||
const landingUntilRef = useRef(Number.NEGATIVE_INFINITY);
|
||||
|
||||
useEffect(() => {
|
||||
if (bodyRef.current) placeAtActiveSpawn(bodyRef.current, orbitRef.current);
|
||||
lastReported.current = [...spawn.footPosition];
|
||||
}, [bodyRef, orbitRef, resetRevision, spawn]);
|
||||
clearJumpRequest();
|
||||
jumpTimingRef.current = createPlayerJumpTiming(performance.now());
|
||||
wasGroundedRef.current = true;
|
||||
landingUntilRef.current = Number.NEGATIVE_INFINITY;
|
||||
verticalMotionRef.current = "grounded";
|
||||
}, [bodyRef, orbitRef, resetRevision, spawn, verticalMotionRef]);
|
||||
|
||||
useFrame((_, delta) => {
|
||||
const body = bodyRef.current;
|
||||
@@ -131,18 +163,68 @@ function PlayerController({
|
||||
}
|
||||
|
||||
const velocity = body.linvel();
|
||||
if (paused || mapOpen || companionOpen || controlledUntil > Date.now()) {
|
||||
const translation = body.translation();
|
||||
if (![translation.x, translation.y, translation.z].every(Number.isFinite)) {
|
||||
placeAtActiveSpawn(body, orbit);
|
||||
return;
|
||||
}
|
||||
|
||||
const nowMs = performance.now();
|
||||
groundRay.origin.x = translation.x;
|
||||
groundRay.origin.y = translation.y;
|
||||
groundRay.origin.z = translation.z;
|
||||
const groundProbeLength = PLAYER_CENTER_HEIGHT + PLAYER_GROUND_PROBE_DISTANCE;
|
||||
const groundHit = world.castRayAndGetNormal(
|
||||
groundRay,
|
||||
groundProbeLength,
|
||||
true,
|
||||
rapier.QueryFilterFlags.EXCLUDE_SENSORS | rapier.QueryFilterFlags.EXCLUDE_DYNAMIC,
|
||||
undefined,
|
||||
undefined,
|
||||
body,
|
||||
);
|
||||
let grounded = velocity.y <= 0.5 && isWalkableGroundHit(groundHit, groundProbeLength);
|
||||
const requestedAtMs = consumeJumpRequest();
|
||||
const gameplayBlocked = paused || mapOpen || companionOpen || controlledUntil > Date.now();
|
||||
if (gameplayBlocked) {
|
||||
cancelBufferedPlayerJump(jumpTimingRef.current);
|
||||
movingRef.current = false;
|
||||
verticalMotionRef.current = characterVerticalMotion(
|
||||
grounded,
|
||||
velocity.y,
|
||||
nowMs,
|
||||
landingUntilRef.current,
|
||||
);
|
||||
body.setLinvel({ x: 0, y: velocity.y, z: 0 }, true);
|
||||
return;
|
||||
}
|
||||
if (requestedAtMs !== null) bufferPlayerJump(jumpTimingRef.current, requestedAtMs);
|
||||
|
||||
const shouldJump = updatePlayerJumpTiming(
|
||||
jumpTimingRef.current,
|
||||
nowMs,
|
||||
grounded,
|
||||
velocity.y,
|
||||
);
|
||||
const verticalVelocity = shouldJump ? PLAYER_JUMP_VELOCITY : velocity.y;
|
||||
if (shouldJump) grounded = false;
|
||||
if (grounded && !wasGroundedRef.current) {
|
||||
landingUntilRef.current = nowMs + PLAYER_LANDING_PRESENTATION_MS;
|
||||
}
|
||||
wasGroundedRef.current = grounded;
|
||||
verticalMotionRef.current = characterVerticalMotion(
|
||||
grounded,
|
||||
verticalVelocity,
|
||||
nowMs,
|
||||
landingUntilRef.current,
|
||||
);
|
||||
|
||||
const [worldX, worldZ] = cameraRelativeMovement(
|
||||
snapshot.moveX,
|
||||
snapshot.moveForward,
|
||||
orbit.yaw,
|
||||
);
|
||||
body.setLinvel({ x: worldX * MOVE_SPEED, y: velocity.y, z: worldZ * MOVE_SPEED }, true);
|
||||
body.setLinvel({ x: worldX * MOVE_SPEED, y: verticalVelocity, z: worldZ * MOVE_SPEED }, true);
|
||||
|
||||
const moving = Math.hypot(worldX, worldZ) > 0.05;
|
||||
movingRef.current = moving;
|
||||
@@ -152,11 +234,6 @@ function PlayerController({
|
||||
avatarRef.current.rotation.y += difference * (1 - Math.exp(-14 * delta));
|
||||
}
|
||||
|
||||
const translation = body.translation();
|
||||
if (![translation.x, translation.y, translation.z].every(Number.isFinite)) {
|
||||
placeAtActiveSpawn(body, orbit);
|
||||
return;
|
||||
}
|
||||
const activeManastormPackage = gameMode === "manastorm"
|
||||
? activeManastormStageAssetPackage()
|
||||
: null;
|
||||
@@ -185,6 +262,7 @@ function PlayerController({
|
||||
position: footPosition,
|
||||
yaw: orbit.yaw,
|
||||
distanceDelta,
|
||||
grounded,
|
||||
});
|
||||
lastReported.current = footPosition;
|
||||
}
|
||||
@@ -214,6 +292,7 @@ function PlayerController({
|
||||
equipment={equipmentItems}
|
||||
active={!paused && !mapOpen && !companionOpen}
|
||||
movingRef={movingRef}
|
||||
verticalMotionRef={verticalMotionRef}
|
||||
animationEventRef={animationEventRef}
|
||||
fallback={<ProceduralAvatar accent={classById(identity?.classId ?? "priest").color} />}
|
||||
/>
|
||||
@@ -331,6 +410,7 @@ export function PlayerRig() {
|
||||
const bodyRef = useRef<RapierRigidBody>(null);
|
||||
const avatarRef = useRef<Object3D>(null);
|
||||
const movingRef = useRef(false);
|
||||
const verticalMotionRef = useRef<CharacterVerticalMotion>("grounded");
|
||||
const animationEventRef = useRef<CharacterCombatAnimationEvent | null>(animationEvent);
|
||||
animationEventRef.current = animationEvent;
|
||||
const activeDungeonId = useGameStore((state) => state.activeDungeonId);
|
||||
@@ -349,6 +429,7 @@ export function PlayerRig() {
|
||||
identity={activeCharacter}
|
||||
equipmentItems={equipmentItems}
|
||||
movingRef={movingRef}
|
||||
verticalMotionRef={verticalMotionRef}
|
||||
animationEventRef={animationEventRef}
|
||||
/>
|
||||
<ThirdPersonCamera bodyRef={bodyRef} orbitRef={orbitRef} avatarRef={avatarRef} />
|
||||
|
||||
Reference in new issue
Block a user