This commit is contained in:
128
src/data/companionRoster.ts
Normal file
128
src/data/companionRoster.ts
Normal file
@@ -0,0 +1,128 @@
|
||||
import { CompanionState, GameState } from '../types';
|
||||
import { MAX_COMPANIONS } from './npcInteractions';
|
||||
|
||||
function upsertCompanion(list: CompanionState[], companion: CompanionState) {
|
||||
const next = [...list];
|
||||
const existingIndex = next.findIndex(item => item.npcId === companion.npcId);
|
||||
if (existingIndex >= 0) {
|
||||
next[existingIndex] = companion;
|
||||
return next;
|
||||
}
|
||||
|
||||
next.push(companion);
|
||||
return next;
|
||||
}
|
||||
|
||||
function removeCompanion(list: CompanionState[], npcId: string) {
|
||||
return list.filter(item => item.npcId !== npcId);
|
||||
}
|
||||
|
||||
export function getRecruitedNpcIds(state: Pick<GameState, 'companions' | 'roster'>) {
|
||||
return new Set([
|
||||
...state.companions.map(companion => companion.npcId),
|
||||
...state.roster.map(companion => companion.npcId),
|
||||
]);
|
||||
}
|
||||
|
||||
export function normalizeRoster(roster: CompanionState[], activeCompanions: CompanionState[]) {
|
||||
const activeIds = new Set(activeCompanions.map(companion => companion.npcId));
|
||||
return roster
|
||||
.filter(companion => !activeIds.has(companion.npcId))
|
||||
.reduce<CompanionState[]>((next, companion) => upsertCompanion(next, companion), []);
|
||||
}
|
||||
|
||||
export function benchActiveCompanion(state: GameState, npcId: string) {
|
||||
const activeCompanion = state.companions.find(companion => companion.npcId === npcId);
|
||||
if (!activeCompanion) return state;
|
||||
|
||||
return {
|
||||
...state,
|
||||
companions: state.companions.filter(companion => companion.npcId !== npcId),
|
||||
roster: upsertCompanion(state.roster, activeCompanion),
|
||||
};
|
||||
}
|
||||
|
||||
export function activateRosterCompanion(state: GameState, npcId: string, swapNpcId?: string | null) {
|
||||
const reserveCompanion = state.roster.find(companion => companion.npcId === npcId);
|
||||
if (!reserveCompanion) return state;
|
||||
|
||||
if (state.companions.some(companion => companion.npcId === npcId)) {
|
||||
return {
|
||||
...state,
|
||||
roster: removeCompanion(state.roster, npcId),
|
||||
};
|
||||
}
|
||||
|
||||
if (state.companions.length < MAX_COMPANIONS) {
|
||||
return {
|
||||
...state,
|
||||
companions: [...state.companions, reserveCompanion],
|
||||
roster: removeCompanion(state.roster, npcId),
|
||||
};
|
||||
}
|
||||
|
||||
if (!swapNpcId) return state;
|
||||
const swapIndex = state.companions.findIndex(companion => companion.npcId === swapNpcId);
|
||||
if (swapIndex < 0) return state;
|
||||
|
||||
const swappedOut = state.companions[swapIndex];
|
||||
if (!swappedOut) {
|
||||
return state;
|
||||
}
|
||||
|
||||
const nextCompanions = [...state.companions];
|
||||
nextCompanions[swapIndex] = reserveCompanion;
|
||||
|
||||
return {
|
||||
...state,
|
||||
companions: nextCompanions,
|
||||
roster: upsertCompanion(removeCompanion(state.roster, npcId), swappedOut),
|
||||
};
|
||||
}
|
||||
|
||||
export function recruitCompanionToParty(
|
||||
state: GameState,
|
||||
companion: CompanionState,
|
||||
replacedNpcId?: string | null,
|
||||
) {
|
||||
const nextReserve = removeCompanion(state.roster, companion.npcId);
|
||||
|
||||
if (!replacedNpcId && state.companions.length < MAX_COMPANIONS) {
|
||||
return {
|
||||
...state,
|
||||
companions: [...state.companions, companion],
|
||||
roster: nextReserve,
|
||||
};
|
||||
}
|
||||
|
||||
if (!replacedNpcId) {
|
||||
return {
|
||||
...state,
|
||||
companions: state.companions.slice(0, MAX_COMPANIONS),
|
||||
roster: normalizeRoster(nextReserve, state.companions),
|
||||
};
|
||||
}
|
||||
|
||||
const replaceIndex = state.companions.findIndex(item => item.npcId === replacedNpcId);
|
||||
if (replaceIndex < 0) {
|
||||
return {
|
||||
...state,
|
||||
companions: [...state.companions, companion].slice(0, MAX_COMPANIONS),
|
||||
roster: nextReserve,
|
||||
};
|
||||
}
|
||||
|
||||
const replacedCompanion = state.companions[replaceIndex];
|
||||
if (!replacedCompanion) {
|
||||
return state;
|
||||
}
|
||||
|
||||
const nextCompanions = [...state.companions];
|
||||
nextCompanions[replaceIndex] = companion;
|
||||
|
||||
return {
|
||||
...state,
|
||||
companions: nextCompanions,
|
||||
roster: upsertCompanion(nextReserve, replacedCompanion),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user