fix(parity): preserve legacy monthly turn ordering
This commit is contained in:
@@ -858,7 +858,22 @@ export class GeneralAI {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (candidate.stats.leadership >= this.nationPolicy.minNpcWarLeadership) {
|
||||
const fullLeadership = this.commandEnv.generalActionModules
|
||||
? resolveLegacyAiStatsWithModules(
|
||||
candidate,
|
||||
this.nation,
|
||||
this.commandEnv.maxStatLevel ?? this.scenarioConfig.stat.max,
|
||||
this.commandEnv.generalActionModules,
|
||||
this.worldRef,
|
||||
this.world,
|
||||
this.startYear
|
||||
).fullLeadership
|
||||
: resolveLegacyAiStats(
|
||||
candidate,
|
||||
this.nation,
|
||||
this.commandEnv.maxStatLevel ?? this.scenarioConfig.stat.max
|
||||
).fullLeadership;
|
||||
if (fullLeadership >= this.nationPolicy.minNpcWarLeadership) {
|
||||
npcWarGenerals[candidate.id] = candidate;
|
||||
} else {
|
||||
npcCivilGenerals[candidate.id] = candidate;
|
||||
|
||||
@@ -41,7 +41,11 @@ export const doNPC헌납 = (ai: GeneralAI) => {
|
||||
genRes >= ai.aiConst.minNationalRice / 2
|
||||
) {
|
||||
const amount = genRes < ai.aiConst.minNationalRice ? genRes : genRes / 2;
|
||||
args.push([{ isGold: false, amount }, amount]);
|
||||
// Ref passes the literal string "rice" here. che_헌납::argTest()
|
||||
// rejects that candidate because isGold is not boolean; preserving
|
||||
// the malformed weighted candidate also preserves the RNG draw and
|
||||
// lets the priority loop continue when it is selected.
|
||||
args.push([{ isGold: 'rice', amount }, amount]);
|
||||
}
|
||||
if (genRes < reqRes * 1.5) {
|
||||
continue;
|
||||
|
||||
@@ -128,11 +128,14 @@ export const do부대후방발령 = (ai: GeneralAI) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Ref consumes the troop-leader draw before the destination-city draw.
|
||||
// Both selections share the nation command RNG, so reversing them can
|
||||
// assign the same two outcomes to different leaders and cities.
|
||||
const leader = ai.rng.choice(troopCandidates);
|
||||
const destCityId = Number(ai.rng.choiceUsingWeight(cityCandidates));
|
||||
if (!Number.isFinite(destCityId)) {
|
||||
return null;
|
||||
}
|
||||
const leader = ai.rng.choice(troopCandidates);
|
||||
return buildAssignmentCandidate(ai, leader.id, destCityId, '부대후방발령');
|
||||
};
|
||||
|
||||
@@ -162,10 +165,10 @@ export const do부대구출발령 = (ai: GeneralAI) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const leader = ai.rng.choice(troopCandidates);
|
||||
const destCityId = pickRandomCityId(ai, ai.frontCities);
|
||||
if (destCityId === null) {
|
||||
return null;
|
||||
}
|
||||
const leader = ai.rng.choice(troopCandidates);
|
||||
return buildAssignmentCandidate(ai, leader.id, destCityId, '부대구출발령');
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { GeneralAI } from '../core.js';
|
||||
import { GeneralActionPipeline } from '@sammo-ts/logic/actionModules/general.js';
|
||||
import { findCrewTypeById, getTechCost } from '@sammo-ts/logic/world/unitSet.js';
|
||||
import type { TurnGeneral } from '../../../types.js';
|
||||
import { asRecord, readMetaNumber, readRequiredMetaNumber } from '../../aiUtils.js';
|
||||
@@ -45,6 +46,35 @@ const clampLegacy = (value: number, min: number | null, max: number | null): num
|
||||
};
|
||||
|
||||
const getFullLeadership = (ai: GeneralAI, general: TurnGeneral): number => {
|
||||
const modules = ai.commandEnv.generalActionModules;
|
||||
if (modules && modules.length > 0) {
|
||||
const pipeline = new GeneralActionPipeline(modules);
|
||||
const adjusted = pipeline.onCalcStat(
|
||||
{
|
||||
general,
|
||||
nation: ai.nation,
|
||||
...(ai.worldRef
|
||||
? {
|
||||
worldView: {
|
||||
listGenerals: () => ai.worldRef!.listGenerals(),
|
||||
listGeneralsByCity: (cityId: number) =>
|
||||
ai.worldRef!.listGenerals().filter((candidate) => candidate.cityId === cityId),
|
||||
listNations: () => ai.worldRef!.listNations(),
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
time: {
|
||||
year: ai.world.currentYear,
|
||||
month: ai.world.currentMonth,
|
||||
startYear: ai.startYear,
|
||||
},
|
||||
},
|
||||
'leadership',
|
||||
general.stats.leadership
|
||||
);
|
||||
const maxStat = ai.commandEnv.maxStatLevel ?? ai.scenarioConfig.stat.max;
|
||||
return Math.trunc(Math.max(0, Math.min(Number(adjusted), maxStat)));
|
||||
}
|
||||
const nationLevel = ai.nation?.level ?? 0;
|
||||
const officerBonus = general.officerLevel === 12 ? nationLevel * 2 : general.officerLevel >= 5 ? nationLevel : 0;
|
||||
const maxStat = ai.commandEnv.maxStatLevel ?? ai.scenarioConfig.stat.max;
|
||||
|
||||
Reference in New Issue
Block a user