import {validateWorldAttributeSchema} from '../data/attributeValidation'; import {getTemplateWorldAttributeSchema} from '../data/worldAttributeSchemas'; import type { AttributeSchemaGenerationInput, WorldAttributeSchema, WorldAttributeSlot, } from '../types'; import {WorldType} from '../types'; import {detectCustomWorldThemeMode} from './customWorldTheme'; function buildSchema( input: AttributeSchemaGenerationInput, slots: WorldAttributeSlot[], ): WorldAttributeSchema { return { id: `schema:${input.worldType.toLowerCase()}:${input.worldName}`, worldId: input.worldType === WorldType.CUSTOM ? `custom:${input.worldName}` : input.worldType, schemaVersion: 1, generatedFrom: { worldType: input.worldType, worldName: input.worldName, settingSummary: input.summary, tone: input.tone, conflictCore: input.coreConflicts[0] ?? input.playerGoal, }, slots, }; } function buildCustomThemeSlots(input: AttributeSchemaGenerationInput) { const themeMode = detectCustomWorldThemeMode({ settingText: input.settingText, summary: input.summary, tone: input.tone, playerGoal: input.playerGoal, templateWorldType: /仙|灵|宗门|秘境|裂界/u.test(input.settingText) ? WorldType.XIANXIA : WorldType.WUXIA, }); if (themeMode === 'mythic') { return { slots: [ { slotId: 'axis_a', name: '体魄' }, { slotId: 'axis_b', name: '身法' }, { slotId: 'axis_c', name: '识见' }, { slotId: 'axis_d', name: '胆魄' }, { slotId: 'axis_e', name: '牵引' }, { slotId: 'axis_f', name: '定力' }, ] satisfies WorldAttributeSlot[], }; } if (themeMode === 'machina') { return { slots: [ { slotId: 'axis_a', name: '机锋' }, { slotId: 'axis_b', name: '步准' }, { slotId: 'axis_c', name: '算识' }, { slotId: 'axis_d', name: '潮压' }, { slotId: 'axis_e', name: '协频' }, { slotId: 'axis_f', name: '续载' }, ] satisfies WorldAttributeSlot[], }; } if (themeMode === 'tide') { return { slots: [ { slotId: 'axis_a', name: '潮骨' }, { slotId: 'axis_b', name: '浪步' }, { slotId: 'axis_c', name: '舟识' }, { slotId: 'axis_d', name: '潮魄' }, { slotId: 'axis_e', name: '契汐' }, { slotId: 'axis_f', name: '回澜' }, ] satisfies WorldAttributeSlot[], }; } if (themeMode === 'rift') { return { slots: [ { slotId: 'axis_a', name: '界躯' }, { slotId: 'axis_b', name: '裂步' }, { slotId: 'axis_c', name: '界识' }, { slotId: 'axis_d', name: '界压' }, { slotId: 'axis_e', name: '缚契' }, { slotId: 'axis_f', name: '回脉' }, ] satisfies WorldAttributeSlot[], }; } return { slots: getTemplateWorldAttributeSchema(WorldType.WUXIA).slots, }; } export function generateWorldAttributeSchema(input: AttributeSchemaGenerationInput) { if (input.worldType === WorldType.WUXIA) { return getTemplateWorldAttributeSchema(WorldType.WUXIA); } if (input.worldType === WorldType.XIANXIA) { return getTemplateWorldAttributeSchema(WorldType.XIANXIA); } const generated = buildCustomThemeSlots(input); const schema = buildSchema(input, generated.slots); const issues = validateWorldAttributeSchema(schema); if (issues.length > 0) { const fallbackWorldType = /仙|灵|宗门|秘境|裂界/u.test(input.settingText) ? WorldType.XIANXIA : WorldType.WUXIA; return { ...getTemplateWorldAttributeSchema(fallbackWorldType), id: `schema:custom-fallback:${input.worldName}`, worldId: `custom:${input.worldName}`, generatedFrom: { worldType: WorldType.CUSTOM, worldName: input.worldName, settingSummary: input.summary, tone: input.tone, conflictCore: input.coreConflicts[0] ?? input.playerGoal, }, }; } return schema; }