@rpgm-tools/neo-angband-core 0.17.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/agent/perceive.d.ts.map +1 -1
- package/dist/agent/perceive.js +2 -2
- package/dist/agent/perceive.js.map +1 -1
- package/dist/combat/blow-vectors.d.ts +78 -0
- package/dist/combat/blow-vectors.d.ts.map +1 -0
- package/dist/combat/blow-vectors.fixtures.d.ts +19 -0
- package/dist/combat/blow-vectors.fixtures.d.ts.map +1 -0
- package/dist/combat/blow-vectors.fixtures.js +81 -0
- package/dist/combat/blow-vectors.fixtures.js.map +1 -0
- package/dist/combat/blow-vectors.js +195 -0
- package/dist/combat/blow-vectors.js.map +1 -0
- package/dist/combat/brand-slay.d.ts +22 -9
- package/dist/combat/brand-slay.d.ts.map +1 -1
- package/dist/combat/brand-slay.js +37 -10
- package/dist/combat/brand-slay.js.map +1 -1
- package/dist/combat/index.d.ts +1 -1
- package/dist/combat/index.js +1 -1
- package/dist/combat/melee.d.ts +25 -13
- package/dist/combat/melee.d.ts.map +1 -1
- package/dist/combat/melee.js +23 -19
- package/dist/combat/melee.js.map +1 -1
- package/dist/combat/mon-melee.d.ts +166 -7
- package/dist/combat/mon-melee.d.ts.map +1 -1
- package/dist/combat/mon-melee.js +469 -338
- package/dist/combat/mon-melee.js.map +1 -1
- package/dist/combat/ranged.d.ts +15 -13
- package/dist/combat/ranged.d.ts.map +1 -1
- package/dist/combat/ranged.js +31 -29
- package/dist/combat/ranged.js.map +1 -1
- package/dist/constants.d.ts +14 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +14 -0
- package/dist/constants.js.map +1 -1
- package/dist/datafile.d.ts +48 -0
- package/dist/datafile.d.ts.map +1 -0
- package/dist/datafile.js +102 -0
- package/dist/datafile.js.map +1 -0
- package/dist/effects/effect-info-registry.d.ts +237 -0
- package/dist/effects/effect-info-registry.d.ts.map +1 -0
- package/dist/effects/effect-info-registry.js +138 -0
- package/dist/effects/effect-info-registry.js.map +1 -0
- package/dist/effects/effect-info-vectors.d.ts +92 -0
- package/dist/effects/effect-info-vectors.d.ts.map +1 -0
- package/dist/effects/effect-info-vectors.fixtures.d.ts +18 -0
- package/dist/effects/effect-info-vectors.fixtures.d.ts.map +1 -0
- package/dist/effects/effect-info-vectors.fixtures.js +51 -0
- package/dist/effects/effect-info-vectors.fixtures.js.map +1 -0
- package/dist/effects/effect-info-vectors.js +315 -0
- package/dist/effects/effect-info-vectors.js.map +1 -0
- package/dist/effects/effect-info.d.ts +5 -1
- package/dist/effects/effect-info.d.ts.map +1 -1
- package/dist/effects/effect-info.js +245 -143
- package/dist/effects/effect-info.js.map +1 -1
- package/dist/effects/effect.d.ts +4 -3
- package/dist/effects/effect.d.ts.map +1 -1
- package/dist/effects/effect.js +88 -70
- package/dist/effects/effect.js.map +1 -1
- package/dist/effects/handlers.d.ts +1 -1
- package/dist/effects/handlers.d.ts.map +1 -1
- package/dist/effects/handlers.js +5 -2
- package/dist/effects/handlers.js.map +1 -1
- package/dist/effects/interpreter.d.ts +11 -0
- package/dist/effects/interpreter.d.ts.map +1 -1
- package/dist/effects/interpreter.js +13 -0
- package/dist/effects/interpreter.js.map +1 -1
- package/dist/game/cave-cmd.d.ts +9 -5
- package/dist/game/cave-cmd.d.ts.map +1 -1
- package/dist/game/cave-cmd.js +56 -11
- package/dist/game/cave-cmd.js.map +1 -1
- package/dist/game/cave-square.d.ts +42 -0
- package/dist/game/cave-square.d.ts.map +1 -0
- package/dist/game/cave-square.js +73 -0
- package/dist/game/cave-square.js.map +1 -0
- package/dist/game/char-sheet.d.ts +12 -8
- package/dist/game/char-sheet.d.ts.map +1 -1
- package/dist/game/char-sheet.js +41 -8
- package/dist/game/char-sheet.js.map +1 -1
- package/dist/game/chest.d.ts +2 -3
- package/dist/game/chest.d.ts.map +1 -1
- package/dist/game/chest.js +17 -6
- package/dist/game/chest.js.map +1 -1
- package/dist/game/context.d.ts +213 -22
- package/dist/game/context.d.ts.map +1 -1
- package/dist/game/context.js +109 -17
- package/dist/game/context.js.map +1 -1
- package/dist/game/describe.d.ts +13 -0
- package/dist/game/describe.d.ts.map +1 -1
- package/dist/game/describe.js +32 -4
- package/dist/game/describe.js.map +1 -1
- package/dist/game/display.d.ts +97 -8
- package/dist/game/display.d.ts.map +1 -1
- package/dist/game/display.js +157 -13
- package/dist/game/display.js.map +1 -1
- package/dist/game/dump-level.d.ts.map +1 -1
- package/dist/game/dump-level.js +3 -2
- package/dist/game/dump-level.js.map +1 -1
- package/dist/game/effect-attack.d.ts.map +1 -1
- package/dist/game/effect-attack.js +36 -27
- package/dist/game/effect-attack.js.map +1 -1
- package/dist/game/effect-detect.d.ts +4 -4
- package/dist/game/effect-detect.d.ts.map +1 -1
- package/dist/game/effect-detect.js +42 -9
- package/dist/game/effect-detect.js.map +1 -1
- package/dist/game/effect-env.d.ts +7 -1
- package/dist/game/effect-env.d.ts.map +1 -1
- package/dist/game/effect-env.js +1 -0
- package/dist/game/effect-env.js.map +1 -1
- package/dist/game/effect-general.d.ts +5 -3
- package/dist/game/effect-general.d.ts.map +1 -1
- package/dist/game/effect-general.js +94 -43
- package/dist/game/effect-general.js.map +1 -1
- package/dist/game/effect-item.d.ts +2 -1
- package/dist/game/effect-item.d.ts.map +1 -1
- package/dist/game/effect-item.js +136 -82
- package/dist/game/effect-item.js.map +1 -1
- package/dist/game/effect-melee.d.ts +10 -4
- package/dist/game/effect-melee.d.ts.map +1 -1
- package/dist/game/effect-melee.js +44 -19
- package/dist/game/effect-melee.js.map +1 -1
- package/dist/game/effect-monster.d.ts +26 -4
- package/dist/game/effect-monster.d.ts.map +1 -1
- package/dist/game/effect-monster.js +52 -9
- package/dist/game/effect-monster.js.map +1 -1
- package/dist/game/effect-teleport.d.ts +58 -19
- package/dist/game/effect-teleport.d.ts.map +1 -1
- package/dist/game/effect-teleport.js +143 -27
- package/dist/game/effect-teleport.js.map +1 -1
- package/dist/game/effect-terrain.d.ts +1 -3
- package/dist/game/effect-terrain.d.ts.map +1 -1
- package/dist/game/effect-terrain.js +38 -22
- package/dist/game/effect-terrain.js.map +1 -1
- package/dist/game/equip-cmp.d.ts.map +1 -1
- package/dist/game/equip-cmp.js +10 -7
- package/dist/game/equip-cmp.js.map +1 -1
- package/dist/game/floor.d.ts +16 -4
- package/dist/game/floor.d.ts.map +1 -1
- package/dist/game/floor.js +22 -4
- package/dist/game/floor.js.map +1 -1
- package/dist/game/gear.d.ts +101 -13
- package/dist/game/gear.d.ts.map +1 -1
- package/dist/game/gear.js +183 -24
- package/dist/game/gear.js.map +1 -1
- package/dist/game/harness.d.ts +2 -1
- package/dist/game/harness.d.ts.map +1 -1
- package/dist/game/harness.js +12 -1
- package/dist/game/harness.js.map +1 -1
- package/dist/game/ignore-cmd.d.ts +47 -8
- package/dist/game/ignore-cmd.d.ts.map +1 -1
- package/dist/game/ignore-cmd.js +76 -8
- package/dist/game/ignore-cmd.js.map +1 -1
- package/dist/game/known.d.ts +223 -34
- package/dist/game/known.d.ts.map +1 -1
- package/dist/game/known.js +301 -67
- package/dist/game/known.js.map +1 -1
- package/dist/game/loop.d.ts +4 -3
- package/dist/game/loop.d.ts.map +1 -1
- package/dist/game/loop.js +49 -29
- package/dist/game/loop.js.map +1 -1
- package/dist/game/lore-color.d.ts.map +1 -1
- package/dist/game/lore-color.js +13 -1
- package/dist/game/lore-color.js.map +1 -1
- package/dist/game/mon-cast.d.ts +3 -4
- package/dist/game/mon-cast.d.ts.map +1 -1
- package/dist/game/mon-cast.js +30 -2
- package/dist/game/mon-cast.js.map +1 -1
- package/dist/game/mon-cmd.d.ts +4 -5
- package/dist/game/mon-cmd.d.ts.map +1 -1
- package/dist/game/mon-cmd.js +80 -27
- package/dist/game/mon-cmd.js.map +1 -1
- package/dist/game/mon-death.d.ts +8 -4
- package/dist/game/mon-death.d.ts.map +1 -1
- package/dist/game/mon-death.js +6 -9
- package/dist/game/mon-death.js.map +1 -1
- package/dist/game/mon-group.d.ts +9 -5
- package/dist/game/mon-group.d.ts.map +1 -1
- package/dist/game/mon-group.js +9 -5
- package/dist/game/mon-group.js.map +1 -1
- package/dist/game/mon-message.d.ts +90 -40
- package/dist/game/mon-message.d.ts.map +1 -1
- package/dist/game/mon-message.js +267 -59
- package/dist/game/mon-message.js.map +1 -1
- package/dist/game/mon-place.d.ts +11 -1
- package/dist/game/mon-place.d.ts.map +1 -1
- package/dist/game/mon-place.js +15 -3
- package/dist/game/mon-place.js.map +1 -1
- package/dist/game/mon-ranged.d.ts +2 -1
- package/dist/game/mon-ranged.d.ts.map +1 -1
- package/dist/game/mon-ranged.js +11 -5
- package/dist/game/mon-ranged.js.map +1 -1
- package/dist/game/mon-side.d.ts +3 -2
- package/dist/game/mon-side.d.ts.map +1 -1
- package/dist/game/mon-side.js +15 -14
- package/dist/game/mon-side.js.map +1 -1
- package/dist/game/monster-turn.d.ts +20 -10
- package/dist/game/monster-turn.d.ts.map +1 -1
- package/dist/game/monster-turn.js +110 -83
- package/dist/game/monster-turn.js.map +1 -1
- package/dist/game/notice.d.ts +36 -0
- package/dist/game/notice.d.ts.map +1 -0
- package/dist/game/notice.js +79 -0
- package/dist/game/notice.js.map +1 -0
- package/dist/game/obj-cmd.d.ts +14 -3
- package/dist/game/obj-cmd.d.ts.map +1 -1
- package/dist/game/obj-cmd.js +109 -35
- package/dist/game/obj-cmd.js.map +1 -1
- package/dist/game/obj-list.d.ts +13 -2
- package/dist/game/obj-list.d.ts.map +1 -1
- package/dist/game/obj-list.js +42 -27
- package/dist/game/obj-list.js.map +1 -1
- package/dist/game/object-inspect.d.ts +9 -0
- package/dist/game/object-inspect.d.ts.map +1 -1
- package/dist/game/object-inspect.js +4 -0
- package/dist/game/object-inspect.js.map +1 -1
- package/dist/game/pickup.d.ts +0 -2
- package/dist/game/pickup.d.ts.map +1 -1
- package/dist/game/pickup.js +18 -3
- package/dist/game/pickup.js.map +1 -1
- package/dist/game/player-side-vectors.d.ts +174 -0
- package/dist/game/player-side-vectors.d.ts.map +1 -0
- package/dist/game/player-side-vectors.fixtures.d.ts +33 -0
- package/dist/game/player-side-vectors.fixtures.d.ts.map +1 -0
- package/dist/game/player-side-vectors.fixtures.js +191 -0
- package/dist/game/player-side-vectors.fixtures.js.map +1 -0
- package/dist/game/player-side-vectors.js +292 -0
- package/dist/game/player-side-vectors.js.map +1 -0
- package/dist/game/player-side.d.ts +129 -1
- package/dist/game/player-side.d.ts.map +1 -1
- package/dist/game/player-side.js +520 -338
- package/dist/game/player-side.js.map +1 -1
- package/dist/game/player-turn.d.ts +26 -7
- package/dist/game/player-turn.d.ts.map +1 -1
- package/dist/game/player-turn.js +180 -33
- package/dist/game/player-turn.js.map +1 -1
- package/dist/game/poly.d.ts +38 -0
- package/dist/game/poly.d.ts.map +1 -0
- package/dist/game/poly.js +82 -0
- package/dist/game/poly.js.map +1 -0
- package/dist/game/project-cast.d.ts +20 -3
- package/dist/game/project-cast.d.ts.map +1 -1
- package/dist/game/project-cast.js +49 -6
- package/dist/game/project-cast.js.map +1 -1
- package/dist/game/project-feat-vectors.d.ts +124 -0
- package/dist/game/project-feat-vectors.d.ts.map +1 -0
- package/dist/game/project-feat-vectors.fixtures.d.ts +13 -0
- package/dist/game/project-feat-vectors.fixtures.d.ts.map +1 -0
- package/dist/game/project-feat-vectors.fixtures.js +94 -0
- package/dist/game/project-feat-vectors.fixtures.js.map +1 -0
- package/dist/game/project-feat-vectors.js +229 -0
- package/dist/game/project-feat-vectors.js.map +1 -0
- package/dist/game/project-feat.d.ts +53 -1
- package/dist/game/project-feat.d.ts.map +1 -1
- package/dist/game/project-feat.js +374 -247
- package/dist/game/project-feat.js.map +1 -1
- package/dist/game/project-monster.d.ts +21 -8
- package/dist/game/project-monster.d.ts.map +1 -1
- package/dist/game/project-monster.js +45 -21
- package/dist/game/project-monster.js.map +1 -1
- package/dist/game/project-obj.d.ts +62 -0
- package/dist/game/project-obj.d.ts.map +1 -1
- package/dist/game/project-obj.js +72 -41
- package/dist/game/project-obj.js.map +1 -1
- package/dist/game/project-player.d.ts +8 -0
- package/dist/game/project-player.d.ts.map +1 -1
- package/dist/game/project-player.js.map +1 -1
- package/dist/game/projection-handlers.d.ts +81 -0
- package/dist/game/projection-handlers.d.ts.map +1 -0
- package/dist/game/projection-handlers.js +93 -0
- package/dist/game/projection-handlers.js.map +1 -0
- package/dist/game/quest.d.ts +23 -0
- package/dist/game/quest.d.ts.map +1 -1
- package/dist/game/quest.js +42 -0
- package/dist/game/quest.js.map +1 -1
- package/dist/game/ranged-cmd.d.ts +13 -2
- package/dist/game/ranged-cmd.d.ts.map +1 -1
- package/dist/game/ranged-cmd.js +32 -15
- package/dist/game/ranged-cmd.js.map +1 -1
- package/dist/game/repeat.d.ts +78 -0
- package/dist/game/repeat.d.ts.map +1 -0
- package/dist/game/repeat.js +88 -0
- package/dist/game/repeat.js.map +1 -0
- package/dist/game/shape-inspect.d.ts +74 -0
- package/dist/game/shape-inspect.d.ts.map +1 -0
- package/dist/game/shape-inspect.js +114 -0
- package/dist/game/shape-inspect.js.map +1 -0
- package/dist/game/spell-cmd.d.ts +15 -4
- package/dist/game/spell-cmd.d.ts.map +1 -1
- package/dist/game/spell-cmd.js +35 -6
- package/dist/game/spell-cmd.js.map +1 -1
- package/dist/game/spoil.d.ts.map +1 -1
- package/dist/game/spoil.js +89 -40
- package/dist/game/spoil.js.map +1 -1
- package/dist/game/steal.d.ts +3 -3
- package/dist/game/steal.d.ts.map +1 -1
- package/dist/game/steal.js +9 -4
- package/dist/game/steal.js.map +1 -1
- package/dist/game/target-loop.d.ts +10 -4
- package/dist/game/target-loop.d.ts.map +1 -1
- package/dist/game/target-loop.js +14 -8
- package/dist/game/target-loop.js.map +1 -1
- package/dist/game/target.d.ts +4 -4
- package/dist/game/target.d.ts.map +1 -1
- package/dist/game/target.js +19 -8
- package/dist/game/target.js.map +1 -1
- package/dist/game/ui-entry.d.ts +63 -4
- package/dist/game/ui-entry.d.ts.map +1 -1
- package/dist/game/ui-entry.js +151 -23
- package/dist/game/ui-entry.js.map +1 -1
- package/dist/game/wizard.d.ts +23 -5
- package/dist/game/wizard.d.ts.map +1 -1
- package/dist/game/wizard.js +93 -11
- package/dist/game/wizard.js.map +1 -1
- package/dist/game/world.d.ts.map +1 -1
- package/dist/game/world.js +6 -0
- package/dist/game/world.js.map +1 -1
- package/dist/gen/cave.d.ts +49 -8
- package/dist/gen/cave.d.ts.map +1 -1
- package/dist/gen/cave.js +200 -28
- package/dist/gen/cave.js.map +1 -1
- package/dist/gen/generate.d.ts +54 -9
- package/dist/gen/generate.d.ts.map +1 -1
- package/dist/gen/generate.js +55 -8
- package/dist/gen/generate.js.map +1 -1
- package/dist/gen/glyph-vectors.d.ts +109 -0
- package/dist/gen/glyph-vectors.d.ts.map +1 -0
- package/dist/gen/glyph-vectors.fixtures.d.ts +18 -0
- package/dist/gen/glyph-vectors.fixtures.d.ts.map +1 -0
- package/dist/gen/glyph-vectors.fixtures.js +94 -0
- package/dist/gen/glyph-vectors.fixtures.js.map +1 -0
- package/dist/gen/glyph-vectors.js +218 -0
- package/dist/gen/glyph-vectors.js.map +1 -0
- package/dist/gen/glyph.d.ts +104 -0
- package/dist/gen/glyph.d.ts.map +1 -0
- package/dist/gen/glyph.js +72 -0
- package/dist/gen/glyph.js.map +1 -0
- package/dist/gen/room.d.ts +26 -2
- package/dist/gen/room.d.ts.map +1 -1
- package/dist/gen/room.js +414 -264
- package/dist/gen/room.js.map +1 -1
- package/dist/gen/util.d.ts +11 -2
- package/dist/gen/util.d.ts.map +1 -1
- package/dist/gen/util.js +31 -9
- package/dist/gen/util.js.map +1 -1
- package/dist/i18n/i18n.d.ts +207 -0
- package/dist/i18n/i18n.d.ts.map +1 -0
- package/dist/i18n/i18n.js +405 -0
- package/dist/i18n/i18n.js.map +1 -0
- package/dist/i18n/text.d.ts +62 -0
- package/dist/i18n/text.d.ts.map +1 -0
- package/dist/i18n/text.js +120 -0
- package/dist/i18n/text.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -1
- package/dist/mod/extension.d.ts +115 -0
- package/dist/mod/extension.d.ts.map +1 -0
- package/dist/mod/extension.js +85 -0
- package/dist/mod/extension.js.map +1 -0
- package/dist/mod/hooks.d.ts +27 -1
- package/dist/mod/hooks.d.ts.map +1 -1
- package/dist/mod/hooks.js +23 -0
- package/dist/mod/hooks.js.map +1 -1
- package/dist/mod/ids.d.ts +10 -0
- package/dist/mod/ids.d.ts.map +1 -1
- package/dist/mod/ids.js +90 -21
- package/dist/mod/ids.js.map +1 -1
- package/dist/mod/record-keys.d.ts +43 -0
- package/dist/mod/record-keys.d.ts.map +1 -0
- package/dist/mod/record-keys.js +100 -0
- package/dist/mod/record-keys.js.map +1 -0
- package/dist/mod/registry-host.d.ts +472 -0
- package/dist/mod/registry-host.d.ts.map +1 -1
- package/dist/mod/registry-host.js +313 -0
- package/dist/mod/registry-host.js.map +1 -1
- package/dist/mod/save-blocks.d.ts +1 -1
- package/dist/mon/bind.d.ts.map +1 -1
- package/dist/mon/bind.js +6 -3
- package/dist/mon/bind.js.map +1 -1
- package/dist/mon/knowledge-groups.d.ts +0 -6
- package/dist/mon/knowledge-groups.d.ts.map +1 -1
- package/dist/mon/knowledge-groups.js +12 -8
- package/dist/mon/knowledge-groups.js.map +1 -1
- package/dist/mon/lore-describe.d.ts +46 -10
- package/dist/mon/lore-describe.d.ts.map +1 -1
- package/dist/mon/lore-describe.js +74 -22
- package/dist/mon/lore-describe.js.map +1 -1
- package/dist/mon/lore-file.d.ts +126 -0
- package/dist/mon/lore-file.d.ts.map +1 -0
- package/dist/mon/lore-file.js +291 -0
- package/dist/mon/lore-file.js.map +1 -0
- package/dist/mon/lore.d.ts +9 -3
- package/dist/mon/lore.d.ts.map +1 -1
- package/dist/mon/lore.js +9 -3
- package/dist/mon/lore.js.map +1 -1
- package/dist/mon/make.d.ts +4 -2
- package/dist/mon/make.d.ts.map +1 -1
- package/dist/mon/make.js +4 -2
- package/dist/mon/make.js.map +1 -1
- package/dist/mon/monster.d.ts +1 -1
- package/dist/mon/monster.js +1 -1
- package/dist/mon/predicate.d.ts +14 -9
- package/dist/mon/predicate.d.ts.map +1 -1
- package/dist/mon/predicate.js +14 -9
- package/dist/mon/predicate.js.map +1 -1
- package/dist/mon/project-mon.d.ts +16 -3
- package/dist/mon/project-mon.d.ts.map +1 -1
- package/dist/mon/project-mon.js +14 -5
- package/dist/mon/project-mon.js.map +1 -1
- package/dist/mon/steal.d.ts +31 -4
- package/dist/mon/steal.d.ts.map +1 -1
- package/dist/mon/steal.js +20 -7
- package/dist/mon/steal.js.map +1 -1
- package/dist/mon/take-hit.d.ts +8 -3
- package/dist/mon/take-hit.d.ts.map +1 -1
- package/dist/mon/take-hit.js +8 -3
- package/dist/mon/take-hit.js.map +1 -1
- package/dist/mon/timed.d.ts +15 -9
- package/dist/mon/timed.d.ts.map +1 -1
- package/dist/mon/timed.js +13 -8
- package/dist/mon/timed.js.map +1 -1
- package/dist/mon/types.d.ts +11 -4
- package/dist/mon/types.d.ts.map +1 -1
- package/dist/mon/types.js.map +1 -1
- package/dist/msg.d.ts +40 -1
- package/dist/msg.d.ts.map +1 -1
- package/dist/msg.js +42 -1
- package/dist/msg.js.map +1 -1
- package/dist/obj/artifact-fake.d.ts +46 -14
- package/dist/obj/artifact-fake.d.ts.map +1 -1
- package/dist/obj/artifact-fake.js +46 -17
- package/dist/obj/artifact-fake.js.map +1 -1
- package/dist/obj/bind.d.ts +23 -0
- package/dist/obj/bind.d.ts.map +1 -1
- package/dist/obj/bind.js +49 -9
- package/dist/obj/bind.js.map +1 -1
- package/dist/obj/desc-vectors.d.ts +68 -0
- package/dist/obj/desc-vectors.d.ts.map +1 -0
- package/dist/obj/desc-vectors.fixtures.d.ts +12 -0
- package/dist/obj/desc-vectors.fixtures.d.ts.map +1 -0
- package/dist/obj/desc-vectors.fixtures.js +95 -0
- package/dist/obj/desc-vectors.fixtures.js.map +1 -0
- package/dist/obj/desc-vectors.js +86 -0
- package/dist/obj/desc-vectors.js.map +1 -0
- package/dist/obj/desc.d.ts +17 -2
- package/dist/obj/desc.d.ts.map +1 -1
- package/dist/obj/desc.js +129 -54
- package/dist/obj/desc.js.map +1 -1
- package/dist/obj/effects-info.d.ts.map +1 -1
- package/dist/obj/effects-info.js +87 -58
- package/dist/obj/effects-info.js.map +1 -1
- package/dist/obj/fake-object.d.ts +70 -0
- package/dist/obj/fake-object.d.ts.map +1 -0
- package/dist/obj/fake-object.js +104 -0
- package/dist/obj/fake-object.js.map +1 -0
- package/dist/obj/ignore.d.ts +55 -12
- package/dist/obj/ignore.d.ts.map +1 -1
- package/dist/obj/ignore.js +68 -31
- package/dist/obj/ignore.js.map +1 -1
- package/dist/obj/knowledge.d.ts +46 -3
- package/dist/obj/knowledge.d.ts.map +1 -1
- package/dist/obj/knowledge.js +169 -151
- package/dist/obj/knowledge.js.map +1 -1
- package/dist/obj/known-object.d.ts +68 -8
- package/dist/obj/known-object.d.ts.map +1 -1
- package/dist/obj/known-object.js +90 -10
- package/dist/obj/known-object.js.map +1 -1
- package/dist/obj/make.d.ts +15 -4
- package/dist/obj/make.d.ts.map +1 -1
- package/dist/obj/make.js +49 -27
- package/dist/obj/make.js.map +1 -1
- package/dist/obj/object-info.d.ts +10 -0
- package/dist/obj/object-info.d.ts.map +1 -1
- package/dist/obj/object-info.js +93 -7
- package/dist/obj/object-info.js.map +1 -1
- package/dist/obj/object.d.ts +42 -4
- package/dist/obj/object.d.ts.map +1 -1
- package/dist/obj/object.js +362 -147
- package/dist/obj/object.js.map +1 -1
- package/dist/obj/power.d.ts +23 -4
- package/dist/obj/power.d.ts.map +1 -1
- package/dist/obj/power.js +231 -65
- package/dist/obj/power.js.map +1 -1
- package/dist/obj/randart-build.d.ts +27 -22
- package/dist/obj/randart-build.d.ts.map +1 -1
- package/dist/obj/randart-build.js +435 -357
- package/dist/obj/randart-build.js.map +1 -1
- package/dist/obj/randart-data.d.ts +62 -24
- package/dist/obj/randart-data.d.ts.map +1 -1
- package/dist/obj/randart-data.js +333 -189
- package/dist/obj/randart-data.js.map +1 -1
- package/dist/obj/randart-file.d.ts +21 -0
- package/dist/obj/randart-file.d.ts.map +1 -0
- package/dist/obj/randart-file.js +119 -0
- package/dist/obj/randart-file.js.map +1 -0
- package/dist/obj/randart-log.d.ts +63 -0
- package/dist/obj/randart-log.d.ts.map +1 -0
- package/dist/obj/randart-log.js +72 -0
- package/dist/obj/randart-log.js.map +1 -0
- package/dist/obj/randart-registry.d.ts +178 -0
- package/dist/obj/randart-registry.d.ts.map +1 -0
- package/dist/obj/randart-registry.js +140 -0
- package/dist/obj/randart-registry.js.map +1 -0
- package/dist/obj/randart-vectors.d.ts +97 -0
- package/dist/obj/randart-vectors.d.ts.map +1 -0
- package/dist/obj/randart-vectors.fixtures.d.ts +18 -0
- package/dist/obj/randart-vectors.fixtures.d.ts.map +1 -0
- package/dist/obj/randart-vectors.fixtures.js +50 -0
- package/dist/obj/randart-vectors.fixtures.js.map +1 -0
- package/dist/obj/randart-vectors.js +311 -0
- package/dist/obj/randart-vectors.js.map +1 -0
- package/dist/obj/randart.d.ts +53 -15
- package/dist/obj/randart.d.ts.map +1 -1
- package/dist/obj/randart.js +166 -44
- package/dist/obj/randart.js.map +1 -1
- package/dist/obj/rune-registry.d.ts +180 -0
- package/dist/obj/rune-registry.d.ts.map +1 -0
- package/dist/obj/rune-registry.js +161 -0
- package/dist/obj/rune-registry.js.map +1 -0
- package/dist/obj/rune-vectors.d.ts +99 -0
- package/dist/obj/rune-vectors.d.ts.map +1 -0
- package/dist/obj/rune-vectors.fixtures.d.ts +44 -0
- package/dist/obj/rune-vectors.fixtures.d.ts.map +1 -0
- package/dist/obj/rune-vectors.fixtures.js +125 -0
- package/dist/obj/rune-vectors.fixtures.js.map +1 -0
- package/dist/obj/rune-vectors.js +159 -0
- package/dist/obj/rune-vectors.js.map +1 -0
- package/dist/obj/tval-registry.d.ts +174 -0
- package/dist/obj/tval-registry.d.ts.map +1 -0
- package/dist/obj/tval-registry.js +151 -0
- package/dist/obj/tval-registry.js.map +1 -0
- package/dist/obj/tval-vectors.d.ts +85 -0
- package/dist/obj/tval-vectors.d.ts.map +1 -0
- package/dist/obj/tval-vectors.fixtures.d.ts +24 -0
- package/dist/obj/tval-vectors.fixtures.d.ts.map +1 -0
- package/dist/obj/tval-vectors.fixtures.js +41 -0
- package/dist/obj/tval-vectors.fixtures.js.map +1 -0
- package/dist/obj/tval-vectors.js +76 -0
- package/dist/obj/tval-vectors.js.map +1 -0
- package/dist/obj/types.d.ts +18 -7
- package/dist/obj/types.d.ts.map +1 -1
- package/dist/obj/types.js.map +1 -1
- package/dist/obj/value.d.ts.map +1 -1
- package/dist/obj/value.js +23 -20
- package/dist/obj/value.js.map +1 -1
- package/dist/parser.d.ts +116 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +205 -0
- package/dist/parser.js.map +1 -0
- package/dist/player/bind.d.ts.map +1 -1
- package/dist/player/bind.js +3 -2
- package/dist/player/bind.js.map +1 -1
- package/dist/player/birth.d.ts +2 -1
- package/dist/player/birth.d.ts.map +1 -1
- package/dist/player/birth.js +2 -1
- package/dist/player/birth.js.map +1 -1
- package/dist/player/calcs.d.ts +58 -23
- package/dist/player/calcs.d.ts.map +1 -1
- package/dist/player/calcs.js +93 -36
- package/dist/player/calcs.js.map +1 -1
- package/dist/player/death.d.ts +50 -0
- package/dist/player/death.d.ts.map +1 -0
- package/dist/player/death.js +46 -0
- package/dist/player/death.js.map +1 -0
- package/dist/player/options-file.d.ts +129 -0
- package/dist/player/options-file.d.ts.map +1 -0
- package/dist/player/options-file.js +309 -0
- package/dist/player/options-file.js.map +1 -0
- package/dist/player/options.d.ts +2 -1
- package/dist/player/options.d.ts.map +1 -1
- package/dist/player/options.js +2 -1
- package/dist/player/options.js.map +1 -1
- package/dist/player/player.d.ts +50 -3
- package/dist/player/player.d.ts.map +1 -1
- package/dist/player/player.js +10 -1
- package/dist/player/player.js.map +1 -1
- package/dist/player/shape-lore.d.ts +11 -7
- package/dist/player/shape-lore.d.ts.map +1 -1
- package/dist/player/shape-lore.js +24 -11
- package/dist/player/shape-lore.js.map +1 -1
- package/dist/player/timed.d.ts +5 -3
- package/dist/player/timed.d.ts.map +1 -1
- package/dist/player/timed.js +11 -2
- package/dist/player/timed.js.map +1 -1
- package/dist/player/types.d.ts +29 -4
- package/dist/player/types.d.ts.map +1 -1
- package/dist/player/types.js +24 -1
- package/dist/player/types.js.map +1 -1
- package/dist/session/boot.d.ts +26 -2
- package/dist/session/boot.d.ts.map +1 -1
- package/dist/session/boot.js +21 -2
- package/dist/session/boot.js.map +1 -1
- package/dist/session/game.d.ts +15 -0
- package/dist/session/game.d.ts.map +1 -1
- package/dist/session/game.js +616 -140
- package/dist/session/game.js.map +1 -1
- package/dist/session/save-migrate.d.ts.map +1 -1
- package/dist/session/save-migrate.js +76 -1
- package/dist/session/save-migrate.js.map +1 -1
- package/dist/session/save.d.ts +75 -12
- package/dist/session/save.d.ts.map +1 -1
- package/dist/session/save.js +177 -18
- package/dist/session/save.js.map +1 -1
- package/dist/store/bind.d.ts +1 -1
- package/dist/store/bind.d.ts.map +1 -1
- package/dist/store/bind.js +4 -3
- package/dist/store/bind.js.map +1 -1
- package/dist/store/mass-produce-vectors.d.ts +40 -0
- package/dist/store/mass-produce-vectors.d.ts.map +1 -0
- package/dist/store/mass-produce-vectors.fixtures.d.ts +13 -0
- package/dist/store/mass-produce-vectors.fixtures.d.ts.map +1 -0
- package/dist/store/mass-produce-vectors.fixtures.js +52 -0
- package/dist/store/mass-produce-vectors.fixtures.js.map +1 -0
- package/dist/store/mass-produce-vectors.js +44 -0
- package/dist/store/mass-produce-vectors.js.map +1 -0
- package/dist/store/store.d.ts +104 -7
- package/dist/store/store.d.ts.map +1 -1
- package/dist/store/store.js +199 -77
- package/dist/store/store.js.map +1 -1
- package/dist/store/transact.d.ts +14 -5
- package/dist/store/transact.d.ts.map +1 -1
- package/dist/store/transact.js +17 -16
- package/dist/store/transact.js.map +1 -1
- package/dist/store/types.d.ts +3 -2
- package/dist/store/types.d.ts.map +1 -1
- package/dist/store/types.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/visuals/index.d.ts +1 -0
- package/dist/visuals/index.d.ts.map +1 -1
- package/dist/visuals/index.js +1 -0
- package/dist/visuals/index.js.map +1 -1
- package/dist/visuals/map-text.d.ts +8 -0
- package/dist/visuals/map-text.d.ts.map +1 -1
- package/dist/visuals/map-text.js +1 -1
- package/dist/visuals/map-text.js.map +1 -1
- package/dist/visuals/object-glyph.d.ts +56 -0
- package/dist/visuals/object-glyph.d.ts.map +1 -0
- package/dist/visuals/object-glyph.js +52 -0
- package/dist/visuals/object-glyph.js.map +1 -0
- package/dist/visuals/prefs.d.ts +14 -22
- package/dist/visuals/prefs.d.ts.map +1 -1
- package/dist/visuals/prefs.js +4 -23
- package/dist/visuals/prefs.js.map +1 -1
- package/dist/visuals/tile-prefs.d.ts +26 -0
- package/dist/visuals/tile-prefs.d.ts.map +1 -1
- package/dist/visuals/tile-prefs.js +28 -0
- package/dist/visuals/tile-prefs.js.map +1 -1
- package/dist/world/feature.d.ts +2 -1
- package/dist/world/feature.d.ts.map +1 -1
- package/dist/world/feature.js +2 -0
- package/dist/world/feature.js.map +1 -1
- package/dist/world/project.d.ts +10 -2
- package/dist/world/project.d.ts.map +1 -1
- package/dist/world/project.js +18 -6
- package/dist/world/project.js.map +1 -1
- package/dist/world/projection.d.ts +37 -3
- package/dist/world/projection.d.ts.map +1 -1
- package/dist/world/projection.js +69 -7
- package/dist/world/projection.js.map +1 -1
- package/dist/world/trap.d.ts +2 -1
- package/dist/world/trap.d.ts.map +1 -1
- package/dist/world/trap.js +2 -1
- package/dist/world/trap.js.map +1 -1
- package/dist/world/view.d.ts +1 -1
- package/dist/world/view.d.ts.map +1 -1
- package/dist/world/view.js +11 -3
- package/dist/world/view.js.map +1 -1
- package/package.json +1 -1
- package/src/agent/perceive.ts +2 -3
- package/src/combat/blow-vectors.fixtures.ts +99 -0
- package/src/combat/blow-vectors.json +482 -0
- package/src/combat/blow-vectors.ts +280 -0
- package/src/combat/brand-slay.ts +42 -11
- package/src/combat/index.ts +1 -1
- package/src/combat/melee.ts +37 -19
- package/src/combat/mon-melee.ts +611 -364
- package/src/combat/ranged.ts +43 -26
- package/src/constants.ts +15 -0
- package/src/datafile.ts +148 -0
- package/src/effects/effect-info-registry.ts +313 -0
- package/src/effects/effect-info-vectors.fixtures.ts +61 -0
- package/src/effects/effect-info-vectors.json +11532 -0
- package/src/effects/effect-info-vectors.ts +376 -0
- package/src/effects/effect-info.ts +1005 -859
- package/src/effects/effect.ts +96 -62
- package/src/effects/handlers.ts +5 -2
- package/src/effects/interpreter.ts +14 -0
- package/src/game/cave-cmd.ts +54 -11
- package/src/game/cave-square.ts +80 -0
- package/src/game/char-sheet.ts +59 -16
- package/src/game/chest.ts +25 -8
- package/src/game/context.ts +293 -27
- package/src/game/describe.ts +34 -4
- package/src/game/display.ts +215 -19
- package/src/game/dump-level.ts +3 -2
- package/src/game/effect-attack.ts +41 -28
- package/src/game/effect-detect.ts +45 -8
- package/src/game/effect-env.ts +8 -0
- package/src/game/effect-general.ts +110 -47
- package/src/game/effect-item.ts +1075 -999
- package/src/game/effect-melee.ts +51 -18
- package/src/game/effect-monster.ts +55 -9
- package/src/game/effect-teleport.ts +173 -38
- package/src/game/effect-terrain.ts +38 -22
- package/src/game/equip-cmp.ts +483 -480
- package/src/game/floor.ts +22 -4
- package/src/game/gear.ts +210 -21
- package/src/game/harness.ts +12 -1
- package/src/game/ignore-cmd.ts +96 -8
- package/src/game/known.ts +392 -73
- package/src/game/loop.ts +52 -27
- package/src/game/lore-color.ts +13 -1
- package/src/game/mon-cast.ts +31 -6
- package/src/game/mon-cmd.ts +95 -30
- package/src/game/mon-death.ts +14 -12
- package/src/game/mon-group.ts +9 -5
- package/src/game/mon-message.ts +363 -65
- package/src/game/mon-place.ts +15 -3
- package/src/game/mon-ranged.ts +14 -5
- package/src/game/mon-side.ts +16 -12
- package/src/game/monster-turn.ts +120 -87
- package/src/game/notice.ts +85 -0
- package/src/game/obj-cmd.ts +126 -37
- package/src/game/obj-list.ts +44 -26
- package/src/game/object-inspect.ts +13 -0
- package/src/game/pickup.ts +29 -5
- package/src/game/player-side-vectors.fixtures.ts +215 -0
- package/src/game/player-side-vectors.json +6914 -0
- package/src/game/player-side-vectors.ts +420 -0
- package/src/game/player-side.ts +622 -340
- package/src/game/player-turn.ts +228 -31
- package/src/game/poly.ts +107 -0
- package/src/game/project-cast.ts +63 -6
- package/src/game/project-feat-vectors.fixtures.ts +106 -0
- package/src/game/project-feat-vectors.json +6554 -0
- package/src/game/project-feat-vectors.ts +323 -0
- package/src/game/project-feat.ts +417 -248
- package/src/game/project-monster.ts +69 -30
- package/src/game/project-obj-vectors.json +1 -0
- package/src/game/project-obj.ts +115 -47
- package/src/game/project-player.ts +8 -0
- package/src/game/projection-handlers.ts +110 -0
- package/src/game/quest.ts +48 -0
- package/src/game/ranged-cmd.ts +45 -11
- package/src/game/repeat.ts +92 -0
- package/src/game/shape-inspect.ts +166 -0
- package/src/game/spell-cmd.ts +39 -6
- package/src/game/spoil.ts +92 -39
- package/src/game/steal.ts +9 -4
- package/src/game/target-loop.ts +14 -7
- package/src/game/target.ts +18 -7
- package/src/game/ui-entry.ts +172 -22
- package/src/game/wizard.ts +97 -10
- package/src/game/world.ts +6 -0
- package/src/gen/cave.ts +225 -26
- package/src/gen/generate.ts +62 -9
- package/src/gen/glyph-vectors.fixtures.ts +122 -0
- package/src/gen/glyph-vectors.json +5996 -0
- package/src/gen/glyph-vectors.ts +280 -0
- package/src/gen/glyph.ts +132 -0
- package/src/gen/room.ts +446 -265
- package/src/gen/util.ts +32 -9
- package/src/i18n/i18n.ts +492 -0
- package/src/i18n/text.ts +117 -0
- package/src/index.ts +307 -254
- package/src/mod/extension.ts +136 -0
- package/src/mod/hooks.ts +54 -1
- package/src/mod/ids.ts +92 -21
- package/src/mod/record-keys.ts +102 -0
- package/src/mod/registry-host.ts +1063 -234
- package/src/mon/bind.ts +14 -8
- package/src/mon/knowledge-groups.ts +12 -12
- package/src/mon/lore-describe.ts +93 -26
- package/src/mon/lore-file.ts +365 -0
- package/src/mon/lore.ts +9 -3
- package/src/mon/make.ts +4 -2
- package/src/mon/monster.ts +1 -1
- package/src/mon/predicate.ts +14 -9
- package/src/mon/project-mon.ts +23 -5
- package/src/mon/steal.ts +39 -7
- package/src/mon/take-hit.ts +8 -3
- package/src/mon/timed.ts +15 -9
- package/src/mon/types.ts +11 -4
- package/src/msg.ts +55 -1
- package/src/obj/artifact-fake.ts +47 -17
- package/src/obj/bind.ts +52 -9
- package/src/obj/desc-vectors.fixtures.ts +119 -0
- package/src/obj/desc-vectors.json +2360 -0
- package/src/obj/desc-vectors.ts +128 -0
- package/src/obj/desc.ts +159 -55
- package/src/obj/effects-info.ts +90 -59
- package/src/obj/fake-object.ts +135 -0
- package/src/obj/ignore.ts +95 -28
- package/src/obj/knowledge.ts +291 -139
- package/src/obj/known-object.ts +126 -11
- package/src/obj/make.ts +53 -29
- package/src/obj/object-info.ts +103 -6
- package/src/obj/object.ts +392 -151
- package/src/obj/power.ts +297 -59
- package/src/obj/randart-build.ts +1875 -1705
- package/src/obj/randart-data.ts +1547 -1344
- package/src/obj/randart-file.ts +130 -0
- package/src/obj/randart-log.ts +78 -0
- package/src/obj/randart-registry.ts +247 -0
- package/src/obj/randart-vectors.fixtures.ts +61 -0
- package/src/obj/randart-vectors.json +836 -0
- package/src/obj/randart-vectors.ts +369 -0
- package/src/obj/randart.ts +722 -552
- package/src/obj/rune-registry.ts +270 -0
- package/src/obj/rune-vectors.fixtures.ts +164 -0
- package/src/obj/rune-vectors.json +121 -0
- package/src/obj/rune-vectors.ts +229 -0
- package/src/obj/tval-kind-vectors.json +391 -0
- package/src/obj/tval-registry.ts +243 -0
- package/src/obj/tval-vectors.fixtures.ts +50 -0
- package/src/obj/tval-vectors.json +38 -0
- package/src/obj/tval-vectors.ts +126 -0
- package/src/obj/types.ts +18 -7
- package/src/obj/value.ts +26 -20
- package/src/parser.ts +214 -0
- package/src/player/bind.ts +5 -2
- package/src/player/birth.ts +2 -1
- package/src/player/calcs.ts +123 -42
- package/src/player/death.ts +78 -0
- package/src/player/options-file.ts +387 -0
- package/src/player/options.ts +2 -1
- package/src/player/player.ts +60 -4
- package/src/player/shape-lore.ts +33 -14
- package/src/player/timed.ts +14 -4
- package/src/player/types.ts +30 -4
- package/src/session/boot.ts +51 -1
- package/src/session/game.ts +720 -163
- package/src/session/save-migrate.ts +81 -1
- package/src/session/save.ts +264 -22
- package/src/store/bind.ts +4 -3
- package/src/store/mass-produce-vectors.fixtures.ts +64 -0
- package/src/store/mass-produce-vectors.json +1169 -0
- package/src/store/mass-produce-vectors.ts +67 -0
- package/src/store/store.ts +266 -63
- package/src/store/transact.ts +39 -16
- package/src/store/types.ts +3 -2
- package/src/version.ts +1 -1
- package/src/visuals/index.ts +1 -0
- package/src/visuals/map-text.ts +1 -1
- package/src/visuals/object-glyph.ts +76 -0
- package/src/visuals/prefs.ts +22 -32
- package/src/visuals/tile-prefs.ts +32 -0
- package/src/world/feature.ts +4 -1
- package/src/world/project.ts +19 -4
- package/src/world/projection.ts +79 -8
- package/src/world/trap.ts +25 -21
- package/src/world/view.ts +11 -1
package/src/obj/randart.ts
CHANGED
|
@@ -1,552 +1,722 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Random artifact generation: the top-level design loop and entry point,
|
|
3
|
-
* ported from reference/src/obj-randart.c (Angband 4.2.6) lines 2672-3219.
|
|
4
|
-
* This module ports copy_artifact (L2676), artifact_gen_name (L2713),
|
|
5
|
-
* design_artifact (L2751), create_artifact_set (L2954), artifact_set_data_new
|
|
6
|
-
* (via artifactSetDataNew in randart-data.ts) and do_randart (L3154). It drives
|
|
7
|
-
* the measurement half (collectArtifactData, artifactPower in randart-data.ts)
|
|
8
|
-
* and the building primitives (getBaseItem, artifactPrep, buildFreqTable,
|
|
9
|
-
* trySupercharge, addAbility, removeContradictory, makeBad in randart-build.ts).
|
|
10
|
-
*
|
|
11
|
-
* do_randart is pure with respect to its seed: the same seed always yields the
|
|
12
|
-
* same (Artifact|null)[] set. It measures the registry's standard artifact set
|
|
13
|
-
* to build the generation frequencies, then designs a fresh copy of every
|
|
14
|
-
* artifact into a new array, leaving ObjRegistry.artifacts untouched.
|
|
15
|
-
*
|
|
16
|
-
* Faithful notes / deferrals / approximations:
|
|
17
|
-
* - RNG mode: upstream do_randart sets Rand_quick = true and seeds Rand_value
|
|
18
|
-
* with randart_seed, i.e. it draws from the "quick" LCRNG, not the WELL
|
|
19
|
-
* stream. This port creates its Rng in quick mode to match the draw stream
|
|
20
|
-
* (new Rng(seed, { quick: true })).
|
|
21
|
-
* - artifact_gen_name / wordlist (FAITHFUL when the TOLKIEN corpus is supplied):
|
|
22
|
-
* upstream builds a Markov-chain name from the RANDNAME_TOLKIEN word list in
|
|
23
|
-
* the names datafile (randname.c randname_make + name_sections). randname_make
|
|
24
|
-
* and build_prob are ported faithfully in randname.ts, and the corpus ships in
|
|
25
|
-
* the content pack as names.json section 1 (loaded into
|
|
26
|
-
* CoreRegistries.nameSections at boot). doRandart now accepts that word list
|
|
27
|
-
* (tolkienWords); artifactGenName then calls randnameMake(RANDNAME_TOLKIEN,
|
|
28
|
-
* MIN_NAME_LEN, MAX_NAME_LEN) exactly like upstream artifact_gen_name
|
|
29
|
-
* (obj-randart.c L2713), so the name draws consume the same RNG values in the
|
|
30
|
-
* same order and the generated names match upstream. This is verified against
|
|
31
|
-
* an independent Python oracle in randart.test.ts.
|
|
32
|
-
*
|
|
33
|
-
* Game path: session/game.ts swapRandartSet() threads the corpus -
|
|
34
|
-
* doRandart(reg.objects, seed, reg.nameSections.get(RANDNAME_TOLKIEN))
|
|
35
|
-
* (game.ts:2511-2514) - so the in-game randart names draw faithfully too.
|
|
36
|
-
* randNameFallback (a local syllable table) is retained only as a defensive
|
|
37
|
-
* guard for callers that pass no corpus (it never runs on the wired paths).
|
|
38
|
-
* -
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* -
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* -
|
|
53
|
-
*
|
|
54
|
-
* (obj-randart.c
|
|
55
|
-
* the
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
} from "./
|
|
74
|
-
import
|
|
75
|
-
import {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
*/
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
dst.
|
|
128
|
-
dst.
|
|
129
|
-
dst.
|
|
130
|
-
dst.
|
|
131
|
-
dst.
|
|
132
|
-
dst.
|
|
133
|
-
dst.
|
|
134
|
-
dst.
|
|
135
|
-
dst.
|
|
136
|
-
dst.
|
|
137
|
-
dst.
|
|
138
|
-
dst.
|
|
139
|
-
dst.
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
dst.
|
|
143
|
-
dst.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
*/
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
*
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
*
|
|
267
|
-
*
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
*/
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
/*
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
/*
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
/*
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
*
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Random artifact generation: the top-level design loop and entry point,
|
|
3
|
+
* ported from reference/src/obj-randart.c (Angband 4.2.6) lines 2672-3219.
|
|
4
|
+
* This module ports copy_artifact (L2676), artifact_gen_name (L2713),
|
|
5
|
+
* design_artifact (L2751), create_artifact_set (L2954), artifact_set_data_new
|
|
6
|
+
* (via artifactSetDataNew in randart-data.ts) and do_randart (L3154). It drives
|
|
7
|
+
* the measurement half (collectArtifactData, artifactPower in randart-data.ts)
|
|
8
|
+
* and the building primitives (getBaseItem, artifactPrep, buildFreqTable,
|
|
9
|
+
* trySupercharge, addAbility, removeContradictory, makeBad in randart-build.ts).
|
|
10
|
+
*
|
|
11
|
+
* do_randart is pure with respect to its seed: the same seed always yields the
|
|
12
|
+
* same (Artifact|null)[] set. It measures the registry's standard artifact set
|
|
13
|
+
* to build the generation frequencies, then designs a fresh copy of every
|
|
14
|
+
* artifact into a new array, leaving ObjRegistry.artifacts untouched.
|
|
15
|
+
*
|
|
16
|
+
* Faithful notes / deferrals / approximations:
|
|
17
|
+
* - RNG mode: upstream do_randart sets Rand_quick = true and seeds Rand_value
|
|
18
|
+
* with randart_seed, i.e. it draws from the "quick" LCRNG, not the WELL
|
|
19
|
+
* stream. This port creates its Rng in quick mode to match the draw stream
|
|
20
|
+
* (new Rng(seed, { quick: true })).
|
|
21
|
+
* - artifact_gen_name / wordlist (FAITHFUL when the TOLKIEN corpus is supplied):
|
|
22
|
+
* upstream builds a Markov-chain name from the RANDNAME_TOLKIEN word list in
|
|
23
|
+
* the names datafile (randname.c randname_make + name_sections). randname_make
|
|
24
|
+
* and build_prob are ported faithfully in randname.ts, and the corpus ships in
|
|
25
|
+
* the content pack as names.json section 1 (loaded into
|
|
26
|
+
* CoreRegistries.nameSections at boot). doRandart now accepts that word list
|
|
27
|
+
* (tolkienWords); artifactGenName then calls randnameMake(RANDNAME_TOLKIEN,
|
|
28
|
+
* MIN_NAME_LEN, MAX_NAME_LEN) exactly like upstream artifact_gen_name
|
|
29
|
+
* (obj-randart.c L2713), so the name draws consume the same RNG values in the
|
|
30
|
+
* same order and the generated names match upstream. This is verified against
|
|
31
|
+
* an independent Python oracle in randart.test.ts.
|
|
32
|
+
*
|
|
33
|
+
* Game path: session/game.ts swapRandartSet() threads the corpus -
|
|
34
|
+
* doRandart(reg.objects, seed, reg.nameSections.get(RANDNAME_TOLKIEN))
|
|
35
|
+
* (game.ts:2511-2514) - so the in-game randart names draw faithfully too.
|
|
36
|
+
* randNameFallback (a local syllable table) is retained only as a defensive
|
|
37
|
+
* guard for callers that pass no corpus (it never runs on the wired paths).
|
|
38
|
+
* - randart.log (PORT_TODO 5.5): PORTED bar one line. do_randart opens and
|
|
39
|
+
* closes it through the host; the maintainer's disposition on 2026-08-04 was
|
|
40
|
+
* pursue parity, so the "it never affects an artifact field" argument the old
|
|
41
|
+
* note made here was never a reason to omit it. What is and is not written is
|
|
42
|
+
* MEASURED by obj/randart-log.census.test.ts rather than claimed in prose,
|
|
43
|
+
* including the one site the census's span filter cannot see. See
|
|
44
|
+
* randart-log.ts for the sink and the reason it is a module-level static.
|
|
45
|
+
* - randart.txt: PORTED. obj/randart-file.ts, gated by do_randart's create_file
|
|
46
|
+
* (obj-randart.c L3195-L3215), which is a required parameter here.
|
|
47
|
+
* - The second measurement pass upstream runs after generation
|
|
48
|
+
* (store_base_power/parse_frequencies on the finished set, L3181-L3186):
|
|
49
|
+
* PORTED. It exists only to populate the log's closing statistics, and the
|
|
50
|
+
* set it measures is a parameter here because this port does not overwrite
|
|
51
|
+
* the a_info global the way upstream does.
|
|
52
|
+
* - copy_artifact activation/alt_msg quirk (FAITHFUL): upstream copy_artifact
|
|
53
|
+
* memcpy's the whole struct and then explicitly nulls a_dst->activation and
|
|
54
|
+
* a_dst->alt_msg (obj-randart.c L2689-L2690). copyArtifact reproduces this:
|
|
55
|
+
* the destination always loses its activation (set null) and alt_msg (set "")
|
|
56
|
+
* even though every other field is copied. This means a rollback in the
|
|
57
|
+
* design loop can drop an activation that add_activation had added. Faithful.
|
|
58
|
+
* - design_artifact stale-kind quirk (FAITHFUL): upstream looks up `kind` once
|
|
59
|
+
* before the fixed-artifact skip loop and never refreshes it inside the loop
|
|
60
|
+
* (obj-randart.c L2754, L2778). The QUEST_ART test therefore keeps reading
|
|
61
|
+
* the initial artifact's kind while the name test tracks the advancing
|
|
62
|
+
* artifact. In the standard set the quest artifacts are last and contiguous,
|
|
63
|
+
* so this is unobservable, but it is reproduced exactly. Noted.
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
import { FileMode, FileType, HostDir, host } from "../host/io.js";
|
|
67
|
+
import type { HostIo } from "../host/io.js";
|
|
68
|
+
import { RANDART_TXT, writeRandartFile } from "./randart-file.js";
|
|
69
|
+
import { randartLog, randartLogf, setRandartLog } from "./randart-log.js";
|
|
70
|
+
import { KF, TV } from "../generated/index.js";
|
|
71
|
+
import { Rng } from "../rng.js";
|
|
72
|
+
import type { Constants } from "../constants.js";
|
|
73
|
+
import type { ObjRegistry } from "./bind.js";
|
|
74
|
+
import { tvalFindName } from "./bind.js";
|
|
75
|
+
import { buildProb, randnameMake, type NameProbs } from "./randname.js";
|
|
76
|
+
import {
|
|
77
|
+
addAbility,
|
|
78
|
+
getBaseItem,
|
|
79
|
+
artifactPrep,
|
|
80
|
+
buildFreqTable,
|
|
81
|
+
makeBad,
|
|
82
|
+
removeContradictory,
|
|
83
|
+
trySupercharge,
|
|
84
|
+
} from "./randart-build.js";
|
|
85
|
+
import type { ArtifactSetData } from "./randart-data.js";
|
|
86
|
+
import {
|
|
87
|
+
artifactPower,
|
|
88
|
+
collectArtifactData,
|
|
89
|
+
getBaseItemTval,
|
|
90
|
+
} from "./randart-data.js";
|
|
91
|
+
import type { Artifact } from "./types.js";
|
|
92
|
+
import { TV_MAX } from "./types.js";
|
|
93
|
+
|
|
94
|
+
/* Re-export makeBad so consumers can reach it from the top-level module. */
|
|
95
|
+
export { makeBad };
|
|
96
|
+
|
|
97
|
+
/* ------------------------------------------------------------------ */
|
|
98
|
+
/* Constants (obj-randart.h) */
|
|
99
|
+
/* ------------------------------------------------------------------ */
|
|
100
|
+
|
|
101
|
+
/** MAX_TRIES (obj-randart.h L28). */
|
|
102
|
+
const MAX_TRIES = 200;
|
|
103
|
+
|
|
104
|
+
/** MIN_NAME_LEN / MAX_NAME_LEN (obj-randart.h L31-L32). */
|
|
105
|
+
const MIN_NAME_LEN = 5;
|
|
106
|
+
const MAX_NAME_LEN = 9;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* RANDNAME_TOLKIEN (randname.h L26): the names.txt section index whose word list
|
|
110
|
+
* feeds artifact_gen_name (obj-randart.c L2717). Section 1 in names.json.
|
|
111
|
+
*/
|
|
112
|
+
export const RANDNAME_TOLKIEN = 1;
|
|
113
|
+
|
|
114
|
+
/* ------------------------------------------------------------------ */
|
|
115
|
+
/* copy_artifact (obj-randart.c L2676) */
|
|
116
|
+
/* ------------------------------------------------------------------ */
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* copy_artifact (obj-randart.c L2676): copy every artifact field from src to
|
|
120
|
+
* dst in place. Faithful to the upstream memcpy-then-null: the destination's
|
|
121
|
+
* activation is always cleared to null and its alt_msg to "" (obj-randart.c
|
|
122
|
+
* L2689-L2690), even though all other fields (name, text, combat, flags,
|
|
123
|
+
* modifiers, element info, deep copies of slays/brands/curses, time) are
|
|
124
|
+
* copied. dst keeps its own identity so array references stay valid.
|
|
125
|
+
*/
|
|
126
|
+
export function copyArtifact(src: Artifact, dst: Artifact): void {
|
|
127
|
+
dst.name = src.name;
|
|
128
|
+
dst.text = src.text;
|
|
129
|
+
dst.aidx = src.aidx;
|
|
130
|
+
dst.tval = src.tval;
|
|
131
|
+
dst.sval = src.sval;
|
|
132
|
+
dst.toH = src.toH;
|
|
133
|
+
dst.toD = src.toD;
|
|
134
|
+
dst.toA = src.toA;
|
|
135
|
+
dst.ac = src.ac;
|
|
136
|
+
dst.dd = src.dd;
|
|
137
|
+
dst.ds = src.ds;
|
|
138
|
+
dst.weight = src.weight;
|
|
139
|
+
dst.cost = src.cost;
|
|
140
|
+
dst.flags = src.flags.clone();
|
|
141
|
+
dst.modifiers = src.modifiers.slice();
|
|
142
|
+
dst.elInfo = src.elInfo.map((e) => ({ resLevel: e.resLevel, flags: e.flags }));
|
|
143
|
+
dst.brands = src.brands ? src.brands.slice() : null;
|
|
144
|
+
dst.slays = src.slays ? src.slays.slice() : null;
|
|
145
|
+
dst.curses = src.curses ? src.curses.slice() : null;
|
|
146
|
+
dst.level = src.level;
|
|
147
|
+
dst.allocProb = src.allocProb;
|
|
148
|
+
dst.allocMin = src.allocMin;
|
|
149
|
+
dst.allocMax = src.allocMax;
|
|
150
|
+
dst.time = { ...src.time };
|
|
151
|
+
|
|
152
|
+
/* Upstream nulls these after the memcpy (obj-randart.c L2689-L2690). */
|
|
153
|
+
dst.activation = null;
|
|
154
|
+
dst.altMsg = "";
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* A full deep copy of an artifact, preserving activation and alt_msg. Used to
|
|
159
|
+
* snapshot the registry's standard artifacts into a mutable working set so
|
|
160
|
+
* do_randart never mutates ObjRegistry.artifacts. This is NOT copy_artifact
|
|
161
|
+
* (which deliberately drops activation/alt_msg); it is the honest clone the
|
|
162
|
+
* working array needs.
|
|
163
|
+
*
|
|
164
|
+
* EXPORTED so a test harness can start from the same object shape production
|
|
165
|
+
* mutates - a hand-built Artifact would be the harness asserting what the
|
|
166
|
+
* struct looks like rather than measuring it.
|
|
167
|
+
*/
|
|
168
|
+
export function cloneArtifact(src: Artifact): Artifact {
|
|
169
|
+
return {
|
|
170
|
+
name: src.name,
|
|
171
|
+
text: src.text,
|
|
172
|
+
aidx: src.aidx,
|
|
173
|
+
tval: src.tval,
|
|
174
|
+
sval: src.sval,
|
|
175
|
+
toH: src.toH,
|
|
176
|
+
toD: src.toD,
|
|
177
|
+
toA: src.toA,
|
|
178
|
+
ac: src.ac,
|
|
179
|
+
dd: src.dd,
|
|
180
|
+
ds: src.ds,
|
|
181
|
+
weight: src.weight,
|
|
182
|
+
cost: src.cost,
|
|
183
|
+
flags: src.flags.clone(),
|
|
184
|
+
modifiers: src.modifiers.slice(),
|
|
185
|
+
elInfo: src.elInfo.map((e) => ({ resLevel: e.resLevel, flags: e.flags })),
|
|
186
|
+
brands: src.brands ? src.brands.slice() : null,
|
|
187
|
+
slays: src.slays ? src.slays.slice() : null,
|
|
188
|
+
curses: src.curses ? src.curses.slice() : null,
|
|
189
|
+
level: src.level,
|
|
190
|
+
allocProb: src.allocProb,
|
|
191
|
+
allocMin: src.allocMin,
|
|
192
|
+
allocMax: src.allocMax,
|
|
193
|
+
activation: src.activation,
|
|
194
|
+
altMsg: src.altMsg,
|
|
195
|
+
time: { ...src.time },
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* ------------------------------------------------------------------ */
|
|
200
|
+
/* artifact_gen_name (obj-randart.c L2713) */
|
|
201
|
+
/* ------------------------------------------------------------------ */
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* my_strcap (z-util.c L529): capitalize only the first character, leaving the
|
|
205
|
+
* rest untouched. randnameMake returns an all-lowercase word, so this matches
|
|
206
|
+
* upstream exactly.
|
|
207
|
+
*/
|
|
208
|
+
function myStrcap(word: string): string {
|
|
209
|
+
if (word.length === 0) return word;
|
|
210
|
+
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Tolkien-flavoured syllable fragments used ONLY as the seam fallback when no
|
|
215
|
+
* RANDNAME_TOLKIEN corpus is supplied to doRandart (see module SEAM note). This
|
|
216
|
+
* is NOT the upstream algorithm; it keeps the game path deterministic and
|
|
217
|
+
* crash-free until game.ts threads the real corpus.
|
|
218
|
+
*/
|
|
219
|
+
const NAME_SYLLABLES: readonly string[] = [
|
|
220
|
+
"an", "ar", "el", "en", "or", "ith", "gal", "dor", "mir", "las",
|
|
221
|
+
"thal", "rond", "wen", "dil", "beth", "ath", "ien", "ael", "uin", "gorn",
|
|
222
|
+
"iel", "und", "ost", "loth", "mor", "fin", "hir", "eth", "ond", "aur",
|
|
223
|
+
];
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Seam fallback (non-faithful): assemble a plausible name from the syllable
|
|
227
|
+
* table. Fragments are drawn until the length reaches MIN_NAME_LEN, then clamped
|
|
228
|
+
* to MAX_NAME_LEN. Deterministic and bounded; used only when doRandart has no
|
|
229
|
+
* corpus.
|
|
230
|
+
*/
|
|
231
|
+
function randNameFallback(rng: Rng): string {
|
|
232
|
+
let word = "";
|
|
233
|
+
while (word.length < MIN_NAME_LEN) {
|
|
234
|
+
word += NAME_SYLLABLES[rng.randint0(NAME_SYLLABLES.length)]!;
|
|
235
|
+
}
|
|
236
|
+
if (word.length > MAX_NAME_LEN) word = word.slice(0, MAX_NAME_LEN);
|
|
237
|
+
return word;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* artifact_gen_name (obj-randart.c L2713): generate a random artifact name.
|
|
242
|
+
* Faithful to upstream: draw a Markov word from the RANDNAME_TOLKIEN corpus via
|
|
243
|
+
* randnameMake(MIN_NAME_LEN, MAX_NAME_LEN) (obj-randart.c L2717), my_strcap the
|
|
244
|
+
* first letter (L2719), then one_in_(3) selects the "'Name'" form over
|
|
245
|
+
* "of Name" (L2721-L2724). The upstream `struct artifact *a` argument is unused.
|
|
246
|
+
*
|
|
247
|
+
* `probs` is the precomputed transition table (build_prob over the corpus). When
|
|
248
|
+
* null (seam fallback, no corpus), the syllable table is used instead - this is
|
|
249
|
+
* NOT upstream-faithful and consumes a different number of RNG draws.
|
|
250
|
+
*/
|
|
251
|
+
export function artifactGenName(rng: Rng, probs: NameProbs | null): string {
|
|
252
|
+
const word =
|
|
253
|
+
probs !== null
|
|
254
|
+
? randnameMake(rng, MIN_NAME_LEN, MAX_NAME_LEN, probs)
|
|
255
|
+
: randNameFallback(rng);
|
|
256
|
+
const capped = myStrcap(word);
|
|
257
|
+
if (rng.oneIn(3)) return `'${capped}'`;
|
|
258
|
+
return `of ${capped}`;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/* ------------------------------------------------------------------ */
|
|
262
|
+
/* describe_artifact (obj-randart.c L2731) */
|
|
263
|
+
/* ------------------------------------------------------------------ */
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* describe_artifact (obj-randart.c L2731): give the artifact a boring
|
|
267
|
+
* "Random <type> of power <n>" description. Consumes no RNG.
|
|
268
|
+
*/
|
|
269
|
+
function describeArtifact(art: Artifact, power: number): void {
|
|
270
|
+
art.text = `Random ${tvalFindName(art.tval)} of power ${power}`;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/* ------------------------------------------------------------------ */
|
|
274
|
+
/* design_artifact (obj-randart.c L2751) */
|
|
275
|
+
/* ------------------------------------------------------------------ */
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* design_artifact (obj-randart.c L2751): design a random artifact into
|
|
279
|
+
* arts[aidx], possibly skipping forward past fixed artifacts. Returns the
|
|
280
|
+
* (possibly advanced) working index, matching upstream's *aidx after return;
|
|
281
|
+
* the caller then increments it. `tv` is TV_NULL to pick a tval from the
|
|
282
|
+
* learned frequencies, or a specific tval to force.
|
|
283
|
+
*
|
|
284
|
+
* The artifact is assigned a target power from the range of powers for its
|
|
285
|
+
* tval, given a suitable base item, optionally supercharged, then has abilities
|
|
286
|
+
* (or, for a cursed artifact, curses) added until its power lands between 19/20
|
|
287
|
+
* and 23/20 of the target.
|
|
288
|
+
*/
|
|
289
|
+
export function designArtifact(
|
|
290
|
+
reg: ObjRegistry,
|
|
291
|
+
constants: Constants,
|
|
292
|
+
arts: (Artifact | null)[],
|
|
293
|
+
data: ArtifactSetData,
|
|
294
|
+
tv: number,
|
|
295
|
+
aidx: number,
|
|
296
|
+
rng: Rng,
|
|
297
|
+
nameProbs: NameProbs | null,
|
|
298
|
+
): number {
|
|
299
|
+
/* Defensive guard (upstream relies on aidx staying in range). */
|
|
300
|
+
if (aidx < 1 || aidx >= arts.length) return aidx;
|
|
301
|
+
|
|
302
|
+
let art = arts[aidx] as Artifact;
|
|
303
|
+
/* Upstream captures kind once and never refreshes it in the skip loop. */
|
|
304
|
+
let kind = reg.lookupKind(art.tval, art.sval);
|
|
305
|
+
const kindAtEntry = kind;
|
|
306
|
+
let artLevel = art.level;
|
|
307
|
+
|
|
308
|
+
/* Set tval if necessary. */
|
|
309
|
+
let tval = tv === TV.NULL ? getBaseItemTval(data, rng) : tv;
|
|
310
|
+
|
|
311
|
+
/* Choose a power for the artifact. */
|
|
312
|
+
let power = rng.randSample(
|
|
313
|
+
data.avgTvPower[tval]!,
|
|
314
|
+
data.maxTvPower[tval]!,
|
|
315
|
+
data.minTvPower[tval]!,
|
|
316
|
+
20,
|
|
317
|
+
20,
|
|
318
|
+
);
|
|
319
|
+
|
|
320
|
+
/* Choose a name. */
|
|
321
|
+
const newName = artifactGenName(rng, nameProbs);
|
|
322
|
+
|
|
323
|
+
/* Skip fixed artifacts (stale-kind quirk preserved: kindAtEntry). */
|
|
324
|
+
while (
|
|
325
|
+
art.name.includes("The One Ring") ||
|
|
326
|
+
(kindAtEntry !== null && kindAtEntry.kindFlags.has(KF.QUEST_ART))
|
|
327
|
+
) {
|
|
328
|
+
aidx++;
|
|
329
|
+
if (aidx >= arts.length) return aidx;
|
|
330
|
+
art = arts[aidx] as Artifact;
|
|
331
|
+
artLevel = art.level;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/* Apply the new name. */
|
|
335
|
+
art.name = newName;
|
|
336
|
+
|
|
337
|
+
randartLog(">>>>>>>>>>>>>>>>>>>>>>>>>> CREATING NEW ARTIFACT\n");
|
|
338
|
+
randartLogf(
|
|
339
|
+
() => `Artifact ${String(aidx)}: power = ${String(power)}\n`,
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
/* Flip the sign on power if it's negative (unlikely) and damage. */
|
|
343
|
+
let hurtMe = false;
|
|
344
|
+
if (power < 0) {
|
|
345
|
+
hurtMe = true;
|
|
346
|
+
power = -power;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/* Structure to hold the old artifact for rollbacks. */
|
|
350
|
+
const aOld = cloneArtifact(art);
|
|
351
|
+
|
|
352
|
+
let tries: number;
|
|
353
|
+
let ap = 0;
|
|
354
|
+
|
|
355
|
+
/* Choose a base item not too powerful, so we'll have to add to it. */
|
|
356
|
+
for (tries = 0; tries < MAX_TRIES; tries++) {
|
|
357
|
+
if (tval === TV.NULL) tval = getBaseItemTval(data, rng);
|
|
358
|
+
kind = getBaseItem(reg, tval, rng);
|
|
359
|
+
artifactPrep(reg, art, kind, data, rng);
|
|
360
|
+
|
|
361
|
+
/* Get the kind again in case it's changed. */
|
|
362
|
+
kind = reg.lookupKind(art.tval, art.sval);
|
|
363
|
+
|
|
364
|
+
const basePower = artifactPower(reg, constants, art, "for base item power", rng);
|
|
365
|
+
randartLogf(() => `Base item power ${String(basePower)}\n`);
|
|
366
|
+
|
|
367
|
+
/* New base item power too close to target artifact power. */
|
|
368
|
+
if (basePower > Math.trunc((power * 6) / 10) + 1 && power - basePower < 20) {
|
|
369
|
+
randartLog("Power too high!\n");
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/* Acceptable. */
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/* Failed to get a good base item. */
|
|
378
|
+
if (tries >= MAX_TRIES) {
|
|
379
|
+
randartLog(
|
|
380
|
+
"Warning! Couldn't get appropriate power level on base item.\n",
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/* Generate the cumulative frequency table for this base item type. */
|
|
385
|
+
const artFreq = buildFreqTable(art, data);
|
|
386
|
+
|
|
387
|
+
/* Copy artifact info temporarily. */
|
|
388
|
+
copyArtifact(art, aOld);
|
|
389
|
+
|
|
390
|
+
/* Give this artifact a shot at being supercharged. */
|
|
391
|
+
trySupercharge(reg, art, power, data, rng);
|
|
392
|
+
ap = artifactPower(reg, constants, art, "result of supercharge", rng);
|
|
393
|
+
if (ap > Math.trunc((power * 23) / 20) + 1) {
|
|
394
|
+
/* Too powerful -- put it back. */
|
|
395
|
+
copyArtifact(aOld, art);
|
|
396
|
+
randartLog("--- Supercharge is too powerful! Rolling back.\n");
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/* Give this artifact a chance to be cursed - note it retains its power. */
|
|
400
|
+
if (rng.oneIn(Math.trunc(arts.length / Math.max(2, data.negPowerTotal)))) {
|
|
401
|
+
hurtMe = true;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/* Do the actual artifact design. */
|
|
405
|
+
for (tries = 0; tries < MAX_TRIES; tries++) {
|
|
406
|
+
/* Copy artifact info temporarily. */
|
|
407
|
+
copyArtifact(art, aOld);
|
|
408
|
+
|
|
409
|
+
/* Add an ability. */
|
|
410
|
+
addAbility(reg, art, power, artFreq, data, rng);
|
|
411
|
+
removeContradictory(reg, art, data.timedFoil, data.activationSummarize);
|
|
412
|
+
|
|
413
|
+
/* Check the power, handle negative power. */
|
|
414
|
+
ap = artifactPower(reg, constants, art, "artifact attempt", rng);
|
|
415
|
+
if (ap < 0) {
|
|
416
|
+
ap = -ap;
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/* Curse the designated artifacts. */
|
|
421
|
+
if (hurtMe) {
|
|
422
|
+
makeBad(reg, art, artLevel, rng, data.timedFoil);
|
|
423
|
+
if (rng.oneIn(3)) {
|
|
424
|
+
hurtMe = false;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/* Check power. */
|
|
429
|
+
if (ap > Math.trunc((power * 23) / 20) + 1) {
|
|
430
|
+
/* Too powerful -- put it back. */
|
|
431
|
+
copyArtifact(aOld, art);
|
|
432
|
+
randartLog("--- Too powerful! Rolling back.\n");
|
|
433
|
+
continue;
|
|
434
|
+
} else if (ap >= Math.trunc((power * 19) / 20)) {
|
|
435
|
+
/* Just right. */
|
|
436
|
+
break;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/* Couldn't generate an artifact with the number of permitted iterations. */
|
|
441
|
+
if (tries >= MAX_TRIES) {
|
|
442
|
+
randartLog(
|
|
443
|
+
"Warning! Couldn't get appropriate power level on artifact.\n",
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/* Set rarity based on power. kind is the final base item kind. */
|
|
448
|
+
const baseKind = kind as NonNullable<typeof kind>;
|
|
449
|
+
let allocNew = Math.trunc(4000000 / (ap * ap));
|
|
450
|
+
allocNew = Math.trunc(allocNew / (baseKind.allocProb ? baseKind.allocProb : 20));
|
|
451
|
+
if (allocNew > 99) allocNew = 99;
|
|
452
|
+
if (allocNew < 1) allocNew = 1;
|
|
453
|
+
art.allocProb = allocNew;
|
|
454
|
+
|
|
455
|
+
/* Set depth according to power. */
|
|
456
|
+
art.allocMax = Math.min(127, Math.trunc((ap * 3) / 5));
|
|
457
|
+
art.allocMin = Math.min(100, Math.trunc(((ap + 100) * 100) / data.maxPower));
|
|
458
|
+
|
|
459
|
+
/* Have a chance to be less rare or deep, more likely the less power. */
|
|
460
|
+
if (rng.oneIn(5 + Math.trunc(power / 20))) {
|
|
461
|
+
art.allocProb += rng.randint1(20);
|
|
462
|
+
if (art.allocProb > 99) art.allocProb = 99;
|
|
463
|
+
} else if (rng.oneIn(5 + Math.trunc(power / 20))) {
|
|
464
|
+
art.allocMin = Math.trunc(art.allocMin / 2);
|
|
465
|
+
if (art.allocMin < 1) art.allocMin = 1;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/* Sanity check. */
|
|
469
|
+
art.allocMax = Math.max(art.allocMax, Math.min(art.allocMin * 2, 127));
|
|
470
|
+
|
|
471
|
+
/*
|
|
472
|
+
* If there is no activation or effect from the kind, level currently does
|
|
473
|
+
* nothing. Set it to alloc_min in case changes elsewhere start using level.
|
|
474
|
+
*/
|
|
475
|
+
if (!art.activation && !baseKind.activation && !baseKind.effect) {
|
|
476
|
+
art.level = art.allocMin;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
randartLogf(
|
|
480
|
+
() =>
|
|
481
|
+
`New depths are min ${String(art.allocMin)}, max ${String(art.allocMax)}\n`,
|
|
482
|
+
);
|
|
483
|
+
randartLogf(
|
|
484
|
+
() => `Power-based alloc_prob is ${String(art.allocProb)}\n`,
|
|
485
|
+
);
|
|
486
|
+
|
|
487
|
+
/* Success. */
|
|
488
|
+
randartLog("<<<<<<<<<<<<<<<<<<<<<<<<<< ARTIFACT COMPLETED\n");
|
|
489
|
+
randartLogf(
|
|
490
|
+
() =>
|
|
491
|
+
`Number of tries for artifact ${String(aidx)} was: ${String(tries)}\n`,
|
|
492
|
+
);
|
|
493
|
+
|
|
494
|
+
/* Describe it. */
|
|
495
|
+
describeArtifact(art, ap);
|
|
496
|
+
|
|
497
|
+
return aidx;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/* ------------------------------------------------------------------ */
|
|
501
|
+
/* create_artifact_set (obj-randart.c L2954) */
|
|
502
|
+
/* ------------------------------------------------------------------ */
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* create_artifact_set (obj-randart.c L2954): design a full set of random
|
|
506
|
+
* artifacts into `arts`. The resulting set has at least 80% as many artifacts
|
|
507
|
+
* of any given tval as the original set (tvals with fewer than 5 original
|
|
508
|
+
* artifacts get equal or more). Remaining slots are filled with random-tval
|
|
509
|
+
* artifacts. The final slot (index arts.length - 1) is left as the original,
|
|
510
|
+
* matching the upstream `aidx < z_info->a_max - 1` bound.
|
|
511
|
+
*/
|
|
512
|
+
export function createArtifactSet(
|
|
513
|
+
reg: ObjRegistry,
|
|
514
|
+
constants: Constants,
|
|
515
|
+
arts: (Artifact | null)[],
|
|
516
|
+
data: ArtifactSetData,
|
|
517
|
+
rng: Rng,
|
|
518
|
+
nameProbs: NameProbs | null,
|
|
519
|
+
): void {
|
|
520
|
+
let aidx = 1;
|
|
521
|
+
const tvalTotal = new Array<number>(TV_MAX).fill(0);
|
|
522
|
+
let notDone = true;
|
|
523
|
+
|
|
524
|
+
/* Get min tval frequencies for the new artifacts (at least 80% each). */
|
|
525
|
+
for (let i = 0; i < TV_MAX; i++) {
|
|
526
|
+
tvalTotal[i] = Math.trunc((4 * (data.tvNum[i]! + 1)) / 5);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/* Allocate a minimal set of artifacts to the tvals. */
|
|
530
|
+
while (notDone) {
|
|
531
|
+
notDone = false;
|
|
532
|
+
|
|
533
|
+
/* Multiple passes through tvals until all have enough artifacts. */
|
|
534
|
+
for (let i = 0; i < TV_MAX; i++) {
|
|
535
|
+
if (tvalTotal[i]! > 0) {
|
|
536
|
+
aidx = designArtifact(reg, constants, arts, data, i, aidx, rng, nameProbs);
|
|
537
|
+
tvalTotal[i]!--;
|
|
538
|
+
aidx++;
|
|
539
|
+
notDone = true;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/* Allocate remaining artifacts at random. */
|
|
545
|
+
while (aidx < arts.length - 1) {
|
|
546
|
+
aidx = designArtifact(
|
|
547
|
+
reg,
|
|
548
|
+
constants,
|
|
549
|
+
arts,
|
|
550
|
+
data,
|
|
551
|
+
TV.NULL,
|
|
552
|
+
aidx,
|
|
553
|
+
rng,
|
|
554
|
+
nameProbs,
|
|
555
|
+
);
|
|
556
|
+
aidx++;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/* ------------------------------------------------------------------ */
|
|
561
|
+
/* do_randart (obj-randart.c L3154) */
|
|
562
|
+
/* ------------------------------------------------------------------ */
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* do_randart (obj-randart.c L3154): generate a full random artifact set from a
|
|
566
|
+
* seed and return it as a fresh (Artifact|null)[] array (index 0 null),
|
|
567
|
+
* leaving ObjRegistry.artifacts untouched. Pure with respect to the seed.
|
|
568
|
+
*
|
|
569
|
+
* Upstream seeds the "quick" LCRNG (Rand_value = seed, Rand_quick = true), so
|
|
570
|
+
* this port creates its Rng in quick mode and draws in upstream order:
|
|
571
|
+
* measure the standard set (store_base_power + parse_frequencies via
|
|
572
|
+
* collectArtifactData), design every artifact (create_artifact_set), then
|
|
573
|
+
* measure the finished set the same way. The log file (randart.log), the
|
|
574
|
+
* post-generation measurement pass and the optional spoiler file (create_file /
|
|
575
|
+
* write_randart_entry) are all ported (PORT_TODO 5.5); none of them affects an
|
|
576
|
+
* artifact field or an RNG draw.
|
|
577
|
+
*/
|
|
578
|
+
/** path_build(ANGBAND_DIR_USER, "randart.log") (obj-randart.c L3165). */
|
|
579
|
+
export const RANDART_LOG = "randart.log";
|
|
580
|
+
|
|
581
|
+
export function doRandart(
|
|
582
|
+
reg: ObjRegistry,
|
|
583
|
+
/**
|
|
584
|
+
* z_info / the player constants object_prep reads. Upstream reaches them as
|
|
585
|
+
* globals; the port passes them, and they arrive here because artifact_power
|
|
586
|
+
* builds a real fake object through make_fake_artifact.
|
|
587
|
+
*/
|
|
588
|
+
constants: Constants,
|
|
589
|
+
randartSeed: number,
|
|
590
|
+
/**
|
|
591
|
+
* do_randart's `create_file` (obj-randart.c:3154). True writes randart.txt
|
|
592
|
+
* beside randart.log; upstream passes true from birth, from loading a save
|
|
593
|
+
* and from the spoiler generator, and false from the statistics harnesses.
|
|
594
|
+
*
|
|
595
|
+
* REQUIRED, with no default: the two callers that want it differ from the
|
|
596
|
+
* many that do not, and a default would silently pick one of them.
|
|
597
|
+
*/
|
|
598
|
+
createFile: boolean,
|
|
599
|
+
tolkienWords?: readonly string[],
|
|
600
|
+
extras?: Pick<ArtifactSetData, "timedFoil" | "activationSummarize">,
|
|
601
|
+
io: HostIo = host(),
|
|
602
|
+
onLogError?: (message: string) => void,
|
|
603
|
+
): (Artifact | null)[] {
|
|
604
|
+
/*
|
|
605
|
+
* OPEN randart.log (obj-randart.c L3164-L3171).
|
|
606
|
+
*
|
|
607
|
+
* Upstream file_opens ANGBAND_DIR_USER/randart.log for writing before it
|
|
608
|
+
* touches an artifact, and `exit(1)`s if it cannot. That exit is the one
|
|
609
|
+
* thing the port cannot copy: a browser tab has no process to kill, and a
|
|
610
|
+
* desktop player did not ask to lose a character over a log file. So the
|
|
611
|
+
* failure goes through the host instead - the open is probed by truncating
|
|
612
|
+
* the file to empty (which is what MODE_WRITE does), and if that fails the
|
|
613
|
+
* sink stays closed, `onLogError` gets upstream's own message, and every
|
|
614
|
+
* emitter downstream is the no-op it already is with no log running.
|
|
615
|
+
* Generation continues, which is the deliberate divergence.
|
|
616
|
+
*
|
|
617
|
+
* BUFFERED, not appended line by line: HostIo.write is one whole-file call
|
|
618
|
+
* (that is what a localStorage-backed adapter can express), and a run of the
|
|
619
|
+
* standard set emits tens of thousands of lines.
|
|
620
|
+
*/
|
|
621
|
+
/* Prepare to use the Angband "simple" (quick LCRNG) RNG. */
|
|
622
|
+
const rng = new Rng(randartSeed, { quick: true });
|
|
623
|
+
|
|
624
|
+
const lines: string[] = [];
|
|
625
|
+
let generated: (Artifact | null)[] = [];
|
|
626
|
+
let logging = false;
|
|
627
|
+
if (io.write(HostDir.USER, RANDART_LOG, "", FileMode.WRITE, FileType.TEXT) === "ok") {
|
|
628
|
+
logging = true;
|
|
629
|
+
setRandartLog((text) => lines.push(text));
|
|
630
|
+
} else {
|
|
631
|
+
onLogError?.("Error - can't open randart.log for writing.");
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
try {
|
|
635
|
+
/*
|
|
636
|
+
* Build the RANDNAME_TOLKIEN transition table once (build_prob is cached
|
|
637
|
+
* per-type upstream, randname.c L94-L103; here we build it once per run).
|
|
638
|
+
* When no corpus is supplied (the current game-path seam), fall back to the
|
|
639
|
+
* non-faithful syllable generator (see module SEAM note). An empty word list
|
|
640
|
+
* is treated as "no corpus" because build_prob/randname_make would otherwise
|
|
641
|
+
* loop forever on an empty table.
|
|
642
|
+
*/
|
|
643
|
+
const nameProbs: NameProbs | null =
|
|
644
|
+
tolkienWords && tolkienWords.length > 0 ? buildProb(tolkienWords) : null;
|
|
645
|
+
|
|
646
|
+
/* Store the original power ratings and determine generation probabilities
|
|
647
|
+
* for the STANDARD set (L3175-L3178). `extras` threads the curse TIMED_INC
|
|
648
|
+
* foil tables (gap 3.3) and the activation redundancy summarizer (gap 3.8);
|
|
649
|
+
* absent, both checks are skipped as before. */
|
|
650
|
+
const data = collectArtifactData(reg, constants, reg.artifacts, rng);
|
|
651
|
+
if (extras?.timedFoil) data.timedFoil = extras.timedFoil;
|
|
652
|
+
if (extras?.activationSummarize) {
|
|
653
|
+
data.activationSummarize = extras.activationSummarize;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/* Work on a fresh copy so the registry's standard artifacts are preserved. */
|
|
657
|
+
const arts: (Artifact | null)[] = reg.artifacts.map((a) =>
|
|
658
|
+
a ? cloneArtifact(a) : null,
|
|
659
|
+
);
|
|
660
|
+
|
|
661
|
+
/* Generate the random artifacts. */
|
|
662
|
+
createArtifactSet(reg, constants, arts, data, rng, nameProbs);
|
|
663
|
+
|
|
664
|
+
generated = arts;
|
|
665
|
+
|
|
666
|
+
/*
|
|
667
|
+
* LOOK AT THE FREQUENCIES ON THE FINISHED ITEMS (L3181-L3186).
|
|
668
|
+
*
|
|
669
|
+
* A whole second measurement pass over the set just generated, into a
|
|
670
|
+
* throwaway ArtifactSetData that upstream frees on the next line. Nothing
|
|
671
|
+
* reads it: its ONLY product is the text both passes write to the log, so
|
|
672
|
+
* a reader can compare the set the game just made against the standard one
|
|
673
|
+
* it was derived from. That is why it was invisible while the log was full
|
|
674
|
+
* of holes, and why it can be added now without changing an artifact - it
|
|
675
|
+
* runs after generation and draws no RNG (see collectArtifactData).
|
|
676
|
+
*
|
|
677
|
+
* `extras` is deliberately NOT applied here: upstream measures the finished
|
|
678
|
+
* set with a plain artifact_set_data_new, and both extras are generation-
|
|
679
|
+
* time checks that this pass never reaches.
|
|
680
|
+
*/
|
|
681
|
+
collectArtifactData(reg, constants, arts, rng);
|
|
682
|
+
|
|
683
|
+
return arts;
|
|
684
|
+
} finally {
|
|
685
|
+
/* CLOSE (L3189-L3193). In a `finally` so a throw mid-generation cannot
|
|
686
|
+
* leave the sink installed for the next caller - upstream's log_file is a
|
|
687
|
+
* static, and a stale one would narrate the following run into this one. */
|
|
688
|
+
setRandartLog(null);
|
|
689
|
+
if (logging) {
|
|
690
|
+
const outcome = io.write(
|
|
691
|
+
HostDir.USER,
|
|
692
|
+
RANDART_LOG,
|
|
693
|
+
lines.join(""),
|
|
694
|
+
FileMode.WRITE,
|
|
695
|
+
FileType.TEXT,
|
|
696
|
+
);
|
|
697
|
+
if (outcome !== "ok") onLogError?.("Error - can't close randart.log file.");
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/*
|
|
701
|
+
* WRITE A DATA FILE IF REQUIRED (L3195-L3215), after the log is closed,
|
|
702
|
+
* which is upstream's order - it reuses the same handle variable for both.
|
|
703
|
+
*
|
|
704
|
+
* Upstream `quit_fmt`s if this file cannot be closed. The port cannot: the
|
|
705
|
+
* same reasoning as the randart.log open above applies, so the failure goes
|
|
706
|
+
* to onLogError and the artifact set is returned regardless. Writing the
|
|
707
|
+
* file is a courtesy; losing the character over it is not.
|
|
708
|
+
*/
|
|
709
|
+
if (createFile) {
|
|
710
|
+
const outcome = io.write(
|
|
711
|
+
HostDir.USER,
|
|
712
|
+
RANDART_TXT,
|
|
713
|
+
writeRandartFile(reg, generated, randartSeed),
|
|
714
|
+
FileMode.WRITE,
|
|
715
|
+
FileType.TEXT,
|
|
716
|
+
);
|
|
717
|
+
if (outcome !== "ok") {
|
|
718
|
+
onLogError?.(`Error - can't close ${RANDART_TXT}.`);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
}
|