forked from phenom/healer-man
Release Healer Man 0.1.14
This commit is contained in:
1 parent
67d7a8ebe7
commit
7b41b102fa
147 files changed
+169892
-1342
No files matched your search
@@ -39,6 +39,7 @@ import {
|
||||
} from "../game/partyRuntimeRegistry";
|
||||
import { PLAYER_AGGRO_ID } from "../game/aggro";
|
||||
import {
|
||||
getMobRuntimeTransform,
|
||||
registerMobRuntime,
|
||||
updateMobRuntimePosition,
|
||||
} from "../game/mobRuntimeRegistry";
|
||||
@@ -1450,6 +1451,100 @@ function StaticPopulationCluster({
|
||||
);
|
||||
}
|
||||
|
||||
function SummonedPopulationMember({
|
||||
instanceId,
|
||||
entity,
|
||||
active,
|
||||
useOriginalModels,
|
||||
}: {
|
||||
readonly instanceId: string;
|
||||
readonly entity: PopulationEntityDefinition;
|
||||
readonly active: boolean;
|
||||
readonly useOriginalModels: boolean;
|
||||
}) {
|
||||
const groupRef = useRef<Group>(null);
|
||||
const initial = getMobRuntimeTransform(instanceId)?.position ?? [0, 0, 0];
|
||||
const positionRef = useRef<MutableMobVector3>([...initial]);
|
||||
useFrame((_, delta) => {
|
||||
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 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);
|
||||
if (!movementLocked && feared) {
|
||||
stepFearedMobAway(
|
||||
position,
|
||||
targetPosition,
|
||||
mob.homePosition ?? initial,
|
||||
maximumStep * 1.1,
|
||||
mob.leashRange,
|
||||
position,
|
||||
);
|
||||
} else if (!movementLocked && mob.combatPhase === "chasing") {
|
||||
stepToward(position, targetPosition, maximumStep);
|
||||
}
|
||||
const facingSign = feared && !movementLocked ? -1 : 1;
|
||||
const yaw = Math.atan2(
|
||||
(targetPosition[0] - position[0]) * facingSign,
|
||||
(targetPosition[2] - position[2]) * facingSign,
|
||||
);
|
||||
if (groupRef.current) {
|
||||
groupRef.current.position.set(position[0], position[1], position[2]);
|
||||
groupRef.current.rotation.y = yaw;
|
||||
}
|
||||
updateMobRuntimePosition(instanceId, position[0], position[1], position[2], yaw);
|
||||
});
|
||||
return (
|
||||
<group ref={groupRef} position={initial} name={`summoned-mob-${instanceId}`}>
|
||||
<ProxyMob
|
||||
definition={entity}
|
||||
instanceId={instanceId}
|
||||
active={active}
|
||||
moving
|
||||
showLabel={false}
|
||||
useOriginalModels={useOriginalModels}
|
||||
/>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
|
||||
function SummonedEnemyPopulation({
|
||||
entities,
|
||||
active,
|
||||
useOriginalModels,
|
||||
}: {
|
||||
readonly entities: PopulationDefinitionMap;
|
||||
readonly active: boolean;
|
||||
readonly useOriginalModels: boolean;
|
||||
}) {
|
||||
const mobs = useCombatStore((state) => state.mobs);
|
||||
const summons = useMemo(() => Object.values(mobs).flatMap((mob) => {
|
||||
if (!mob.summonedBy || mob.serverEntry === null || mob.despawned) return [];
|
||||
const entity = entities[`entry-${mob.serverEntry}`]
|
||||
?? Object.values(entities).find((candidate) => candidate.combat?.serverEntry === mob.serverEntry);
|
||||
return entity ? [{ instanceId: mob.id, entity }] : [];
|
||||
}), [entities, mobs]);
|
||||
return (
|
||||
<group name="summoned-enemy-population">
|
||||
{summons.map(({ instanceId, entity }) => (
|
||||
<SummonedPopulationMember
|
||||
key={instanceId}
|
||||
instanceId={instanceId}
|
||||
entity={entity}
|
||||
active={active}
|
||||
useOriginalModels={useOriginalModels}
|
||||
/>
|
||||
))}
|
||||
</group>
|
||||
);
|
||||
}
|
||||
|
||||
export interface MobPopulationProps {
|
||||
readonly entities: PopulationDefinitionMap;
|
||||
readonly roamingPacks: readonly MobPackDefinition[];
|
||||
@@ -1512,6 +1607,11 @@ export function MobPopulation({
|
||||
useOriginalModels={useOriginalModels}
|
||||
/>
|
||||
))}
|
||||
<SummonedEnemyPopulation
|
||||
entities={entities}
|
||||
active={active}
|
||||
useOriginalModels={useOriginalModels}
|
||||
/>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user