fix scenario 911 assignment troop gather

This commit is contained in:
2026-07-27 09:49:35 +00:00
parent 7afb99256d
commit de510da48e
5 changed files with 177 additions and 14 deletions
@@ -59,6 +59,11 @@ import { buildActionContext } from './reservedTurnActionContext.js';
import { GeneralAI, shouldUseAi } from './ai/generalAi.js';
import type { AiReservedTurnProvider } from './ai/types.js';
import { rankMetaKey } from './rankData.js';
import {
hasScenarioStaticEventHandler,
IMMEDIATE_ASSIGNMENT_GATHER_HANDLER,
LEGACY_NATION_ASSIGNMENT_EVENT,
} from './scenarioStaticEvents.js';
const DEFAULT_ACTION = '휴식';
@@ -1262,6 +1267,59 @@ export const createReservedTurnHandler = async (options: {
}
}
if (
kind === 'nation' &&
actionKey === 'che_발령' &&
!usedFallback &&
resolution.completed &&
worldOverlay &&
hasScenarioStaticEventHandler(
options.scenarioConfig,
LEGACY_NATION_ASSIGNMENT_EVENT,
IMMEDIATE_ASSIGNMENT_GATHER_HANDLER
)
) {
const destGeneralId = actionArgsRecord.destGeneralId;
const destCityId = actionArgsRecord.destCityId;
if (typeof destGeneralId === 'number' && typeof destCityId === 'number') {
const destGeneral = worldOverlay.view.getGeneralById(destGeneralId);
const destCity = worldOverlay.view.getCityById(destCityId);
if (
destGeneral &&
destCity &&
destGeneral.id === destGeneral.troopId &&
destGeneral.nationId === currentGeneral.nationId
) {
const troopName = worldOverlay.view.getTroopById(destGeneral.id)?.name ?? '';
const cityJosa = JosaUtil.pick(destCity.name, '로');
const troopMembers = worldOverlay.view
.listGenerals()
.filter(
(member) =>
member.id !== destGeneral.id &&
member.nationId === destGeneral.nationId &&
member.troopId === destGeneral.id &&
member.cityId !== destCity.id
);
for (const member of troopMembers) {
const patch = { cityId: destCity.id };
patches.generals.push({ id: member.id, patch });
worldOverlay.applyGeneralPatch(member.id, patch);
if (member.id === currentGeneral.id) {
currentGeneral = applyGeneralPatch(currentGeneral, patch);
}
logs.push({
scope: LogScope.GENERAL,
category: LogCategory.ACTION,
generalId: member.id,
format: LogFormat.PLAIN,
text: `${troopName} 부대원들은 <G><b>${destCity.name}</b></>${cityJosa} 즉시 집합되었습니다.`,
});
}
}
}
}
if (resolution.created?.generals) {
const newGenerals = resolution.created.generals as TurnGeneral[];
createdGenerals.push(...newGenerals);
@@ -0,0 +1,17 @@
import { asRecord } from '@sammo-ts/common';
import type { ScenarioConfig } from '@sammo-ts/logic';
export const LEGACY_TROOP_JOIN_EVENT = 'sammo\\API\\Troop\\JoinTroop';
export const IMMEDIATE_TROOP_JOIN_MOVE_HANDLER = 'event_부대탑승즉시이동';
export const LEGACY_NATION_ASSIGNMENT_EVENT = 'sammo\\Command\\Nation\\che_발령';
export const IMMEDIATE_ASSIGNMENT_GATHER_HANDLER = 'event_부대발령즉시집합';
export const hasScenarioStaticEventHandler = (
scenarioConfig: ScenarioConfig,
eventType: string,
handlerName: string
): boolean => {
const handlersByEvent = asRecord(scenarioConfig.const.staticEventHandlers);
const handlers = handlersByEvent[eventType];
return Array.isArray(handlers) && handlers.includes(handlerName);
};
+12 -10
View File
@@ -34,6 +34,11 @@ import {
import type { InMemoryTurnWorld } from './inMemoryWorld.js';
import type { TurnGeneral } from './types.js';
import { openAuction } from '../auction/opener.js';
import {
hasScenarioStaticEventHandler,
IMMEDIATE_TROOP_JOIN_MOVE_HANDLER,
LEGACY_TROOP_JOIN_EVENT,
} from './scenarioStaticEvents.js';
let itemRegistryPromise: Promise<Map<string, ItemModule>> | null = null;
@@ -89,15 +94,6 @@ const resolveMaxSecretPermission = (general: TurnGeneral): number => {
return 4;
};
const LEGACY_TROOP_JOIN_EVENT = 'sammo\\API\\Troop\\JoinTroop';
const IMMEDIATE_TROOP_JOIN_MOVE_HANDLER = 'event_부대탑승즉시이동';
const hasStaticEventHandler = (world: InMemoryTurnWorld, eventType: string, handlerName: string): boolean => {
const handlersByEvent = asRecord(world.getScenarioConfig().const.staticEventHandlers);
const handlers = handlersByEvent[eventType];
return Array.isArray(handlers) && handlers.includes(handlerName);
};
const refreshActorKillturn = (world: InMemoryTurnWorld, actor: TurnGeneral): void => {
const worldKillturn = readMetaNumber(asRecord(world.getState().meta), 'killturn', 0);
const actorKillturn = readMetaNumber(asRecord(actor.meta), 'killturn', 0);
@@ -494,7 +490,13 @@ async function handleTroopJoin(
world.updateGeneral(command.generalId, {
troopId: command.troopId,
});
if (hasStaticEventHandler(world, LEGACY_TROOP_JOIN_EVENT, IMMEDIATE_TROOP_JOIN_MOVE_HANDLER)) {
if (
hasScenarioStaticEventHandler(
world.getScenarioConfig(),
LEGACY_TROOP_JOIN_EVENT,
IMMEDIATE_TROOP_JOIN_MOVE_HANDLER
)
) {
const leader = world.getGeneralById(troop.id);
if (
leader &&