import { Character, GameState, NpcFamilyState, RealmMajor } from '../../types/domain' import { Rng, seedToRng } from '../kernel/rng' import { randomSurname, MALE_GIVEN, FEMALE_GIVEN } from '../kernel/names' import { newCharacter } from './pcgen' import { NPCS } from '../../data/npcs' import { World } from './World' export interface NewGameOptions { seed: string surname: string familyName: string motto: string difficulty: 'easy' | 'normal' | 'hard' } export function createWorldState(opts: NewGameOptions): GameState { const rng = new Rng(seedToRng(opts.seed)) const surname = opts.surname.trim() || randomSurname(rng) const familyName = opts.familyName.trim() || `${surname}家` const diff = opts.difficulty const stones = diff === 'easy' ? 1200 : diff === 'normal' ? 800 : 550 const npcStrength = diff === 'easy' ? 0.9 : diff === 'normal' ? 1 : 1.15 const state: GameState = { schemaVersion: 1, seed: opts.seed, rng: rng.getState(), year: 1, month: 1, seq: 0, family: { surname, name: familyName, motto: opts.motto.trim() || '耕读传家,术法继世', crest: '#c9a227', estate: '青云庄', yearFounded: 1, generation: 1, reputation: 5, stones, inventory: { lingcao: 60, lingkuang: 30, beastcore: 0, 'pill-qiyuan': 2, 'pill-ningyuan': 1 }, buildings: { lingtian: 1, zongci: 1 }, techniques: ['t-qinglian', 't-houtu'], missionIds: [], headId: '', difficulty: diff, flag: { priceMult: 1, tenants: 0, headBless: 0 } }, members: {}, npcFamilies: Object.fromEntries( NPCS.map((n) => [ n.id, { id: n.id, name: n.name, region: n.region, power: Math.round(n.initialPower * npcStrength), relation: 0, allied: false, raidCount: 0 } as NpcFamilyState ]) ), missions: [], chronicle: [], battles: [], eventQueue: [], completedEvents: [], flags: {}, totalTicks: 0, finance: { accum: 0 }, yearStats: { births: 0, deaths: 0 }, yearlyReports: [], stats: { repPeak: 5, popPeak: 5, maxRealmIdx: 25, techniqueGrand: 0, tourneyHistory: [], feishengCount: 0 } } const w = new World(state, []) const male1: string = rng.pick(MALE_GIVEN) const female1: string = rng.pick(FEMALE_GIVEN) const head: Character = newCharacter(rng, { name: `${surname}${male1}`, gender: 'male', generation: 1, bornYear: 1 - 35, age: 35, realm: { major: 'qi', minor: 4 }, isHead: true, isFounder: true, fortuneBase: 7 }) head.realmProgress = 40 head.techniqueId = 't-qinglian' head.traits = ['tiangan', 'shensui'] const wife: Character = newCharacter(rng, { name: `${surname}${female1}`, gender: 'female', generation: 1, bornYear: 1 - 33, age: 33, realm: { major: 'qi', minor: 2 }, fortuneBase: 6 }) wife.realmProgress = 55 head.spouseId = 'x2' wife.spouseId = 'x1' head.children = ['x3', 'x5'] const elderBrother: Character = newCharacter(rng, { name: `${surname}${rng.pick(MALE_GIVEN)}`, gender: 'male', generation: 2, bornYear: 1 - 16, age: 16, realm: { major: 'qi', minor: 1 }, father: head, mother: wife }) elderBrother.realmProgress = 20 elderBrother.techniqueId = 't-houtu' elderBrother.fatherId = 'x1' elderBrother.motherId = 'x2' const sister: Character = newCharacter(rng, { name: `${surname}${rng.pick(FEMALE_GIVEN)}`, gender: 'female', generation: 2, bornYear: 1 - 12, age: 12, realm: { major: 'mortal', minor: 0 }, father: head, mother: wife }) sister.fatherId = 'x1' sister.motherId = 'x2' const uncle: Character = newCharacter(rng, { name: `${surname}${rng.pick(MALE_GIVEN)}`, gender: 'male', generation: 1, bornYear: 1 - 45, age: 45, realm: { major: 'qi', minor: 6 }, fortuneBase: 6 }) uncle.realmProgress = 30 uncle.techniqueId = 't-houtu' uncle.traits = ['xinheng', 'shensui'] uncle.id = 'x4' uncle.spouseHouse = '四海王氏' uncle.children = [] head.id = 'x1' wife.id = 'x2' elderBrother.id = 'x3' sister.id = 'x5' wife.children = ['x3', 'x5'] state.members = { x1: head, x2: wife, x3: elderBrother, x4: uncle, x5: sister } state.family.headId = 'x1' state.seq = 10 w.chronicle('misc', `${surname}氏一族定居山阴,立${familyName}。庄主${head.name},年方三十五。`, head.id, true) w.log('info', `青云庄立,${familyName}始兴。`) return state } export function findInheritor(world: World): Character | undefined { const alive = world.aliveMembers() if (alive.length === 0) return undefined const head = world.state.members[world.state.family.headId] const candidates = alive.filter((c) => c.id !== head?.id) if (candidates.length === 0) return undefined const byBlood = candidates .filter((c) => (head && head.children.includes(c.id)) || (c.fatherId === head?.id)) .sort((a, b) => world.ageOf(b) - world.ageOf(a)) if (byBlood.length > 0) return byBlood[0] const byRealm = [...candidates].sort((a, b) => { const ra = realmRank(a.realm) const rb = realmRank(b.realm) return rb - ra || b.charm - a.charm || world.ageOf(b) - world.ageOf(a) }) return byRealm[0] } function realmRank(realm: { major: RealmMajor; minor: number }): number { const order: RealmMajor[] = ['mortal', 'qi', 'foundation', 'core', 'nascent', 'spirit'] return order.indexOf(realm.major) * 10 + realm.minor }