Release Healer Man 0.1.46
This commit is contained in:
1 parent
f82daf1c13
commit
9ff574ac0b
73 files changed
+33486
-174
No files matched your search
@@ -57,6 +57,7 @@ import {
|
||||
samplePackFormation,
|
||||
} from "../game/mobPopulation";
|
||||
import { useGameStore } from "../game/store";
|
||||
import { dungeonSimulationNow, useDungeonSimulationStore } from "../game/dungeonSimulationStore";
|
||||
import {
|
||||
manastormExperienceReward,
|
||||
manastormRuntimeScaling,
|
||||
@@ -913,7 +914,7 @@ function ProxyMob({
|
||||
const attackRevision = mob?.attackRevision ?? 0;
|
||||
const attackAnimation = mob?.attackAnimation ?? "attack";
|
||||
const woundRevision = mob?.woundRevision ?? 0;
|
||||
const statusNow = Date.now();
|
||||
const statusNow = dungeonSimulationNow();
|
||||
const movementLocked = mob?.statuses.some((status) => status.endsAt > statusNow
|
||||
&& MOVEMENT_LOCKING_MOB_STATUSES.has(status.kind)) ?? false;
|
||||
const feared = mob?.statuses.some((status) => status.endsAt > statusNow
|
||||
@@ -1106,7 +1107,7 @@ function MobHealthPlate({ instanceId, height, boss }: {
|
||||
if (plateRef.current) plateRef.current.lookAt(camera.position);
|
||||
if (castFillRef.current && mob?.activeCast) {
|
||||
const duration = Math.max(1, mob.activeCast.completesAt - mob.activeCast.startedAt);
|
||||
const now = Date.now();
|
||||
const now = dungeonSimulationNow();
|
||||
const progress = Math.max(0.001, Math.min(1, (now - mob.activeCast.startedAt) / duration));
|
||||
castFillRef.current.scale.x = progress;
|
||||
castFillRef.current.position.x = -width * (1 - progress) / 2;
|
||||
@@ -1212,6 +1213,7 @@ function RoamingPack({
|
||||
const nearby = usePopulationProximity(scratchPositions);
|
||||
const memberRefs = useRef<Array<Group | null>>([]);
|
||||
const chasingRefs = useRef<boolean[]>(definition.members.map(() => false));
|
||||
const simulationElapsedRef = useRef(0);
|
||||
|
||||
useEffect(() => {
|
||||
const cleanups = definition.members.map((member, index) => registerMobRuntime(
|
||||
@@ -1226,8 +1228,13 @@ function RoamingPack({
|
||||
if (!nearby) return;
|
||||
|
||||
const combat = useCombatStore.getState();
|
||||
const simulation = useDungeonSimulationStore.getState();
|
||||
const movementDelta = simulation.sessionMode === "spectate-live"
|
||||
? Math.max(0, (simulation.elapsedMs - simulationElapsedRef.current) / 1_000)
|
||||
: simulation.sessionMode === "spectate-replay" ? 0 : delta;
|
||||
simulationElapsedRef.current = simulation.elapsedMs;
|
||||
const playerPosition = useGameStore.getState().playerPosition;
|
||||
const now = Date.now();
|
||||
const now = dungeonSimulationNow();
|
||||
const anyEngaged = definition.members.some((member) => combat.mobs[`${definition.id}:${member.id}`]?.engaged);
|
||||
if (active && !anyEngaged) {
|
||||
let movementMultiplier = 1;
|
||||
@@ -1242,7 +1249,7 @@ function RoamingPack({
|
||||
const slow = statuses.find((status) => status.endsAt > now && status.kind === "slow");
|
||||
if (slow) movementMultiplier = Math.min(movementMultiplier, 1 - (slow.magnitude ?? 0.5));
|
||||
}
|
||||
distanceRef.current = (distanceRef.current + Math.min(delta, 0.05) * definition.speed * movementMultiplier)
|
||||
distanceRef.current = (distanceRef.current + Math.min(movementDelta, 0.5) * definition.speed * movementMultiplier)
|
||||
% path.totalLength;
|
||||
}
|
||||
|
||||
@@ -1259,6 +1266,20 @@ function RoamingPack({
|
||||
const forward = scratchForwards[index];
|
||||
const member = definition.members[index];
|
||||
const instanceId = `${definition.id}:${member.id}`;
|
||||
if (simulation.sessionMode === "spectate-replay") {
|
||||
const replayTransform = getMobRuntimeTransform(instanceId);
|
||||
if (replayTransform) {
|
||||
const object = memberRefs.current[index];
|
||||
if (object) {
|
||||
object.position.set(...replayTransform.position);
|
||||
object.rotation.y = replayTransform.yaw;
|
||||
}
|
||||
chasePositions[index][0] = replayTransform.position[0];
|
||||
chasePositions[index][1] = replayTransform.position[1];
|
||||
chasePositions[index][2] = replayTransform.position[2];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
const synchronizedTransform = onlineSynchronizedMobTransform(instanceId);
|
||||
if (synchronizedTransform) {
|
||||
const object = memberRefs.current[index];
|
||||
@@ -1389,8 +1410,27 @@ function StaticPopulationMember({ spawn, entities, active, showLabels, useOrigin
|
||||
const entity = entities[spawn.entityId];
|
||||
const groupRef = useRef<Group>(null);
|
||||
const positionRef = useRef<MutableMobVector3>([...spawn.position]);
|
||||
const simulationElapsedRef = useRef(0);
|
||||
useEffect(() => registerMobRuntime(spawn.id, spawn.position, spawn.yaw ?? 0), [spawn.id, spawn.position, spawn.yaw]);
|
||||
useFrame((_, delta) => {
|
||||
const simulation = useDungeonSimulationStore.getState();
|
||||
const movementDelta = simulation.sessionMode === "spectate-live"
|
||||
? Math.max(0, (simulation.elapsedMs - simulationElapsedRef.current) / 1_000)
|
||||
: simulation.sessionMode === "spectate-replay" ? 0 : delta;
|
||||
simulationElapsedRef.current = simulation.elapsedMs;
|
||||
if (simulation.sessionMode === "spectate-replay") {
|
||||
const replayTransform = getMobRuntimeTransform(spawn.id);
|
||||
if (replayTransform) {
|
||||
positionRef.current[0] = replayTransform.position[0];
|
||||
positionRef.current[1] = replayTransform.position[1];
|
||||
positionRef.current[2] = replayTransform.position[2];
|
||||
if (groupRef.current) {
|
||||
groupRef.current.position.set(...replayTransform.position);
|
||||
groupRef.current.rotation.y = replayTransform.yaw;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
const synchronizedTransform = onlineSynchronizedMobTransform(spawn.id);
|
||||
if (synchronizedTransform) {
|
||||
positionRef.current[0] = synchronizedTransform.position[0];
|
||||
@@ -1413,7 +1453,7 @@ function StaticPopulationMember({ spawn, entities, active, showLabels, useOrigin
|
||||
const position = positionRef.current;
|
||||
const player = useGameStore.getState().playerPosition;
|
||||
const targetPosition = mobTargetPosition(mob?.targetActorId, player);
|
||||
const now = Date.now();
|
||||
const now = dungeonSimulationNow();
|
||||
let feared = false;
|
||||
let movementLocked = false;
|
||||
if (mob?.dead) {
|
||||
@@ -1423,7 +1463,7 @@ function StaticPopulationMember({ spawn, entities, active, showLabels, useOrigin
|
||||
&& MOVEMENT_LOCKING_MOB_STATUSES.has(status.kind));
|
||||
feared = mob.statuses.some((status) => status.endsAt > now && status.kind === "fear");
|
||||
const slow = mob.statuses.find((status) => status.endsAt > now && status.kind === "slow")?.magnitude ?? 0;
|
||||
const maximumStep = Math.min(delta, 0.05) * mob.moveSpeed * Math.max(0.1, 1 - slow);
|
||||
const maximumStep = Math.min(movementDelta, 0.5) * mob.moveSpeed * Math.max(0.1, 1 - slow);
|
||||
if (active && !movementLocked && feared) {
|
||||
stepFearedMobAway(
|
||||
position,
|
||||
@@ -1438,7 +1478,7 @@ function StaticPopulationMember({ spawn, entities, active, showLabels, useOrigin
|
||||
maximumStep, active, now, movementLocked || feared);
|
||||
} else if (mob?.combatPhase === "returning") {
|
||||
navigateMob(navigator, mob, position, targetPosition, mob.homePosition ?? spawn.position,
|
||||
Math.min(delta, 0.05) * mob.moveSpeed * 1.25, active, now);
|
||||
Math.min(movementDelta, 0.5) * mob.moveSpeed * 1.25, active, now);
|
||||
} else {
|
||||
position[0] = spawn.position[0];
|
||||
position[1] = spawn.position[1];
|
||||
@@ -1531,18 +1571,35 @@ function SummonedPopulationMember({
|
||||
const groupRef = useRef<Group>(null);
|
||||
const initial = getMobRuntimeTransform(instanceId)?.position ?? [0, 0, 0];
|
||||
const positionRef = useRef<MutableMobVector3>([...initial]);
|
||||
const simulationElapsedRef = useRef(0);
|
||||
useFrame((_, delta) => {
|
||||
const simulation = useDungeonSimulationStore.getState();
|
||||
const movementDelta = simulation.sessionMode === "spectate-live"
|
||||
? Math.max(0, (simulation.elapsedMs - simulationElapsedRef.current) / 1_000)
|
||||
: simulation.sessionMode === "spectate-replay" ? 0 : delta;
|
||||
simulationElapsedRef.current = simulation.elapsedMs;
|
||||
if (simulation.sessionMode === "spectate-replay") {
|
||||
const replayTransform = getMobRuntimeTransform(instanceId);
|
||||
if (replayTransform && groupRef.current) {
|
||||
positionRef.current[0] = replayTransform.position[0];
|
||||
positionRef.current[1] = replayTransform.position[1];
|
||||
positionRef.current[2] = replayTransform.position[2];
|
||||
groupRef.current.position.set(...replayTransform.position);
|
||||
groupRef.current.rotation.y = replayTransform.yaw;
|
||||
}
|
||||
return;
|
||||
}
|
||||
const mob = useCombatStore.getState().mobs[instanceId];
|
||||
if (!mob || mob.dead || mob.despawned) return;
|
||||
const player = useGameStore.getState().playerPosition;
|
||||
const targetPosition = mobTargetPosition(mob.targetActorId, player);
|
||||
const position = positionRef.current;
|
||||
const now = Date.now();
|
||||
const now = dungeonSimulationNow();
|
||||
const movementLocked = mob.statuses.some((status) => status.endsAt > now
|
||||
&& MOVEMENT_LOCKING_MOB_STATUSES.has(status.kind));
|
||||
const feared = mob.statuses.some((status) => status.endsAt > now && status.kind === "fear");
|
||||
const slow = mob.statuses.find((status) => status.endsAt > now && status.kind === "slow")?.magnitude ?? 0;
|
||||
const maximumStep = Math.min(delta, 0.05) * mob.moveSpeed * Math.max(0.1, 1 - slow);
|
||||
const maximumStep = Math.min(movementDelta, 0.5) * mob.moveSpeed * Math.max(0.1, 1 - slow);
|
||||
if (active && !movementLocked && feared) {
|
||||
stepFearedMobAway(
|
||||
position,
|
||||
|
||||
Reference in new issue
Block a user