feat: 죽음 연도에 따른 killturn 계산 로직 추가 및 관련 메타 데이터 수정
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { createGamePostgresConnector, type InputJsonValue, type TurnEngineEventCreateManyInput } from '@sammo-ts/infra';
|
import { createGamePostgresConnector, type InputJsonValue, type TurnEngineEventCreateManyInput } from '@sammo-ts/infra';
|
||||||
import { asRecord } from '@sammo-ts/common';
|
import { asRecord } from '@sammo-ts/common';
|
||||||
import { buildScenarioBootstrap, type ScenarioBootstrapWarning, type WorldSeedPayload } from '@sammo-ts/logic';
|
import { buildScenarioBootstrap, type GeneralMeta, type ScenarioBootstrapWarning, type WorldSeedPayload } from '@sammo-ts/logic';
|
||||||
|
|
||||||
import type { MapLoaderOptions } from './mapLoader.js';
|
import type { MapLoaderOptions } from './mapLoader.js';
|
||||||
import { loadMapDefinitionByName } from './mapLoader.js';
|
import { loadMapDefinitionByName } from './mapLoader.js';
|
||||||
@@ -143,6 +143,20 @@ const resolveGeneralAge = (startYear: number | null, birthYear: number): number
|
|||||||
return Math.max(startYear - birthYear, 0);
|
return Math.max(startYear - birthYear, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const resolveKillturnFromDeathYear = (
|
||||||
|
currentYear: number,
|
||||||
|
currentMonth: number,
|
||||||
|
deathYear: number,
|
||||||
|
fallback: number
|
||||||
|
): number => {
|
||||||
|
if (!Number.isFinite(deathYear) || deathYear <= 0) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
const deathMonth = Math.floor(Math.random() * 12) + 1;
|
||||||
|
const diff = (deathYear - currentYear) * 12 + (deathMonth - currentMonth);
|
||||||
|
return Math.max(diff, 0);
|
||||||
|
};
|
||||||
|
|
||||||
const buildEventRows = (rows: unknown[], targetOverride?: string): TurnEngineEventCreateManyInput[] => {
|
const buildEventRows = (rows: unknown[], targetOverride?: string): TurnEngineEventCreateManyInput[] => {
|
||||||
const result: TurnEngineEventCreateManyInput[] = [];
|
const result: TurnEngineEventCreateManyInput[] = [];
|
||||||
|
|
||||||
@@ -369,11 +383,30 @@ export const seedScenarioToDatabase = async (options: ScenarioSeedOptions): Prom
|
|||||||
specialCode: general.special ?? 'None',
|
specialCode: general.special ?? 'None',
|
||||||
special2Code: general.specialWar ?? 'None',
|
special2Code: general.specialWar ?? 'None',
|
||||||
lastTurn: asJson({}),
|
lastTurn: asJson({}),
|
||||||
meta: asJson({
|
meta: asJson(
|
||||||
npcType: general.npcType,
|
(() => {
|
||||||
crewTypeId: general.crewTypeId,
|
const meta = { ...general.meta } as Record<string, unknown>;
|
||||||
...general.meta,
|
if (typeof meta.birthYear !== 'number' || !Number.isFinite(meta.birthYear)) {
|
||||||
}),
|
meta.birthYear = general.birthYear;
|
||||||
|
}
|
||||||
|
delete meta.deathYear;
|
||||||
|
delete meta.deadYear;
|
||||||
|
const fallbackKillturn =
|
||||||
|
typeof meta.killturn === 'number' && Number.isFinite(meta.killturn) ? meta.killturn : 0;
|
||||||
|
const killturn = resolveKillturnFromDeathYear(
|
||||||
|
startState.currentYear,
|
||||||
|
startState.currentMonth,
|
||||||
|
general.deathYear,
|
||||||
|
fallbackKillturn
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...meta,
|
||||||
|
killturn,
|
||||||
|
npcType: general.npcType,
|
||||||
|
crewTypeId: general.crewTypeId,
|
||||||
|
} satisfies GeneralMeta;
|
||||||
|
})()
|
||||||
|
),
|
||||||
penalty: asJson({}),
|
penalty: asJson({}),
|
||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ export interface TalentScoutResolveContext<
|
|||||||
TriggerState extends GeneralTriggerState = GeneralTriggerState,
|
TriggerState extends GeneralTriggerState = GeneralTriggerState,
|
||||||
> extends GeneralActionResolveContext<TriggerState> {
|
> extends GeneralActionResolveContext<TriggerState> {
|
||||||
currentYear: number;
|
currentYear: number;
|
||||||
|
currentMonth: number;
|
||||||
worldSummary: TalentScoutWorldSummary;
|
worldSummary: TalentScoutWorldSummary;
|
||||||
generalPool?: TalentScoutCandidate[];
|
generalPool?: TalentScoutCandidate[];
|
||||||
cityPool?: City[];
|
cityPool?: City[];
|
||||||
@@ -86,6 +87,20 @@ const DEFAULT_MAX_AGE = 25;
|
|||||||
const DEFAULT_DEATH_MIN = 10;
|
const DEFAULT_DEATH_MIN = 10;
|
||||||
const DEFAULT_DEATH_MAX = 50;
|
const DEFAULT_DEATH_MAX = 50;
|
||||||
|
|
||||||
|
const resolveKillturnFromDeathYear = (
|
||||||
|
currentYear: number,
|
||||||
|
currentMonth: number,
|
||||||
|
deathYear: number,
|
||||||
|
rng: RandomGenerator
|
||||||
|
): number => {
|
||||||
|
if (!Number.isFinite(deathYear) || deathYear <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const deathMonth = randomRangeInt(rng, 1, 12);
|
||||||
|
const diff = (deathYear - currentYear) * 12 + (deathMonth - currentMonth);
|
||||||
|
return Math.max(diff, 0);
|
||||||
|
};
|
||||||
|
|
||||||
const addMetaValue = (
|
const addMetaValue = (
|
||||||
meta: Record<string, TriggerValue>,
|
meta: Record<string, TriggerValue>,
|
||||||
key: string,
|
key: string,
|
||||||
@@ -302,14 +317,18 @@ export class ActionResolver<
|
|||||||
? this.env.decorateName(resolvedCandidate.name, NPC_TYPE)
|
? this.env.decorateName(resolvedCandidate.name, NPC_TYPE)
|
||||||
: resolvedCandidate.name;
|
: resolvedCandidate.name;
|
||||||
const meta: GeneralMeta = {
|
const meta: GeneralMeta = {
|
||||||
killturn: context.general.meta.killturn,
|
killturn: resolveKillturnFromDeathYear(
|
||||||
|
context.currentYear,
|
||||||
|
context.currentMonth,
|
||||||
|
deathYear,
|
||||||
|
context.rng
|
||||||
|
),
|
||||||
npcType: NPC_TYPE,
|
npcType: NPC_TYPE,
|
||||||
crewTypeId: this.env.defaultCrewTypeId,
|
crewTypeId: this.env.defaultCrewTypeId,
|
||||||
};
|
};
|
||||||
addMetaValue(meta, 'affinity', resolvedCandidate.affinity ?? null);
|
addMetaValue(meta, 'affinity', resolvedCandidate.affinity ?? null);
|
||||||
addMetaValue(meta, 'picture', resolvedCandidate.picture ?? null);
|
addMetaValue(meta, 'picture', resolvedCandidate.picture ?? null);
|
||||||
addMetaValue(meta, 'birthYear', birthYear);
|
addMetaValue(meta, 'birthYear', birthYear);
|
||||||
addMetaValue(meta, 'deathYear', deathYear);
|
|
||||||
addMetaValue(meta, 'text', resolvedCandidate.text ?? null);
|
addMetaValue(meta, 'text', resolvedCandidate.text ?? null);
|
||||||
|
|
||||||
const newGeneral = buildRecruitmentGeneral<TriggerState>({
|
const newGeneral = buildRecruitmentGeneral<TriggerState>({
|
||||||
@@ -393,6 +412,7 @@ export class ActionDefinition<
|
|||||||
export const actionContextBuilder: ActionContextBuilder = (base, options) => ({
|
export const actionContextBuilder: ActionContextBuilder = (base, options) => ({
|
||||||
...base,
|
...base,
|
||||||
currentYear: options.world.currentYear,
|
currentYear: options.world.currentYear,
|
||||||
|
currentMonth: options.world.currentMonth,
|
||||||
worldSummary: buildWorldSummary(options.worldRef),
|
worldSummary: buildWorldSummary(options.worldRef),
|
||||||
createGeneralId: options.createGeneralId,
|
createGeneralId: options.createGeneralId,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export interface VolunteerRecruitResolveContext<
|
|||||||
TriggerState extends GeneralTriggerState = GeneralTriggerState,
|
TriggerState extends GeneralTriggerState = GeneralTriggerState,
|
||||||
> extends GeneralActionResolveContext<TriggerState> {
|
> extends GeneralActionResolveContext<TriggerState> {
|
||||||
currentYear: number;
|
currentYear: number;
|
||||||
|
currentMonth: number;
|
||||||
startYear: number;
|
startYear: number;
|
||||||
averageNationGeneralCount: number;
|
averageNationGeneralCount: number;
|
||||||
nationAverageStats?: StatBlock;
|
nationAverageStats?: StatBlock;
|
||||||
@@ -91,6 +92,20 @@ const DEFAULT_KILLTURN_MIN = 64;
|
|||||||
const DEFAULT_KILLTURN_MAX = 70;
|
const DEFAULT_KILLTURN_MAX = 70;
|
||||||
const DEFAULT_SPEC_AGE = 19;
|
const DEFAULT_SPEC_AGE = 19;
|
||||||
|
|
||||||
|
const resolveKillturnFromDeathYear = (
|
||||||
|
currentYear: number,
|
||||||
|
currentMonth: number,
|
||||||
|
deathYear: number,
|
||||||
|
rng: RandomGenerator
|
||||||
|
): number => {
|
||||||
|
if (!Number.isFinite(deathYear) || deathYear <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const deathMonth = randomRangeInt(rng, 1, 12);
|
||||||
|
const diff = (deathYear - currentYear) * 12 + (deathMonth - currentMonth);
|
||||||
|
return Math.max(diff, 0);
|
||||||
|
};
|
||||||
|
|
||||||
const addMetaValue = (
|
const addMetaValue = (
|
||||||
meta: Record<string, TriggerValue>,
|
meta: Record<string, TriggerValue>,
|
||||||
key: string,
|
key: string,
|
||||||
@@ -269,17 +284,21 @@ export class ActionResolver<
|
|||||||
const deathYear = context.currentYear + deathYears;
|
const deathYear = context.currentYear + deathYears;
|
||||||
const stats = resolveStats(context, context.rng, this.env, candidate);
|
const stats = resolveStats(context, context.rng, this.env, candidate);
|
||||||
const meta: GeneralMeta = {
|
const meta: GeneralMeta = {
|
||||||
killturn: randomRangeInt(context.rng, killTurnMin, killTurnMax),
|
killturn: resolveKillturnFromDeathYear(
|
||||||
|
context.currentYear,
|
||||||
|
context.currentMonth,
|
||||||
|
deathYear,
|
||||||
|
context.rng
|
||||||
|
),
|
||||||
npcType: NPC_TYPE,
|
npcType: NPC_TYPE,
|
||||||
crewTypeId: this.env.defaultCrewTypeId,
|
crewTypeId: this.env.defaultCrewTypeId,
|
||||||
};
|
};
|
||||||
addMetaValue(meta, 'affinity', candidate.affinity ?? null);
|
addMetaValue(meta, 'affinity', candidate.affinity ?? null);
|
||||||
addMetaValue(meta, 'picture', candidate.picture ?? null);
|
addMetaValue(meta, 'picture', candidate.picture ?? null);
|
||||||
addMetaValue(meta, 'birthYear', birthYear);
|
addMetaValue(meta, 'birthYear', birthYear);
|
||||||
addMetaValue(meta, 'deathYear', deathYear);
|
|
||||||
addMetaValue(meta, 'specAge', DEFAULT_SPEC_AGE);
|
addMetaValue(meta, 'specAge', DEFAULT_SPEC_AGE);
|
||||||
addMetaValue(meta, 'specAge2', DEFAULT_SPEC_AGE);
|
addMetaValue(meta, 'specAge2', DEFAULT_SPEC_AGE);
|
||||||
addMetaValue(meta, 'killturn', meta.killturn);
|
addMetaValue(meta, 'killturn', meta.killturn || randomRangeInt(context.rng, killTurnMin, killTurnMax));
|
||||||
addMetaValue(meta, 'text', candidate.text ?? null);
|
addMetaValue(meta, 'text', candidate.text ?? null);
|
||||||
|
|
||||||
const newGeneral = buildRecruitmentGeneral<TriggerState>({
|
const newGeneral = buildRecruitmentGeneral<TriggerState>({
|
||||||
@@ -357,6 +376,7 @@ export const actionContextBuilder: ActionContextBuilder = (base, options) => {
|
|||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
currentYear: options.world.currentYear,
|
currentYear: options.world.currentYear,
|
||||||
|
currentMonth: options.world.currentMonth,
|
||||||
startYear: resolveStartYear(options.world, options.scenarioMeta),
|
startYear: resolveStartYear(options.world, options.scenarioMeta),
|
||||||
averageNationGeneralCount: buildAverageNationGeneralCount(options.worldRef),
|
averageNationGeneralCount: buildAverageNationGeneralCount(options.worldRef),
|
||||||
nationAverageStats: nationSummary.averageStats,
|
nationAverageStats: nationSummary.averageStats,
|
||||||
|
|||||||
@@ -140,6 +140,20 @@ const resolveDeathYear = (deathYear: number, birthYear: number, startYear: numbe
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const resolveKillturnFromDeathYear = (
|
||||||
|
currentYear: number | null,
|
||||||
|
currentMonth: number,
|
||||||
|
deathYear: number,
|
||||||
|
fallback: number
|
||||||
|
): number => {
|
||||||
|
if (currentYear === null || !Number.isFinite(deathYear) || deathYear <= 0) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
const deathMonth = Math.floor(Math.random() * 12) + 1;
|
||||||
|
const diff = (deathYear - currentYear) * 12 + (deathMonth - currentMonth);
|
||||||
|
return Math.max(diff, 0);
|
||||||
|
};
|
||||||
|
|
||||||
const resolveAge = (startYear: number | null, birthYear: number): number => {
|
const resolveAge = (startYear: number | null, birthYear: number): number => {
|
||||||
if (startYear === null || birthYear <= 0) {
|
if (startYear === null || birthYear <= 0) {
|
||||||
return 20;
|
return 20;
|
||||||
@@ -299,7 +313,7 @@ const buildGeneralSeeds = (
|
|||||||
seeds.push(seed);
|
seeds.push(seed);
|
||||||
|
|
||||||
const generalMeta: GeneralMeta = {
|
const generalMeta: GeneralMeta = {
|
||||||
killturn: DEFAULT_GENERAL_KILLTURN,
|
killturn: resolveKillturnFromDeathYear(scenario.startYear, 1, deathYear, DEFAULT_GENERAL_KILLTURN),
|
||||||
npcType,
|
npcType,
|
||||||
crewTypeId: defaultCrewTypeId,
|
crewTypeId: defaultCrewTypeId,
|
||||||
};
|
};
|
||||||
@@ -313,7 +327,6 @@ const buildGeneralSeeds = (
|
|||||||
addTriggerMeta(generalMeta, 'book', row.book ?? undefined);
|
addTriggerMeta(generalMeta, 'book', row.book ?? undefined);
|
||||||
addTriggerMeta(generalMeta, 'item', row.item ?? undefined);
|
addTriggerMeta(generalMeta, 'item', row.item ?? undefined);
|
||||||
addTriggerMeta(generalMeta, 'birthYear', birthYear);
|
addTriggerMeta(generalMeta, 'birthYear', birthYear);
|
||||||
addTriggerMeta(generalMeta, 'deathYear', deathYear);
|
|
||||||
addTriggerMeta(generalMeta, 'text', row.text ?? undefined);
|
addTriggerMeta(generalMeta, 'text', row.text ?? undefined);
|
||||||
|
|
||||||
generals.push({
|
generals.push({
|
||||||
|
|||||||
Reference in New Issue
Block a user