[M7] 真实怪物:接入 MonStats.txt 与 COF/DCC 怪物美术 #22
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景
当前
src/game/demo-data.ts(45 行)里只有 3 只占位怪:demo-fallen/demo-zombie/demo-skeleton。真实 D2 的MonStats.txt约 700 行。这是被严重低估的「便宜」里程碑
怪物渲染不需要新解码器。
src/game/character.ts的loadCharacterSheet文档明确写着它处理 "character and object animations"src/game/objects.ts已定义MONSTER_ROOT = 'data\\global\\monsters\\'(第 76–78 行)resolveDs1Object已按baseIsMonsters分支(第 611 / 633 / 764 行)tests/dcc.test.ts解出 1633 members / 350032 frames / 0 failed怪物只差接线。
改动清单
src/game/acts.ts——loadActTables目前只加载levels.txt/lvltypes.txt/lvlprest.txt/monstats.txt/MonPreset.txt。追加:MonLvl.txt(难度缩放)MonType.txt(族系,影响免疫与技能克制)SuperUniques.txt(BOSS)MonAi.txtsrc/game/combat.ts——monsterStatsFromRow目前按夹具列名映射,需逐列核对真实MonStats.txt。补齐MonsterStats:抗性、免疫、AI 类型、体型、攻速src/game/monster-sheet.ts—— 封装loadCharacterSheet走MONSTER_ROOT,按怪物 token 解析<token><component><variant><animation><weapon>.dccscripts/pack-act-assets.ts—— 怪物精灵烘焙src/scene/act-scene.ts—— 用MonPreset.txt+ DS1 预设点刷怪,而非随机撒点包体策略(已确认)
按幕分包 + 按需懒加载。 当前烘焙已经 399.3 MB,跨境推送很吃力(实测有效带宽 ~20–50 KB/s),全量怪物精灵不能一次性塞进首屏。
验收
scripts/verify-monsters.ts:全量MonStats.txt行 →MonsterStats映射断言实测核查:怪物生成的三条能力,目前一条都没有
用真实 1.13c MPQ 核查了数据与代码,结论如下。
数据全都在
Levels.txtmon1..10+nmon1..10+umon1..10= 30 列MonDen,MonUMin,MonUMax,MonWndr,MonSpcWalk,NumMonMonStats.txtSuperUniques.txtMonUMod.txtMonLvl.txtMonType.txtMonAi.txt实测三张图的真实数据:
mon普通怪池umon精英池数据很精确:血色荒野
MonUMin/MonUMax是空的(新手图不刷精英),奶牛关密度 800 显著高于野外的 520,石块旷野的精英池用
foulcrow1替换了crownest1。代码侧:三条能力全缺
1. 怪物类型与密度 ——
spawnMonsters的实际行为:angle = attempt * 2.399963),围绕单个出生点stats[placed % stats.length]—— 轮询,不是按池随机minGrp/maxGrp成组刷)2. 精英怪 ——
Monster接口只有index/stats/x/y/hp/cooldown/state/facing/hitFlash/corpseTicks,没有 champion / unique / minion 概念,没有词缀槽。
3. 特殊命名 unique 怪 ——
SuperUniques.txt里 Bishibosh、Rakanishu、Coldcrow、Treehead WoodFist、The Countess、Griswold、Pitspawn Fouldog、Radament 全都在,
带
Class(基础怪)、Mod1/2/3(词缀)、MinGrp/MaxGrp(随从数),零引用。⚠️ 两个必须点破的陷阱
陷阱一:
monstats.txt已加载,但列名 9 个错 8 个loadActTables确实加载了它,map-scene.ts:382在有真表时真的会去读。但
monsterStatsFromRow用的是夹具列名:IdIdNameNameStrHPminHP/maxHPDamageA1MinD/A1MaxDCooldownTicksReachAggroRadiusthreatSpeedVelocity/RunXPExp今天若直接喂真表,735 只怪会全部拿到
DEFAULTS—— 血量、伤害、速度、经验完全一致。这比「没有怪」更危险,因为它看起来在工作。
样本
fallen1真实值:Level=1, minHP=21, maxHP=61, A1MinD=51, A1MaxD=101, Exp=61, AI=Fallen, MonType=fallen—— 且这些不是最终值,需经
MonLvl.txt按等级与难度缩放。陷阱二:
MonPreset.txt不是刷怪表它只有 2 列(
Act,Place),229 行,是 DS1 里 type-1 对象(预置怪物/NPC)的id → 怪物名映射表,当前只用于 DS1 对象解析。与「这张图该刷什么野怪」无关。
因为
loadActTables同时加载了monstats和monpreset,很容易误以为怪物数据已接好。对本里程碑的影响
原描述里「怪物只差接线」那句话只对渲染成立。
选型 / 密度 / 精英 / SuperUnique 这套生成逻辑是从零开始的。
需要新增一个原先没列出的模块:
src/game/monster-spawn.ts——Levels.txt怪物列 → 怪物群的完整转换:按
mon1..10/nmon池选型、按MonDen定密度、按NumMon定种类数、按
MonUMin/MonUMax决定精英数量、按minGrp/maxGrp成组、应用
MonUMod.txt词缀、放置SuperUniques.txt命名怪工作量评估相应上调。SuperUnique 的正确放置依赖 #23。
M7 (Issue #22) 验收完成
MonStats.txt(735 行 255 列)、MonStats2.txt(610 行)、MonLvl.txt、Levels.txt、MonUMod.txt、SuperUniques.txt。L-列、两分支monsterLevelFor等级判定、默认 35 格激怒半径、稀有度与族群预算planLevelMonsters)。src/game/monster-art.ts与src/game/monster-mapping.ts,支持 16 部位通道映射与多图层合成。wl)与待机(nu)动画 0 失败,动态体素全面替换原占位色块。scripts/verify-monsters.ts74/74 项全量断言通过;npm run build生产打包零报错。