feat: DomesticCommandLoader 및 GeneralAction 관련 타입 개선

This commit is contained in:
2025-12-28 17:27:49 +00:00
parent bfe28773e9
commit 87327cb5b5
3 changed files with 66 additions and 28 deletions
+30 -13
View File
@@ -3,8 +3,10 @@ export interface TurnScheduleEntry {
tickMinutes: number;
}
export type TurnScheduleEntries = [TurnScheduleEntry, ...TurnScheduleEntry[]];
export interface TurnSchedule {
entries: TurnScheduleEntry[];
entries: TurnScheduleEntries;
}
const MINUTES_PER_DAY = 24 * 60;
@@ -26,7 +28,7 @@ const toLocalDateAtMinute = (date: Date, minuteOfDay: number, dayOffset = 0): Da
);
};
const normalizeEntries = (entries: TurnScheduleEntry[]): TurnScheduleEntry[] => {
const normalizeEntries = (entries: TurnScheduleEntries): TurnScheduleEntries => {
const normalized = entries
.map((entry) => ({
startMinute: Math.max(0, Math.min(MINUTES_PER_DAY - 1, entry.startMinute)),
@@ -34,27 +36,33 @@ const normalizeEntries = (entries: TurnScheduleEntry[]): TurnScheduleEntry[] =>
}))
.sort((a, b) => a.startMinute - b.startMinute);
if (normalized.length === 0) {
throw new Error('Turn schedule needs at least one entry.');
}
return normalized;
return normalized as TurnScheduleEntries;
};
const findCurrentEntryIndex = (minuteOfDay: number, entries: TurnScheduleEntry[]): number => {
const findCurrentEntryIndex = (
minuteOfDay: number,
entries: TurnScheduleEntries
): number => {
for (let i = entries.length - 1; i >= 0; i -= 1) {
if (entries[i].startMinute <= minuteOfDay) {
const entry = entries[i];
if (entry && entry.startMinute <= minuteOfDay) {
return i;
}
}
return -1;
};
const getEntryAt = (
entries: TurnScheduleEntries,
index: number
): TurnScheduleEntry =>
entries[Math.max(0, Math.min(entries.length - 1, index))] ?? entries[0];
export const getTickMinutesAt = (date: Date, schedule: TurnSchedule): number => {
const entries = normalizeEntries(schedule.entries);
const minuteOfDay = toMinuteOfDay(date);
const index = findCurrentEntryIndex(minuteOfDay, entries);
const entry = index >= 0 ? entries[index] : entries[entries.length - 1];
const entry = getEntryAt(entries, index >= 0 ? index : entries.length - 1);
return entry.tickMinutes;
};
@@ -67,9 +75,18 @@ export const getNextTurnAt = (date: Date, schedule: TurnSchedule): Date => {
const nextIndex = (currentIndex + 1) % entries.length;
const nextDayOffset = startDayOffset + (nextIndex > currentIndex ? 0 : 1);
const currentEntry = entries[currentIndex];
const segmentStart = toLocalDateAtMinute(date, currentEntry.startMinute, startDayOffset);
const segmentEnd = toLocalDateAtMinute(date, entries[nextIndex].startMinute, nextDayOffset);
const currentEntry = getEntryAt(entries, currentIndex);
const nextEntry = getEntryAt(entries, nextIndex);
const segmentStart = toLocalDateAtMinute(
date,
currentEntry.startMinute,
startDayOffset
);
const segmentEnd = toLocalDateAtMinute(
date,
nextEntry.startMinute,
nextDayOffset
);
const elapsedMinutes = (date.getTime() - segmentStart.getTime()) / 60000;
const nextStep = Math.floor(elapsedMinutes / currentEntry.tickMinutes) + 1;