troytt
967a545116
fix(skill): implement Thunder Storm ambient aura and sky strike ( Fixes #433 )
2026-09-24 14:29:45 +00:00
troytt
bfc1164d9b
feat(necro): implement Milestone M3 Necromancer Curses Tree (10 skills)
...
- Implement core curse formulas (radius, duration, debuff stats, immunity breaking)
- Enforce 1.13c ground truth invariants:
* Amplify Damage (-100% phys res, or -20% on immune)
* Decrepify (-50% phys res / -10% on immune, -50% speed, -50% attack rate, -50% damage dealt)
* Lower Resist (-dm56% on fire/lightning/cold/poison, 1/5th penalty on immune)
* Life Tap (50% physical life leech on hit)
* Iron Maiden (reflects 200%..675% physical melee damage back to attacker)
* Weaken (-33% damage dealt)
* Attract (cursetype = 2, immune to overwrite, cannot recast on attracted unit)
* Mental curse immunity for Bosses & Champions (Dim Vision, Terror, Confuse, Attract)
* 2:1 isometric radius targeting and overhead animated overlays
- Add primary verification suite (tests/skills/nec/curses.test.ts)
- Add adversarial challenger stress suite (tests/skills/nec/adv-curses-stress.test.ts)
2026-09-24 09:21:30 +00:00
troytt
7f2dff56ee
feat(combat): fix kill event lifecycle & single-drop gate ( Fixes #404 )
2026-09-24 06:15:36 +00:00
troytt
2e061b3257
feat(skills): implement Enchant (52) and Fire Mastery (61) with authentic 1.13c parity
...
- Implement 1.13c Enchant 5-band weapon fire damage progression (HitShift 7, Warmth 9%/blvl synergy)
- Implement Enchant Attack Rating bonus (20% + 9%/slvl) and duration (3600 + 600/slvl frames)
- Implement Fire Mastery passive fire damage bonus (30% + 7%/slvl) in stat-list and combat-pipeline
- Implement authentic Sorceress melee double-dip and ranged 33% weapon fire damage penalty
- Enforce fire immunity preservation (res >= 100% takes 0 fire damage, Fire Mastery cannot pierce)
- Wire Enchant cast skill (52) and overlay animation in act-scene and engine
- Maintain BATCH1_SKILLS invariant strictly at 38
- Add comprehensive 7-dimensional verification suites for Enchant and Fire Mastery (31 tests passing)
- Closes #206 , Closes #215
2026-09-24 03:59:47 +00:00
troytt
6aa951e8cc
fix(skills): remediate Milestone 3 gate failures for Inferno range and channeled mana drain
...
- Fix calculateInfernoRangePx to authentic 1.13c ratio: calculateInfernoRange(slvl) * 32 (32 px/subtile).
- Update act-scene.ts flame stream ttl calculation to Math.min(60, Math.round(rangePx / speed)) allowing authentic travel reach.
- Connect continuous channeled mana drain in act-scene.ts: drain (36 + slvl - 1) * 4 / 256 mana per frame with fractional accumulator, stopping channel on mana depletion.
- Update tests/skills/sor/skill-041-inferno.test.ts assertions to 320/752/1232 px and add runtime continuous mana drain tests.
- Persist adversarial stress test suites (adv-fire-m3-math-stress.test.ts and adv-fire-m3-geom-stress.test.ts).
2026-09-24 03:20:48 +00:00
troytt
df4c5b66b0
feat(skills): implement Fire Wall, Blaze, and Inferno with 1.13c parity ( closes #205 , closes #200 , closes #195 )
2026-09-24 02:46:20 +00:00
troytt
2d6bbb93a2
fix(sor-cold): remediate number overload contract and wire reactive combat hooks (Issue #194 , #204 , #214 )
...
- Fix calculateShiverArmorDamage and calculateChillingArmorDamage number overload to treat number as allocated synergy points (synPoints) with 1.13c percentage scaling, supporting explicit options.synMultiplier override
- Guard duration and chill/freeze length calculators against negative synergy inputs with Math.max(0, synPoints)
- Wire reactive combat hooks in combat.ts (tickMonsters/updateMonsters and hitPlayerWithMissile):
* Frozen Armor: reactively freezes attacking monster upon taking physical melee damage
* Shiver Armor: proactively chills and damages attacking monster upon melee attack initiation
* Chilling Armor: reflects retaliatory chillingarmorbolt on incoming ranged missiles with returnFire=false
- Wire proactive and reactive combat events in combat-pipeline.ts (executeSUnitDmg):
* Dispatches attackedinmelee proactively before hit resolution
* Dispatches damagedinmelee post-damage on melee hits
* Dispatches hitbymissile post-damage on missile hits
* Exposes attackerStatesApplied, attackerColdDamage256, reflectedPhys256, and spawnedMissiles on SUnitDmgOutcome
- Add comprehensive remediation test suite tests/skills/sor/cold-armors-remediation.test.ts
2026-09-24 01:06:25 +00:00
troytt
e7d105dce0
feat(skills): implement Frozen Armor, Shiver Armor, and Chilling Armor with 1.13c parity ( closes #194 , closes #204 , closes #214 )
2026-09-24 00:29:57 +00:00
troytt
a0567c2473
feat(skills): implement Thunder Storm, Energy Shield, and Lightning Mastery with 1.13c parity ( closes #211 , closes #212 , closes #217 )
...
- Thunder Storm (57):
* Authentic 1.13c duration: 800 + (slvl - 1) * 200 frames (Param1=800, Param2=200).
* Hyperbolic cadence decay: Math.max(25, 125 - Math.floor((110 * slvl) / (slvl + 6))) frames.
* Range: 17 subtiles = 340px (Param7=17).
* 5-band piecewise lightning damage (1-100 base, +10/+10/+11 across bands).
* Authentic missile 'thunderstorm1' (ID 166, CelFile 'LightningboltBig', animLen 8) and cast overlay 'light_cast_2'.
* Zero synergies in 1.13c; multiplicative scaling with Lightning Mastery.
- Energy Shield (58):
* Authentic duration: 3600 + (slvl - 1) * 1500 frames (Param1=3600, Param2=1500).
* 1.13c piecewise absorb percentage: 20% lvl 1, +5% lvl 2-8, +2% lvl 9-16, +1% lvl 17+, strictly hard capped at 95% (slvl 40).
* Telekinesis hard synergy ratio: (32 - Math.min(20, Math.max(0, tkBlvl))) / 16 (2.0 down to 0.75). Hard points only (blvl); soft points ignored.
* Absorbs raw incoming damage BEFORE player resistances are applied. Remainder mitigated by player resistances.
* Poison (elemType === 'pois' || isPoison) and Open Wounds strictly bypass ES directly to HP.
* Mana depletion drains mana to 0, collapses shield, and spills unabsorbed damage to HP.
* Overlays: 'energyshield' looping body overlay and 'energyshieldhit0' directional hit overlay.
- Lightning Mastery (63):
* Passive formula: 50 + (slvl - 1) * 12 percent (+50% at lvl 1, +62% at lvl 2, +158% at lvl 10, +278% at lvl 20, +518% at lvl 40).
* Multiplicative scaling with synergies across all 5 lightning skills (Charged Bolt, Lightning, Chain Lightning, Nova, Thunder Storm): Final = Math.floor(Base * (1 + Syn/100) * (1 + Mastery/100)).
* StatList accrued stat 'passive_ltng_mastery' integration and combat pipeline executeSUnitDmg support.
- 7-Dimensional Vitest Suites:
* Full 7-D coverage for skill-057-thunder-storm.test.ts (15 tests passing).
* Full 7-D coverage for skill-058-energy-shield.test.ts (15 tests passing).
* Full 7-D coverage for skill-063-lightning-mastery.test.ts (17 tests passing).
* Invariants: BATCH1_SKILLS length strictly 38, zero runtime MPQ queries.
* Full repo test suite passing (414 test files, 4213 tests passing, 0 errors).
2026-09-23 20:33:24 +00:00
troytt
0e0cd3adee
feat(skills): harden 1.13c Nova and Static Field against adversarial probes ( fixes #196 , #202 )
...
- Fix ghost property resistLightning to respect monster resistances and lightningResist in act-scene.ts
- Wire monster resistances across MonsterStats and applyEliteModifiers in combat.ts and monsters.ts
- Clamp Static Field damage non-lethally post-resistance scaling and protect against difficulty floor underflow in missile-engine.ts
- Implement continuous sub-step collision and raycast line-of-sight in missile-engine.ts and skills.ts
- Add persistent NextDelay tracking on GameEngine with automatic per-tick expired entry pruning
- Align Nova (64 bolts, aspect ratio 0.5, NextDelay 4) and Static Field in executeSkillCore113c
2026-09-23 17:14:53 +00:00
troytt
c814376e8a
fix(ground-items): authentic ground item icon sprites and eliminate residual white dot
2026-09-23 05:48:03 +00:00
troytt
627af83e97
feat(skills): authentic 1.13c Fire Bolt projectile physics from Missiles.txt ( Fixes #385 )
2026-09-23 02:09:50 +00:00
troytt
064e956de6
feat(items): 用 TC 树替换 rollDrop 并彻底删除 demo 物品数据 (Issue #107 )
2026-09-18 12:54:21 +00:00
troytt
bd7486cc99
refactor(engine): eliminate duplicated presets and constants (single source of truth)
...
- Define BLOOD_MOOR_RIVER_PRESETS and BLOOD_MOOR_POND_PRESETS to make SPECIAL_PRESETS_BY_LEVEL[2] canonical and eliminate inline duplicates
- Import PACK_RADIUS_PX from monster-rooms.ts in combat.ts to establish a single source of truth
- Replace literal * 5 with * SUB_TILES_PER_TILE in wilderness-acts.ts
TAG=agy
CONV=2a1934de-30ef-464e-b3f3-fcbcdbbc49f1
2026-09-17 15:50:24 +00:00
troytt
c2bda29211
Merge remote-tracking branch 'origin/feat/monster-streaming' into feat/monster-room-placement
2026-09-17 08:36:02 +00:00
troytt
8e46b64156
feat(monsters): room-local pack allocation and clustering placement
2026-09-17 08:35:11 +00:00
troytt
71fdaaefe3
feat(sim/monsters): lazy room population with bPopulated and active/sleeping streaming
2026-09-17 08:33:19 +00:00
troytt
e9f2ceec9b
feat(map-gen/population): implement wilderness population phase, waypoints, shrines, superuniques & safe zones ( fixes #36 )
2026-09-17 03:44:12 +00:00
troytt
dcd3da0a22
feat(combat): disable monster aggro in act-scene so monsters stay idle in place
2026-09-16 02:21:17 +00:00
troytt
d6e624829a
fix(monster): fix loading performance, monster facing, and spawn logic ( #30 , #31 , #32 )
...
- Fix #30 : Concurrent layer/animation decoding and shared MPQ archive caching to reduce load latency
- Fix #31 : Use dir64ToDcc for permuted 8-direction DCC extraction in monster art compositing and align 8-way facing calculation
- Fix #32 : Prevent monster spawning in town/safe zones, support hellbovine cow packs, and cluster packs properly
2026-09-15 15:03:28 +00:00
taodao
70b299569e
M7 第一步:真实怪物数据层
...
把 MonStats.txt 读进来,并给它一个能发现错误的检验。
新增 src/game/monsters.ts。它和 combat.ts 里的 monsterStatsFromRow
是两个读取器,不是一个:后者读的是九列的测试夹具(Id/Name/HP/...),
真实的 MonStats.txt 有 255 列且几乎没有一个同名——是 NameStr 不是
Name,是 minHP/maxHP 不是 HP,是 Exp 不是 XP。把夹具读取器指向真表
不会报错,只会让 735 只怪物拿到同一套默认值,看起来像是能用。
新增 scripts/verify-monsters.ts(52 项检查)与 tests/monsters.test.ts
(41 项)。检验脚本一上来就发现了七处问题,其中两处是数据本身的事实,
值得记下来:
- MinHP(N)/MinHP(H) 不是「更高难度的血量」。fallen1 普通 21-61,
噩梦和地狱都是 25-55;594 个有血量的行里有 426 行的 MaxHP(N) 比
maxHP 更低;Duriel 从普通的 4757 掉到地狱的 1295。真正的难度缩放
来自 MonLvl.txt 对普通值的逐等级放大,这些列是只对 boss 生效的覆盖,
而且数据自己用得并不一致。按铁律六,读取器照实读、照实记,不假装
它们是缩放,缩放留给 M9。
- MonStats2.txt 只有 610 行,配 735 只怪物。缺的 119 只是编号变体
(quillrat6、slinger7、deathmauler6 等),游戏用它们 BaseId 的美术
来画。只按 id 查会让这 119 只变成一片空地而不是一个报错,所以
readMonsterArt 走 BaseId 回退。
另外三处是数据里的既有瑕疵,现在被显式承认而不是被抹平:
MonStats.txt 里 cr_lancer8 重复出现两次(检验断言「唯一的重复是这一个」,
新的重复仍会失败);SuperUniques.txt 里的 Expansion 是分节行,有名字
没有 Class;还有两处是我手抄表格时抄错了(foulcrow1 的 MonType 是
foulcrow 不是 bat,hellbovine 的 NameStr 带空格)。
combat.ts 新增 spawnMonsterPacks。原有的 spawnMonsters 把怪物撒在黄金角
螺旋上,那是让互不相干的东西均匀散开的形状,恰好是堕落者营地最不该有的
形状——螺旋上相邻的两点是刻意离得远的。现在螺旋放的是营地,成员在自己
营地里成团。附 tests/monster-packs.test.ts(11 项),直接量距离而不是
看截图。
acts.ts 的 ActTables 增加 MonStats2/MonLvl/MonType/MonUMod/SuperUniques。
验证:tsc 零错误;npm test 502 通过(基线 461);
npm run verify:monsters 52/52。
TAG=agy
CONV=c89513df-cd12-4749-b5bd-5e9f16639391
2026-09-15 08:06:52 +00:00
troytt
897b3735d6
初始提交:从零实现的暗黑破坏神 II WebGL2 引擎(TypeScript + Vite,零运行时依赖)
...
内容概览
- 归档层:MPQ v1 容器(hash/block 表、Storm 加密、分扇区编解码),含 PKWARE
implode/explode 移植;支持 HTTP Range 只读取所需字节。
- 格式层:dc6 / ds1 / dt1 / pal / pl2 / cel / pcx / tbl / sprite,以及 dcc / cof / bitstream。
- 地图层:等距投影场景构建(地板/墙/屋顶分层、逐格瓦片变体加权随机、sub-tile 碰撞),
资源包(索引色 PNG 图集 + scene.json)离线烘焙与逐像素差分校验。
- 角色层:DCC + COF 合成(8 方向),法师行走/站立替换占位棋子。
- 页面:acts.html 全屏画布 + 三级选择器(章节 / 场景 / 细分场景),资源包优先、
可回退到直读归档(?live=1)。
- 验证脚本:verify:all / implode / acts / d2 / packs / dcc / deploy / listfile /
object-lookup / alignment / tiles / generators 等,均带断言与退出码。
数据与许可
- 游戏数据(samples/)与第三方参考源码(reference/)不入库:体积大且无再分发许可,
见 THIRD_PARTY_NOTICES.md。
- 生成关卡(70 迷宫 + 31 野外)尚未烘焙,现状与修复清单见 HANDOVER.md §4f。
2026-09-13 18:10:28 +08:00