fix(game-api): 시나리오 아이템 표시 순서 통일
JSONB에 저장된 품목과 수량을 유지하며 원본 시나리오 순서로 구매·명장일람·유산·전투 시뮬레이터 선택지를 구성한다.
This commit is contained in:
@@ -3,6 +3,10 @@ import { z } from 'zod';
|
||||
|
||||
import { asRecord } from '@sammo-ts/common';
|
||||
import { getDexLevel } from '@sammo-ts/logic';
|
||||
import {
|
||||
resolveLegacyCompatibleUniqueConfig,
|
||||
resolveLegacyPurchasableItemKeys,
|
||||
} from '@sammo-ts/logic/rewards/legacyUniqueItemPool.js';
|
||||
|
||||
import {
|
||||
accessAuthedInputProcedure,
|
||||
@@ -25,6 +29,7 @@ import {
|
||||
loadBattleSimTraitOptions,
|
||||
} from '../../battleSim/simulatorOptions.js';
|
||||
import { getMyGeneral } from '../shared/general.js';
|
||||
import { loadScenarioItemOrder } from '../../services/scenarioItemOrder.js';
|
||||
|
||||
const readNumber = (value: unknown, fallback = 0): number => {
|
||||
if (typeof value === 'number' && Number.isFinite(value)) {
|
||||
@@ -98,7 +103,17 @@ export const battleRouter = router({
|
||||
}
|
||||
|
||||
const environment = await buildBattleSimEnvironment(worldState, ctx.profile.id);
|
||||
const [traits, items] = await Promise.all([loadBattleSimTraitOptions(), loadBattleSimItemOptions()]);
|
||||
const configConst = asRecord(asRecord(worldState.config).const);
|
||||
const [traits, itemOrder, uniqueConfig] = await Promise.all([
|
||||
loadBattleSimTraitOptions(),
|
||||
loadScenarioItemOrder(worldState.scenarioCode),
|
||||
resolveLegacyCompatibleUniqueConfig(configConst),
|
||||
]);
|
||||
const allowedItems = new Set([
|
||||
...resolveLegacyPurchasableItemKeys(configConst),
|
||||
...Object.values(uniqueConfig.allItems).flatMap((entries) => Object.keys(entries ?? {})),
|
||||
]);
|
||||
const items = await loadBattleSimItemOptions(allowedItems, itemOrder);
|
||||
|
||||
return {
|
||||
world: {
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
} from '../../services/inheritance.js';
|
||||
import type { GameApiContext, WorldStateRow } from '../../context.js';
|
||||
import { openAuctionWithDaemon } from '../../auction/open.js';
|
||||
import { loadScenarioItemOrder, orderScenarioItemEntries } from '../../services/scenarioItemOrder.js';
|
||||
|
||||
const BUFF_KEYS: InheritBuffType[] = [
|
||||
'warAvoidRatio',
|
||||
@@ -65,10 +66,11 @@ const loadAvailableUniqueItems = async (worldState: WorldStateRow) => {
|
||||
const configConst = asRecord(asRecord(worldState.config).const);
|
||||
const loader = new ItemLoader();
|
||||
const { allItems } = await resolveLegacyCompatibleUniqueConfig(configConst, loader);
|
||||
const itemOrder = await loadScenarioItemOrder(worldState.scenarioCode);
|
||||
const enabledKeys: Array<Parameters<ItemLoader['load']>[0]> = [];
|
||||
for (const slot of UNIQUE_ITEM_SLOT_ORDER) {
|
||||
const entries = allItems[slot] ?? {};
|
||||
for (const [key, amount] of Object.entries(asRecord(entries))) {
|
||||
for (const [key, amount] of orderScenarioItemEntries(asRecord(entries), itemOrder)) {
|
||||
if (asNumber(amount, 0) !== 0 && isItemKey(key)) {
|
||||
enabledKeys.push(key);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
findLegacyHallRows,
|
||||
isLegacyArchiveProfile,
|
||||
} from '../../services/legacyArchiveStore.js';
|
||||
import { loadScenarioItemOrder, orderScenarioItemEntries } from '../../services/scenarioItemOrder.js';
|
||||
|
||||
const DEFAULT_BG_COLOR = '#330000';
|
||||
const DEFAULT_FG_COLOR = '#ffffff';
|
||||
@@ -98,7 +99,7 @@ export const rankingRouter = router({
|
||||
.optional()
|
||||
).query(async ({ ctx, input }) => {
|
||||
const worldState = await ctx.db.worldState.findFirst({
|
||||
select: { meta: true, config: true },
|
||||
select: { meta: true, config: true, scenarioCode: true },
|
||||
});
|
||||
const meta = asRecord(worldState?.meta);
|
||||
const isUnited = typeof meta.isUnited === 'number' && meta.isUnited !== 0;
|
||||
@@ -309,6 +310,7 @@ export const rankingRouter = router({
|
||||
if (Object.keys(uniqueConfig.allItems).length === 0) {
|
||||
uniqueConfig.allItems = buildLegacyDefaultUniqueItemPool(itemRegistry);
|
||||
}
|
||||
const itemOrder = await loadScenarioItemOrder(worldState?.scenarioCode ?? '');
|
||||
const activeAuctions = await ctx.db.auction.findMany({
|
||||
where: {
|
||||
type: 'UNIQUE_ITEM',
|
||||
@@ -330,7 +332,7 @@ export const rankingRouter = router({
|
||||
item: '도 구',
|
||||
} as const;
|
||||
const itemEntries = (['horse', 'weapon', 'book', 'item'] as const).map((slot) => {
|
||||
const configuredItems = Object.entries(uniqueConfig.allItems[slot] ?? {}).reverse();
|
||||
const configuredItems = orderScenarioItemEntries(uniqueConfig.allItems[slot] ?? {}, itemOrder).reverse();
|
||||
const entries = configuredItems.flatMap(([itemKey, rawCount]) => {
|
||||
const item = itemRegistry.get(itemKey);
|
||||
if (!item || item.buyable) {
|
||||
|
||||
Reference in New Issue
Block a user