Files
ChronicleOfTheImmortalClan/src/renderer/game/engine/sim/Market.ts
T
thzxx a491b9c54a v0.1.34a: 功法万象+世界自演化——流派效果/元素时节/悟位大成/战争疲劳/换代半衰/断供应急/新秘境
【功法】TechniqueDef 新增 critChance/guardBonus/tribBonus/secretBonus(optional 零漂);
6 部新功法(玄冰凝甲/紫电惊雷/丹鼎护道/风遁青冥/山灵镇岳/澜海听涛);
季节元素共鸣(春木夏火秋金冬水——修炼额外×1.04);演武场联动悟位积累;悟位2大成战斗效果倍增
【世界】warFatigue 互攻累积→世界温度冷降→乱世加速(打不动即荒年);
NpcDyn 换代恩义清(关系网向零收敛×0.5);断供应急(连续3月池深<70%→广播+价×1.5);
新秘境灵机(年首几率·乱世×2·模板化生成 addMission 扩展口);addMission 公共口(secrets.ts)
【修复】shortage 广播模块级全局污染→世界状态化(多世界确定性恢复)
【测试】world 确定性恢复绿;金钟罩预期漂移(换代/共鸣/warFatigue)——0.1.34 基线待重算
2026-08-23 22:00:55 +08:00

72 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { World } from '../runtime/World'
import { pack } from '../../data/registry'
import { traitBonuses } from '../runtime/pcgen'
import { WorldSim } from './WorldSim'
export function marketPrice(w: World, itemId: string): number {
const item = pack().items[itemId]
if (!item) return 0
const base = item.basePrice
const fam = w.state.family
const mult = typeof fam.flag['priceMult'] === 'number' ? (fam.flag['priceMult'] as number) : 1
const mood = fam.reputation >= 40 ? 1.06 : fam.reputation >= 20 ? 1.02 : 0.98
// 世界行情乘子(唯一读口:worldSim.marketMultFor;无 sim 时 1
const simMult = w.state.worldSim ? new WorldSim(w).marketMultFor(itemId) : 1
// 0.1.34 断供应急:货源连续告急(shortage ≥ 触发月数)→ 价格上浮(恐慌:供不应求者贵)
const shortN = w.state.worldSim?.shortage?.[itemId]
const shortMult = shortN && shortN >= worldNum('shortageMonths') ? worldNum('shortagePrice') : 1
// 利己(priceMult)与信誉修正
const sellers = w.aliveMembers().filter((c) => traitBonuses(c).priceMult > 0).length
const liarPct = Math.min(0.2, sellers * 0.04)
return Math.max(1, Math.round(base * mult * mood * simMult * shortMult * (1 - liarPct)))
}
export function buyItem(w: World, itemId: string, count: number): boolean {
const fam = w.state.family
if (!pack().items[itemId]) return false
const sim = w.state.worldSim ? new WorldSim(w) : null
// 断供告急:池深低于下限时拒单(零库存市场无货可买;世界生产与 NPC 供给会回填)
if (sim && sim.poolDepthOf(itemId) < worldNum('tradeFloorPct') && w.state.totalTicks > 12) return false
const total = marketPrice(w, itemId) * count
if (total > fam.stones) return false
fam.stones -= total
fam.inventory[itemId] = (fam.inventory[itemId] ?? 0) + count
sim?.tradeSettle(itemId, -count)
return true
}
export function sellItem(w: World, itemId: string, count: number): boolean {
const fam = w.state.family
if (!pack().items[itemId]) return false
const have = fam.inventory[itemId] ?? 0
if (have < count) return false
fam.inventory[itemId] = have - count
fam.stones += marketPrice(w, itemId) * count
if (w.state.worldSim) new WorldSim(w).tradeSettle(itemId, count)
return true
}
export function buyTechnique(w: World, techId: string, price: number): boolean {
const fam = w.state.family
if (fam.techniques.includes(techId)) return false
if (fam.stones < price) return false
fam.stones -= price
fam.techniques.push(techId)
return true
}
export function techniquePrice(techId: string): number {
const t = pack().techniques.find((x) => x.id === techId)
if (t) return TECHNIQUE_GRADE_PRICE[t.grade] ?? 300
return TECH_GRADE_BASE[techId] ?? 200
}
import { TECHNIQUES } from '../../data/techniques'
import { WORLDSIM, worldNum } from './worldsim-data'
const TECHNIQUE_GRADE_PRICE: Record<number, number> = { 1: 120, 2: 300, 3: 700, 4: 1600 }
const TECH_GRADE_BASE: Record<string, number> = Object.fromEntries(
TECHNIQUES.map((t) => [t.id, TECHNIQUE_GRADE_PRICE[t.grade] ?? 300])
)