Rework story engine flow and reorganize project docs
Some checks failed
CI / verify (push) Has been cancelled
Some checks failed
CI / verify (push) Has been cancelled
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { AnimationState, Encounter, GameState, SceneNpc, WorldType } from '../types';
|
||||
import { getRecruitedNpcIds } from './companionRoster';
|
||||
import {
|
||||
createSceneMonstersFromIds,
|
||||
createSceneNpcMonstersFromEncounters,
|
||||
createSceneHostileNpcsFromEncounters,
|
||||
createSceneHostileNpcsFromIds,
|
||||
getFacingTowardPlayer,
|
||||
getMonsterGroupAnchorX,
|
||||
pickEncounterMonsterIds,
|
||||
@@ -42,7 +42,7 @@ function buildResolvedNpcBattleState(state: GameState, encounter: Encounter) {
|
||||
|
||||
return {
|
||||
...state,
|
||||
sceneMonsters: [
|
||||
sceneHostileNpcs: [
|
||||
createNpcBattleMonster(encounter, npcState, 'fight', {
|
||||
worldType: state.worldType,
|
||||
customWorldProfile: state.customWorldProfile,
|
||||
@@ -123,7 +123,7 @@ function buildHostileEncounterGroup(
|
||||
|
||||
const selectedHostiles = pickEncounterHostileNpcs(getAvailableHostileSceneNpcs(state));
|
||||
const hostileEncounters = selectedHostiles.map(npc => buildEncounterFromSceneNpc(npc));
|
||||
const hostileMonsters = createSceneNpcMonstersFromEncounters(
|
||||
const hostileMonsters = createSceneHostileNpcsFromEncounters(
|
||||
state.worldType,
|
||||
hostileEncounters,
|
||||
PLAYER_BASE_X_METERS,
|
||||
@@ -157,7 +157,7 @@ function buildFriendlyEncounter(npc: SceneNpc, xMeters: number) {
|
||||
function buildResolvedHostileBattleState(state: GameState, hostileEncounters: Encounter[]) {
|
||||
if (!state.worldType) return state;
|
||||
|
||||
const resolvedMonsters = createSceneNpcMonstersFromEncounters(
|
||||
const resolvedMonsters = createSceneHostileNpcsFromEncounters(
|
||||
state.worldType,
|
||||
hostileEncounters,
|
||||
PLAYER_BASE_X_METERS,
|
||||
@@ -175,7 +175,7 @@ function buildResolvedHostileBattleState(state: GameState, hostileEncounters: En
|
||||
|
||||
return {
|
||||
...state,
|
||||
sceneMonsters: resolvedMonsters,
|
||||
sceneHostileNpcs: resolvedMonsters,
|
||||
currentEncounter: null,
|
||||
npcInteractionActive: false,
|
||||
playerX: 0,
|
||||
@@ -191,7 +191,7 @@ function buildResolvedHostileBattleState(state: GameState, hostileEncounters: En
|
||||
export function createSceneEncounterPreview(state: GameState) {
|
||||
if (!state.worldType || !state.currentScenePreset) {
|
||||
return {
|
||||
sceneMonsters: [],
|
||||
sceneHostileNpcs: [],
|
||||
currentEncounter: null,
|
||||
npcInteractionActive: false,
|
||||
inBattle: false,
|
||||
@@ -210,7 +210,7 @@ export function createSceneEncounterPreview(state: GameState) {
|
||||
const kind = pickRandomItem(availableKinds);
|
||||
if (!kind) {
|
||||
return {
|
||||
sceneMonsters: [],
|
||||
sceneHostileNpcs: [],
|
||||
currentEncounter: null,
|
||||
npcInteractionActive: false,
|
||||
inBattle: false,
|
||||
@@ -219,7 +219,7 @@ export function createSceneEncounterPreview(state: GameState) {
|
||||
|
||||
if (kind === 'hostile') {
|
||||
return {
|
||||
sceneMonsters: buildHostileEncounterGroup(state, PREVIEW_ENTITY_X_METERS, 'idle'),
|
||||
sceneHostileNpcs: buildHostileEncounterGroup(state, PREVIEW_ENTITY_X_METERS, 'idle'),
|
||||
currentEncounter: null,
|
||||
npcInteractionActive: false,
|
||||
inBattle: false,
|
||||
@@ -230,7 +230,7 @@ export function createSceneEncounterPreview(state: GameState) {
|
||||
const npc = pickRandomItem(availableNpcs);
|
||||
|
||||
return {
|
||||
sceneMonsters: [],
|
||||
sceneHostileNpcs: [],
|
||||
currentEncounter: npc ? buildFriendlyEncounter(npc, PREVIEW_ENTITY_X_METERS) : null,
|
||||
npcInteractionActive: false,
|
||||
inBattle: false,
|
||||
@@ -239,7 +239,7 @@ export function createSceneEncounterPreview(state: GameState) {
|
||||
|
||||
const treasureHint = pickRandomItem(state.currentScenePreset.treasureHints ?? []);
|
||||
return {
|
||||
sceneMonsters: [],
|
||||
sceneHostileNpcs: [],
|
||||
currentEncounter: treasureHint ? createTreasureEncounter(state, treasureHint) : null,
|
||||
npcInteractionActive: false,
|
||||
inBattle: false,
|
||||
@@ -249,7 +249,7 @@ export function createSceneEncounterPreview(state: GameState) {
|
||||
export function createSceneCallOutEncounter(state: GameState) {
|
||||
if (!state.worldType || !state.currentScenePreset) {
|
||||
return {
|
||||
sceneMonsters: [],
|
||||
sceneHostileNpcs: [],
|
||||
currentEncounter: null,
|
||||
npcInteractionActive: false,
|
||||
inBattle: false,
|
||||
@@ -269,7 +269,7 @@ export function createSceneCallOutEncounter(state: GameState) {
|
||||
const kind = pickRandomItem(availableKinds);
|
||||
if (kind === 'hostile') {
|
||||
return {
|
||||
sceneMonsters: buildHostileEncounterGroup(state, CALL_OUT_ENTRY_X_METERS, 'move'),
|
||||
sceneHostileNpcs: buildHostileEncounterGroup(state, CALL_OUT_ENTRY_X_METERS, 'move'),
|
||||
currentEncounter: null,
|
||||
npcInteractionActive: false,
|
||||
inBattle: false,
|
||||
@@ -279,7 +279,7 @@ export function createSceneCallOutEncounter(state: GameState) {
|
||||
if (kind === 'npc') {
|
||||
const npc = pickRandomItem(availableNpcs);
|
||||
return {
|
||||
sceneMonsters: [],
|
||||
sceneHostileNpcs: [],
|
||||
currentEncounter: npc ? buildFriendlyEncounter(npc, CALL_OUT_ENTRY_X_METERS) : null,
|
||||
npcInteractionActive: false,
|
||||
inBattle: false,
|
||||
@@ -289,7 +289,7 @@ export function createSceneCallOutEncounter(state: GameState) {
|
||||
if (kind === 'treasure') {
|
||||
const treasureHint = pickRandomItem(state.currentScenePreset.treasureHints ?? []);
|
||||
return {
|
||||
sceneMonsters: [],
|
||||
sceneHostileNpcs: [],
|
||||
currentEncounter: treasureHint
|
||||
? {
|
||||
...createTreasureEncounter(state, treasureHint),
|
||||
@@ -302,7 +302,7 @@ export function createSceneCallOutEncounter(state: GameState) {
|
||||
}
|
||||
|
||||
return {
|
||||
sceneMonsters: [],
|
||||
sceneHostileNpcs: [],
|
||||
currentEncounter: null,
|
||||
npcInteractionActive: false,
|
||||
inBattle: false,
|
||||
@@ -312,7 +312,7 @@ export function createSceneCallOutEncounter(state: GameState) {
|
||||
export function ensureSceneEncounterPreview(state: GameState): GameState {
|
||||
if (
|
||||
state.inBattle ||
|
||||
state.sceneMonsters.length > 0 ||
|
||||
state.sceneHostileNpcs.length > 0 ||
|
||||
state.currentEncounter ||
|
||||
!state.currentScenePreset ||
|
||||
!state.worldType
|
||||
@@ -337,8 +337,8 @@ export function hasAutoBattleSceneEncounter(state: GameState) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (state.sceneMonsters.length > 0) {
|
||||
return state.sceneMonsters.some(monster => Boolean(monster.encounter?.monsterPresetId));
|
||||
if (state.sceneHostileNpcs.length > 0) {
|
||||
return state.sceneHostileNpcs.some(monster => Boolean(monster.encounter?.monsterPresetId));
|
||||
}
|
||||
|
||||
return state.currentEncounter?.kind === 'npc'
|
||||
@@ -352,12 +352,12 @@ export function resolveSceneEncounterPreview(state: GameState): GameState {
|
||||
}
|
||||
|
||||
const previewState =
|
||||
state.sceneMonsters.length > 0 || state.currentEncounter
|
||||
state.sceneHostileNpcs.length > 0 || state.currentEncounter
|
||||
? state
|
||||
: ensureSceneEncounterPreview(state);
|
||||
|
||||
if (previewState.sceneMonsters.length > 0) {
|
||||
const hostileEncounters = previewState.sceneMonsters
|
||||
if (previewState.sceneHostileNpcs.length > 0) {
|
||||
const hostileEncounters = previewState.sceneHostileNpcs
|
||||
.map(monster => monster.encounter)
|
||||
.filter((encounter): encounter is Encounter => Boolean(encounter?.monsterPresetId));
|
||||
|
||||
@@ -365,9 +365,9 @@ export function resolveSceneEncounterPreview(state: GameState): GameState {
|
||||
return buildResolvedHostileBattleState(previewState, hostileEncounters);
|
||||
}
|
||||
|
||||
const resolvedMonsters = createSceneMonstersFromIds(
|
||||
const resolvedMonsters = createSceneHostileNpcsFromIds(
|
||||
previewState.worldType ?? WorldType.WUXIA,
|
||||
previewState.sceneMonsters.map(monster => monster.id),
|
||||
previewState.sceneHostileNpcs.map(monster => monster.id),
|
||||
PLAYER_BASE_X_METERS,
|
||||
).map(monster => ({
|
||||
...monster,
|
||||
@@ -377,7 +377,7 @@ export function resolveSceneEncounterPreview(state: GameState): GameState {
|
||||
|
||||
return {
|
||||
...previewState,
|
||||
sceneMonsters: resolvedMonsters,
|
||||
sceneHostileNpcs: resolvedMonsters,
|
||||
currentEncounter: null,
|
||||
npcInteractionActive: false,
|
||||
playerX: 0,
|
||||
@@ -405,7 +405,7 @@ export function resolveSceneEncounterPreview(state: GameState): GameState {
|
||||
xMeters: RESOLVED_ENTITY_X_METERS,
|
||||
},
|
||||
npcInteractionActive: false,
|
||||
sceneMonsters: [],
|
||||
sceneHostileNpcs: [],
|
||||
playerX: 0,
|
||||
playerFacing: 'right' as const,
|
||||
animationState: AnimationState.IDLE,
|
||||
@@ -420,7 +420,7 @@ export function resolveSceneEncounterPreview(state: GameState): GameState {
|
||||
}
|
||||
|
||||
export function getPreviewEntityX(state: GameState) {
|
||||
return state.sceneMonsters.length > 0
|
||||
? getMonsterGroupAnchorX(state.sceneMonsters)
|
||||
return state.sceneHostileNpcs.length > 0
|
||||
? getMonsterGroupAnchorX(state.sceneHostileNpcs)
|
||||
: state.currentEncounter?.xMeters ?? PREVIEW_ENTITY_X_METERS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user