@rpgm-tools/neo-angband-core 0.18.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/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/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-data.ts
CHANGED
|
@@ -1,1344 +1,1547 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Random artifact generation: the data model and power-measurement half,
|
|
3
|
-
* ported from reference/src/obj-randart.c (Angband 4.2.6) lines 1-1332 plus
|
|
4
|
-
* the struct artifact_set_data allocator (obj-randart.c L2993) and the
|
|
5
|
-
* struct definition in obj-randart.h.
|
|
6
|
-
*
|
|
7
|
-
* This module ports the parts of the randart generator that measure the
|
|
8
|
-
* standard artifact set: it evaluates each artifact's power (artifactPower,
|
|
9
|
-
* upstream artifact_power), records the baseline power statistics
|
|
10
|
-
* (storeBasePower), tallies how often each ability appears (collectArtifactData
|
|
11
|
-
* and the count_* helpers), and rescales those tallies into generation
|
|
12
|
-
* frequencies (parseFrequencies / rescaleFreqs / adjustFreqs). The actual
|
|
13
|
-
* generation of new artifacts (do_randart and its helpers, obj-randart.c
|
|
14
|
-
* L1332+) is a separate, later port.
|
|
15
|
-
*
|
|
16
|
-
* Faithful notes / approximations:
|
|
17
|
-
* - The upstream file_putf(log_file, ...) logging is
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* -
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
} from "./
|
|
53
|
-
import {
|
|
54
|
-
import {
|
|
55
|
-
import
|
|
56
|
-
import type {
|
|
57
|
-
import {
|
|
58
|
-
import type {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
*/
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
*
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
]
|
|
145
|
-
|
|
146
|
-
ART_IDX.
|
|
147
|
-
ART_IDX.
|
|
148
|
-
ART_IDX.
|
|
149
|
-
];
|
|
150
|
-
const
|
|
151
|
-
ART_IDX.
|
|
152
|
-
ART_IDX.
|
|
153
|
-
ART_IDX.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
ART_IDX.
|
|
157
|
-
ART_IDX.
|
|
158
|
-
ART_IDX.
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
ART_IDX.
|
|
162
|
-
ART_IDX.
|
|
163
|
-
ART_IDX.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
ART_IDX.
|
|
167
|
-
ART_IDX.
|
|
168
|
-
ART_IDX.
|
|
169
|
-
ART_IDX.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
ART_IDX.
|
|
174
|
-
ART_IDX.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
ART_IDX.
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
ART_IDX.
|
|
182
|
-
ART_IDX.
|
|
183
|
-
ART_IDX.
|
|
184
|
-
|
|
185
|
-
]
|
|
186
|
-
|
|
187
|
-
ART_IDX.
|
|
188
|
-
ART_IDX.
|
|
189
|
-
ART_IDX.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
ART_IDX.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
ART_IDX.
|
|
196
|
-
ART_IDX.
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
ART_IDX.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
ART_IDX.
|
|
205
|
-
ART_IDX.
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
ART_IDX.
|
|
209
|
-
ART_IDX.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
/** randcalc(v, 0,
|
|
222
|
-
function
|
|
223
|
-
return v.base + v.dice
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/** Number of set entries in a 1-based boolean slay/brand array, or 0. */
|
|
227
|
-
function countTrue(arr: readonly boolean[] | null): number {
|
|
228
|
-
if (!arr) return 0;
|
|
229
|
-
let n = 0;
|
|
230
|
-
for (let i = 1; i < arr.length; i++) {
|
|
231
|
-
if (arr[i]) n++;
|
|
232
|
-
}
|
|
233
|
-
return n;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* store_base_power's two statistics, at the call shape obj-randart.c L278-L282
|
|
238
|
-
* uses: mean(a, n, &frac) and variance(a, n, false, false, &frac), i.e. the
|
|
239
|
-
* FLOORED variants. The scratch fraction upstream passes is written and then
|
|
240
|
-
* ignored, so one shared throwaway stands in for it.
|
|
241
|
-
*
|
|
242
|
-
* These used to be local reimplementations here (plain floor division and
|
|
243
|
-
* (sum(x^2)*size - sum(x)^2) / size^2). They agreed with the C for artifact
|
|
244
|
-
* powers, but not at the rails: upstream's variance saturates at INT_MAX and
|
|
245
|
-
* upstream's mean floors toward negative infinity via a magnitude-and-fraction
|
|
246
|
-
* dance. ../rational is the real port, so the statistics now go through it.
|
|
247
|
-
*/
|
|
248
|
-
const SCRATCH_FRAC = { n: 0, d: 1 };
|
|
249
|
-
|
|
250
|
-
function meanFloored(nums: readonly number[]): number {
|
|
251
|
-
return mean(nums, nums.length, SCRATCH_FRAC);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
function varianceFloored(nums: readonly number[]): number {
|
|
255
|
-
return variance(nums, nums.length, false, false, SCRATCH_FRAC);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/* ------------------------------------------------------------------ */
|
|
259
|
-
/* artifact_power (obj-randart.c L186) */
|
|
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
|
-
|
|
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
|
-
data.maxPower
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
const
|
|
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
|
-
const
|
|
512
|
-
const
|
|
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
|
-
if (
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
data.artProbs[ART_IDX.
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
data.artProbs[ART_IDX.
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
const
|
|
628
|
-
if (
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
art
|
|
650
|
-
|
|
651
|
-
)
|
|
652
|
-
|
|
653
|
-
if (
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
/*
|
|
727
|
-
if (
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
) {
|
|
761
|
-
|
|
762
|
-
data.
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
if (
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
data.artProbs[ART_IDX.
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
/*
|
|
810
|
-
if (
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
if (
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
if (
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
art.tval === TV.
|
|
872
|
-
art.tval === TV.
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
art.tval === TV.
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
if (
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
if (art.
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
if ((art.
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
if (
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
if (
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
)
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
}
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
data.artProbs[ART_IDX.
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
if (art.
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
)
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
)
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
}
|
|
1124
|
-
|
|
1125
|
-
/*
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
}
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
)
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
*/
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
/*
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
*/
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Random artifact generation: the data model and power-measurement half,
|
|
3
|
+
* ported from reference/src/obj-randart.c (Angband 4.2.6) lines 1-1332 plus
|
|
4
|
+
* the struct artifact_set_data allocator (obj-randart.c L2993) and the
|
|
5
|
+
* struct definition in obj-randart.h.
|
|
6
|
+
*
|
|
7
|
+
* This module ports the parts of the randart generator that measure the
|
|
8
|
+
* standard artifact set: it evaluates each artifact's power (artifactPower,
|
|
9
|
+
* upstream artifact_power), records the baseline power statistics
|
|
10
|
+
* (storeBasePower), tallies how often each ability appears (collectArtifactData
|
|
11
|
+
* and the count_* helpers), and rescales those tallies into generation
|
|
12
|
+
* frequencies (parseFrequencies / rescaleFreqs / adjustFreqs). The actual
|
|
13
|
+
* generation of new artifacts (do_randart and its helpers, obj-randart.c
|
|
14
|
+
* L1332+) is a separate, later port.
|
|
15
|
+
*
|
|
16
|
+
* Faithful notes / approximations:
|
|
17
|
+
* - The upstream file_putf(log_file, ...) logging is PORTED (PORT_TODO 5.5),
|
|
18
|
+
* through the randartLog sink in ./randart-log.js. It never affects any
|
|
19
|
+
* returned value, so a run with no log open behaves identically.
|
|
20
|
+
* - artifact_power (obj-randart.c L186) builds a "fake" object with
|
|
21
|
+
* make_fake_artifact (obj-make.c L728) and calls object_power on it. It calls
|
|
22
|
+
* the REAL one: obj/artifact-fake.ts, the same builder the knowledge browser
|
|
23
|
+
* and the spoiler dump use, which is object_prep(kind, 0, MAXIMISE)
|
|
24
|
+
* (obj-make.c L817) followed by copy_artifact_data (obj-make.c L520).
|
|
25
|
+
* This file used to carry its own hand-written copy of that field mapping,
|
|
26
|
+
* flattened into a PowerObject because object_power reads only a few fields.
|
|
27
|
+
* Two hand-written copies of one C function agree until they do not, and the
|
|
28
|
+
* divergence would have been silent and total (artifact_power drives the
|
|
29
|
+
* whole design loop). It also cost the object_desc log line, which needs the
|
|
30
|
+
* whole object. Both are gone: one builder, one field mapping.
|
|
31
|
+
* - The fake object's curse timeouts (copy_curses, obj-curse.c) are set from a
|
|
32
|
+
* RANDOMISE roll upstream, and that roll DRAWS. The timeout never enters
|
|
33
|
+
* object_power, so this file used to skip it and say no RNG was consumed;
|
|
34
|
+
* that was measured on the standard artifact set (one curse in the whole
|
|
35
|
+
* file) and was wrong during generation, where design_artifact re-powers an
|
|
36
|
+
* artifact make_bad has just cursed. The rolls are made, in upstream's order,
|
|
37
|
+
* by copyArtifactData itself now that the real builder does the work.
|
|
38
|
+
* - Upstream mean()/variance() (z-util.c L1389/L1516) are exact-rational
|
|
39
|
+
* multi-precision routines; store_base_power calls them with a non-NULL frac,
|
|
40
|
+
* which is the "round the result down" path. Both are now ported for real in
|
|
41
|
+
* ../rational (saturation and all) and called through meanFloored /
|
|
42
|
+
* varianceFloored below, rather than reimplemented here.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
import { randartLog, randartLogf } from "./randart-log.js";
|
|
46
|
+
import { randartRegistry, seedRandart } from "./randart-registry.js";
|
|
47
|
+
import { ELEM, KF, OBJ_MOD, OF, TV } from "../generated/index.js";
|
|
48
|
+
import { ART_IDX } from "../generated/randart-properties.js";
|
|
49
|
+
import type { Rng } from "../rng.js";
|
|
50
|
+
import type { Constants } from "../constants.js";
|
|
51
|
+
import type { ObjRegistry } from "./bind.js";
|
|
52
|
+
import { tvalFindName } from "./bind.js";
|
|
53
|
+
import type { CurseTimedFoil } from "./object.js";
|
|
54
|
+
import { makeFakeArtifact } from "./artifact-fake.js";
|
|
55
|
+
import { ODESC, objectDesc } from "./desc.js";
|
|
56
|
+
import type { KnownDesc } from "./known-object.js";
|
|
57
|
+
import { makeRuneEnv } from "./knowledge.js";
|
|
58
|
+
import type { ActivationSummarizer } from "./randart-build.js";
|
|
59
|
+
import { mean, variance } from "../rational.js";
|
|
60
|
+
import { objectPower } from "./power.js";
|
|
61
|
+
import type { Artifact, ElementInfo } from "./types.js";
|
|
62
|
+
import { TV_MAX } from "./types.js";
|
|
63
|
+
import type { RandomValue } from "../rng.js";
|
|
64
|
+
|
|
65
|
+
/** ART_IDX_TOTAL: number of learned-probability slots (obj-randart.h). */
|
|
66
|
+
const ART_IDX_TOTAL = ART_IDX.TOTAL;
|
|
67
|
+
|
|
68
|
+
/* ------------------------------------------------------------------ */
|
|
69
|
+
/* struct artifact_set_data (obj-randart.h L59) */
|
|
70
|
+
/* ------------------------------------------------------------------ */
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* struct artifact_set_data: everything the generator learns from the standard
|
|
74
|
+
* artifact set. Field names mirror the upstream struct (snake_case -> camelCase).
|
|
75
|
+
*/
|
|
76
|
+
export interface ArtifactSetData {
|
|
77
|
+
/* Mean start and increment values for to_hit, to_dam and AC. */
|
|
78
|
+
hitIncrement: number;
|
|
79
|
+
damIncrement: number;
|
|
80
|
+
hitStartval: number;
|
|
81
|
+
damStartval: number;
|
|
82
|
+
acStartval: number;
|
|
83
|
+
acIncrement: number;
|
|
84
|
+
|
|
85
|
+
/* Data structures for learned probabilities. */
|
|
86
|
+
artProbs: number[];
|
|
87
|
+
tvProbs: number[];
|
|
88
|
+
tvNum: number[];
|
|
89
|
+
bowTotal: number;
|
|
90
|
+
meleeTotal: number;
|
|
91
|
+
bootTotal: number;
|
|
92
|
+
gloveTotal: number;
|
|
93
|
+
headgearTotal: number;
|
|
94
|
+
shieldTotal: number;
|
|
95
|
+
cloakTotal: number;
|
|
96
|
+
armorTotal: number;
|
|
97
|
+
otherTotal: number;
|
|
98
|
+
total: number;
|
|
99
|
+
negPowerTotal: number;
|
|
100
|
+
|
|
101
|
+
/* Tval frequency values. */
|
|
102
|
+
tvFreq: number[];
|
|
103
|
+
|
|
104
|
+
/* Artifact power ratings. */
|
|
105
|
+
basePower: number[];
|
|
106
|
+
maxPower: number;
|
|
107
|
+
minPower: number;
|
|
108
|
+
avgPower: number;
|
|
109
|
+
varPower: number;
|
|
110
|
+
avgTvPower: number[];
|
|
111
|
+
minTvPower: number[];
|
|
112
|
+
maxTvPower: number[];
|
|
113
|
+
|
|
114
|
+
/* Base item levels. */
|
|
115
|
+
baseItemLevel: number[];
|
|
116
|
+
|
|
117
|
+
/* Base item rarities. */
|
|
118
|
+
baseItemProb: number[];
|
|
119
|
+
|
|
120
|
+
/* Artifact rarities. */
|
|
121
|
+
baseArtAlloc: number[];
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The player-timed failure tables (timed effect NAME -> fail directives) for
|
|
125
|
+
* artifact_curse_conflicts' TIMED_INC foil rejection (obj-curse.c L267-296).
|
|
126
|
+
* Built by the game from the bound TimedEffect[]; absent => the foil branch
|
|
127
|
+
* is skipped (curses still filtered by explicit conflict flags). See gap 3.3.
|
|
128
|
+
*/
|
|
129
|
+
timedFoil?: CurseTimedFoil | undefined;
|
|
130
|
+
/**
|
|
131
|
+
* effect_summarize_properties (effects-info.c) for
|
|
132
|
+
* remove_contradictory_activation's redundancy check (obj-randart.c L2420,
|
|
133
|
+
* gap 3.8). Lives in the effects domain; injected here. Absent => a redundant
|
|
134
|
+
* activation is never stripped (conservative). Wired from the effects layer.
|
|
135
|
+
*/
|
|
136
|
+
activationSummarize?: ActivationSummarizer | undefined;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* ------------------------------------------------------------------ */
|
|
140
|
+
/* Arrays of indices by item type, used in frequency generation */
|
|
141
|
+
/* (obj-randart.c L52) */
|
|
142
|
+
/* ------------------------------------------------------------------ */
|
|
143
|
+
|
|
144
|
+
const artIdxBow: readonly number[] = [
|
|
145
|
+
ART_IDX.BOW_SHOTS,
|
|
146
|
+
ART_IDX.BOW_MIGHT,
|
|
147
|
+
ART_IDX.BOW_BRAND,
|
|
148
|
+
ART_IDX.BOW_SLAY,
|
|
149
|
+
];
|
|
150
|
+
const artIdxWeapon: readonly number[] = [
|
|
151
|
+
ART_IDX.WEAPON_HIT,
|
|
152
|
+
ART_IDX.WEAPON_DAM,
|
|
153
|
+
ART_IDX.WEAPON_AGGR,
|
|
154
|
+
];
|
|
155
|
+
const artIdxNonweapon: readonly number[] = [
|
|
156
|
+
ART_IDX.NONWEAPON_HIT,
|
|
157
|
+
ART_IDX.NONWEAPON_DAM,
|
|
158
|
+
ART_IDX.NONWEAPON_HIT_DAM,
|
|
159
|
+
ART_IDX.NONWEAPON_AGGR,
|
|
160
|
+
ART_IDX.NONWEAPON_BRAND,
|
|
161
|
+
ART_IDX.NONWEAPON_SLAY,
|
|
162
|
+
ART_IDX.NONWEAPON_BLOWS,
|
|
163
|
+
ART_IDX.NONWEAPON_SHOTS,
|
|
164
|
+
];
|
|
165
|
+
const artIdxMelee: readonly number[] = [
|
|
166
|
+
ART_IDX.MELEE_BLESS,
|
|
167
|
+
ART_IDX.MELEE_SINV,
|
|
168
|
+
ART_IDX.MELEE_BRAND,
|
|
169
|
+
ART_IDX.MELEE_SLAY,
|
|
170
|
+
ART_IDX.MELEE_BLOWS,
|
|
171
|
+
ART_IDX.MELEE_AC,
|
|
172
|
+
ART_IDX.MELEE_DICE,
|
|
173
|
+
ART_IDX.MELEE_WEIGHT,
|
|
174
|
+
ART_IDX.MELEE_TUNN,
|
|
175
|
+
];
|
|
176
|
+
const artIdxAllarmor: readonly number[] = [ART_IDX.ALLARMOR_WEIGHT];
|
|
177
|
+
const artIdxBoot: readonly number[] = [
|
|
178
|
+
ART_IDX.BOOT_AC,
|
|
179
|
+
ART_IDX.BOOT_FEATHER,
|
|
180
|
+
ART_IDX.BOOT_STEALTH,
|
|
181
|
+
ART_IDX.BOOT_TRAP_IMM,
|
|
182
|
+
ART_IDX.BOOT_SPEED,
|
|
183
|
+
ART_IDX.BOOT_MOVES,
|
|
184
|
+
];
|
|
185
|
+
const artIdxGlove: readonly number[] = [
|
|
186
|
+
ART_IDX.GLOVE_AC,
|
|
187
|
+
ART_IDX.GLOVE_HIT_DAM,
|
|
188
|
+
ART_IDX.GLOVE_FA,
|
|
189
|
+
ART_IDX.GLOVE_DEX,
|
|
190
|
+
];
|
|
191
|
+
const artIdxHeadgear: readonly number[] = [
|
|
192
|
+
ART_IDX.HELM_AC,
|
|
193
|
+
ART_IDX.HELM_RBLIND,
|
|
194
|
+
ART_IDX.HELM_ESP,
|
|
195
|
+
ART_IDX.HELM_SINV,
|
|
196
|
+
ART_IDX.HELM_WIS,
|
|
197
|
+
ART_IDX.HELM_INT,
|
|
198
|
+
];
|
|
199
|
+
const artIdxShield: readonly number[] = [
|
|
200
|
+
ART_IDX.SHIELD_AC,
|
|
201
|
+
ART_IDX.SHIELD_LRES,
|
|
202
|
+
];
|
|
203
|
+
const artIdxCloak: readonly number[] = [
|
|
204
|
+
ART_IDX.CLOAK_AC,
|
|
205
|
+
ART_IDX.CLOAK_STEALTH,
|
|
206
|
+
];
|
|
207
|
+
const artIdxArmor: readonly number[] = [
|
|
208
|
+
ART_IDX.ARMOR_AC,
|
|
209
|
+
ART_IDX.ARMOR_STEALTH,
|
|
210
|
+
ART_IDX.ARMOR_HLIFE,
|
|
211
|
+
ART_IDX.ARMOR_CON,
|
|
212
|
+
ART_IDX.ARMOR_LRES,
|
|
213
|
+
ART_IDX.ARMOR_ALLRES,
|
|
214
|
+
ART_IDX.ARMOR_HRES,
|
|
215
|
+
];
|
|
216
|
+
|
|
217
|
+
/* ------------------------------------------------------------------ */
|
|
218
|
+
/* Aspect helpers (pure; MAXIMISE/MINIMISE consume no RNG) */
|
|
219
|
+
/* ------------------------------------------------------------------ */
|
|
220
|
+
|
|
221
|
+
/** randcalc(v, 0, MINIMISE): base + dice (see rng.ts damcalc/mBonusCalc). */
|
|
222
|
+
function rvMinimise(v: RandomValue): number {
|
|
223
|
+
return v.base + v.dice;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/** Number of set entries in a 1-based boolean slay/brand array, or 0. */
|
|
227
|
+
function countTrue(arr: readonly boolean[] | null): number {
|
|
228
|
+
if (!arr) return 0;
|
|
229
|
+
let n = 0;
|
|
230
|
+
for (let i = 1; i < arr.length; i++) {
|
|
231
|
+
if (arr[i]) n++;
|
|
232
|
+
}
|
|
233
|
+
return n;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* store_base_power's two statistics, at the call shape obj-randart.c L278-L282
|
|
238
|
+
* uses: mean(a, n, &frac) and variance(a, n, false, false, &frac), i.e. the
|
|
239
|
+
* FLOORED variants. The scratch fraction upstream passes is written and then
|
|
240
|
+
* ignored, so one shared throwaway stands in for it.
|
|
241
|
+
*
|
|
242
|
+
* These used to be local reimplementations here (plain floor division and
|
|
243
|
+
* (sum(x^2)*size - sum(x)^2) / size^2). They agreed with the C for artifact
|
|
244
|
+
* powers, but not at the rails: upstream's variance saturates at INT_MAX and
|
|
245
|
+
* upstream's mean floors toward negative infinity via a magnitude-and-fraction
|
|
246
|
+
* dance. ../rational is the real port, so the statistics now go through it.
|
|
247
|
+
*/
|
|
248
|
+
const SCRATCH_FRAC = { n: 0, d: 1 };
|
|
249
|
+
|
|
250
|
+
function meanFloored(nums: readonly number[]): number {
|
|
251
|
+
return mean(nums, nums.length, SCRATCH_FRAC);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function varianceFloored(nums: readonly number[]): number {
|
|
255
|
+
return variance(nums, nums.length, false, false, SCRATCH_FRAC);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/* ------------------------------------------------------------------ */
|
|
259
|
+
/* artifact_power (obj-randart.c L186) */
|
|
260
|
+
/* ------------------------------------------------------------------ */
|
|
261
|
+
/**
|
|
262
|
+
* artifact_power (obj-randart.c L186): the artifact's power, by generating a
|
|
263
|
+
* fake object from the artifact and calling the common object_power.
|
|
264
|
+
*/
|
|
265
|
+
export function artifactPower(
|
|
266
|
+
reg: ObjRegistry,
|
|
267
|
+
/**
|
|
268
|
+
* object_prep's z_info / player constants, reached upstream as globals. Only
|
|
269
|
+
* the real make_fake_artifact needs them, which is why this argument appears
|
|
270
|
+
* here at all: the flattened builder that used to live in this file could
|
|
271
|
+
* skip object_prep, and skipping object_prep is what let the two copies of
|
|
272
|
+
* one C function drift.
|
|
273
|
+
*/
|
|
274
|
+
constants: Constants,
|
|
275
|
+
art: Artifact,
|
|
276
|
+
/**
|
|
277
|
+
* artifact_power's `reason` (obj-randart.c:186), which exists only to head
|
|
278
|
+
* the log block. REQUIRED rather than optional: upstream writes it out at
|
|
279
|
+
* every one of its four call sites, and a default here would silently label
|
|
280
|
+
* one evaluation as another in the log the argument exists to produce.
|
|
281
|
+
*/
|
|
282
|
+
reason: string,
|
|
283
|
+
/**
|
|
284
|
+
* make_fake_artifact's copy_curses rolls a timeout per cursed slot and those
|
|
285
|
+
* rolls DRAW. Required, because a default would hand back a private Rng and
|
|
286
|
+
* silently restore the divergence this argument exists to close.
|
|
287
|
+
*/
|
|
288
|
+
rng: Rng,
|
|
289
|
+
): number {
|
|
290
|
+
randartLogf(() => `********** Evaluating ${reason} ********\n`);
|
|
291
|
+
randartLogf(() => `Artifact index is ${art.aidx}\n`);
|
|
292
|
+
|
|
293
|
+
const obj = makeFakeArtifact(reg, constants, art, rng);
|
|
294
|
+
if (!obj) return 0;
|
|
295
|
+
|
|
296
|
+
/*
|
|
297
|
+
* object_desc of the fake artifact (obj-randart.c L205-L206), with
|
|
298
|
+
* ODESC_PREFIX | ODESC_FULL | ODESC_SPOIL and a NULL player - upstream's own
|
|
299
|
+
* argument, and the reason this needs no knowledge state. A null player is
|
|
300
|
+
* an omniscient observer: objectDesc uses the object as its own known shadow
|
|
301
|
+
* and every gate opens, so the RuneEnv below is never asked a knowledge
|
|
302
|
+
* question. It supplies the registries and nothing else, and slot_object is
|
|
303
|
+
* null for every slot because there is no player to have equipment.
|
|
304
|
+
*
|
|
305
|
+
* The KnownDesc is equally thin, and deliberately says the honest thing
|
|
306
|
+
* rather than the convenient one: isAware/isTried are FALSE, exactly as
|
|
307
|
+
* upstream's kind->aware at this point in birth. It does not matter -- SPOIL
|
|
308
|
+
* forces `aware` true a line later, and obj_desc_get_basename returns
|
|
309
|
+
* kind->name for an artifact regardless -- but a KnownDesc that lied here
|
|
310
|
+
* would be a claim about the player, and this code has no player.
|
|
311
|
+
*
|
|
312
|
+
* Its format string is "%s\n", which has no literal span for the census in
|
|
313
|
+
* randart-log.census.test.ts to match, so this line was carried there as
|
|
314
|
+
* UNWRITTEN_SPANLESS = 1 for as long as it went unwritten. That count is now
|
|
315
|
+
* zero, which is the only reason the reassuring EXPECTED_MISSING_RANDART = 0
|
|
316
|
+
* can be read as "nothing left".
|
|
317
|
+
*/
|
|
318
|
+
randartLogf(() => {
|
|
319
|
+
const env = makeRuneEnv(
|
|
320
|
+
() => null,
|
|
321
|
+
(v) => rng.randcalcVaries(v),
|
|
322
|
+
{
|
|
323
|
+
brands: reg.brands,
|
|
324
|
+
slays: reg.slays,
|
|
325
|
+
curses: reg.curses,
|
|
326
|
+
properties: reg.properties,
|
|
327
|
+
elementNames: (reg.projections ?? []).map((p) => p.name),
|
|
328
|
+
},
|
|
329
|
+
);
|
|
330
|
+
const deps: KnownDesc = { isAware: () => false, isTried: () => false };
|
|
331
|
+
const name = objectDesc(
|
|
332
|
+
obj,
|
|
333
|
+
ODESC.PREFIX | ODESC.FULL | ODESC.SPOIL,
|
|
334
|
+
null,
|
|
335
|
+
env,
|
|
336
|
+
deps,
|
|
337
|
+
);
|
|
338
|
+
return `${name}
|
|
339
|
+
`;
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
return objectPower(reg, obj);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/* ------------------------------------------------------------------ */
|
|
346
|
+
/* store_base_power (obj-randart.c L219) */
|
|
347
|
+
/* ------------------------------------------------------------------ */
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* store_base_power (obj-randart.c L219): store the original artifact power
|
|
351
|
+
* ratings as a baseline, and capture the per-set and per-tval power statistics
|
|
352
|
+
* and base-item info.
|
|
353
|
+
*/
|
|
354
|
+
export function storeBasePower(
|
|
355
|
+
reg: ObjRegistry,
|
|
356
|
+
constants: Constants,
|
|
357
|
+
arts: readonly (Artifact | null)[],
|
|
358
|
+
data: ArtifactSetData,
|
|
359
|
+
rng: Rng,
|
|
360
|
+
): void {
|
|
361
|
+
const aMax = arts.length;
|
|
362
|
+
|
|
363
|
+
data.maxPower = 0;
|
|
364
|
+
data.minPower = INHIBIT_POWER + 1;
|
|
365
|
+
data.varPower = 0;
|
|
366
|
+
|
|
367
|
+
const fakeTotalPower: number[] = [];
|
|
368
|
+
const fakeTvPower: number[][] = [];
|
|
369
|
+
for (let i = 0; i < TV_MAX; i++) {
|
|
370
|
+
fakeTvPower.push([]);
|
|
371
|
+
data.minTvPower[i] = INHIBIT_POWER + 1;
|
|
372
|
+
data.maxTvPower[i] = 0;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
for (let i = 0; i < aMax; i++) {
|
|
376
|
+
const art = arts[i] ?? null;
|
|
377
|
+
const power = art
|
|
378
|
+
? artifactPower(reg, constants, art, "for original power", rng)
|
|
379
|
+
: 0;
|
|
380
|
+
data.basePower[i] = power;
|
|
381
|
+
|
|
382
|
+
/* Capture power stats, ignoring cursed and uber arts. */
|
|
383
|
+
if (power > data.maxPower && power < INHIBIT_POWER) {
|
|
384
|
+
data.maxPower = power;
|
|
385
|
+
}
|
|
386
|
+
if (power < data.minPower && power > 0) {
|
|
387
|
+
data.minPower = power;
|
|
388
|
+
}
|
|
389
|
+
if (power > 0 && power < INHIBIT_POWER && art) {
|
|
390
|
+
const tval = art.tval;
|
|
391
|
+
fakeTotalPower.push(power);
|
|
392
|
+
fakeTvPower[tval]!.push(power);
|
|
393
|
+
data.tvNum[tval] = (data.tvNum[tval] ?? 0) + 1;
|
|
394
|
+
if (power < (data.minTvPower[tval] ?? 0)) data.minTvPower[tval] = power;
|
|
395
|
+
if (power > (data.maxTvPower[tval] ?? 0)) data.maxTvPower[tval] = power;
|
|
396
|
+
}
|
|
397
|
+
if (power < 0) {
|
|
398
|
+
data.negPowerTotal++;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
if (!power || !art) continue;
|
|
402
|
+
const kind = reg.lookupKind(art.tval, art.sval);
|
|
403
|
+
if (!kind) continue;
|
|
404
|
+
data.baseItemLevel[i] = kind.level;
|
|
405
|
+
data.baseItemProb[i] = kind.allocProb;
|
|
406
|
+
data.baseArtAlloc[i] = art.allocProb;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/* Round the result down (upstream passes frac but ignores it). */
|
|
410
|
+
data.avgPower = meanFloored(fakeTotalPower);
|
|
411
|
+
data.varPower = varianceFloored(fakeTotalPower);
|
|
412
|
+
for (let i = 0; i < TV_MAX; i++) {
|
|
413
|
+
if (data.tvNum[i]) {
|
|
414
|
+
data.avgTvPower[i] = meanFloored(fakeTvPower[i]!);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
randartLogf(
|
|
419
|
+
() =>
|
|
420
|
+
`Max power is ${String(data.maxPower)}, min is ${String(data.minPower)}\n`,
|
|
421
|
+
);
|
|
422
|
+
randartLogf(
|
|
423
|
+
() =>
|
|
424
|
+
`Mean is ${String(data.avgPower)}, variance is ${String(data.varPower)}\n`,
|
|
425
|
+
);
|
|
426
|
+
for (let i = 0; i < TV_MAX; i++) {
|
|
427
|
+
if (data.avgTvPower[i]) {
|
|
428
|
+
randartLogf(
|
|
429
|
+
() =>
|
|
430
|
+
`Power for tval ${tvalFindName(i)}: min ${String(data.minTvPower[i])}, max ${String(data.maxTvPower[i])}, avg ${String(data.avgTvPower[i])}\n`,
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/* Store the number of different types, for use later. */
|
|
436
|
+
for (let i = 0; i < aMax; i++) {
|
|
437
|
+
const art = arts[i] ?? null;
|
|
438
|
+
const tval = art ? art.tval : TV.NULL;
|
|
439
|
+
/* The upstream switch on tval is now the randart registry's `census`
|
|
440
|
+
* table. This is not bookkeeping: the totals feed the frequency table the
|
|
441
|
+
* design loop SPENDS, so a mod's item class landing in `otherTotal` skews
|
|
442
|
+
* what every randart in the game becomes. An unregistered tval counts
|
|
443
|
+
* toward `otherTotal`, which is upstream's own default arm. */
|
|
444
|
+
const bucket = randartRegistry().census.handlerFor(tval);
|
|
445
|
+
if (bucket) bucket(data);
|
|
446
|
+
else data.otherTotal++;
|
|
447
|
+
data.total++;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/* ------------------------------------------------------------------ *
|
|
452
|
+
* Core's item-class census buckets, lifted case by case.
|
|
453
|
+
* ------------------------------------------------------------------ */
|
|
454
|
+
|
|
455
|
+
seedRandart((registry) => {
|
|
456
|
+
const bucket = (
|
|
457
|
+
tvals: readonly number[],
|
|
458
|
+
count: (data: ArtifactSetData) => void,
|
|
459
|
+
): void => {
|
|
460
|
+
for (const tval of tvals) registry.census.set(tval, count);
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
bucket([TV.SWORD, TV.POLEARM, TV.HAFTED], (d) => {
|
|
464
|
+
d.meleeTotal++;
|
|
465
|
+
});
|
|
466
|
+
bucket([TV.BOW], (d) => {
|
|
467
|
+
d.bowTotal++;
|
|
468
|
+
});
|
|
469
|
+
bucket([TV.SOFT_ARMOR, TV.HARD_ARMOR, TV.DRAG_ARMOR], (d) => {
|
|
470
|
+
d.armorTotal++;
|
|
471
|
+
});
|
|
472
|
+
bucket([TV.SHIELD], (d) => {
|
|
473
|
+
d.shieldTotal++;
|
|
474
|
+
});
|
|
475
|
+
bucket([TV.CLOAK], (d) => {
|
|
476
|
+
d.cloakTotal++;
|
|
477
|
+
});
|
|
478
|
+
bucket([TV.HELM, TV.CROWN], (d) => {
|
|
479
|
+
d.headgearTotal++;
|
|
480
|
+
});
|
|
481
|
+
bucket([TV.GLOVES], (d) => {
|
|
482
|
+
d.gloveTotal++;
|
|
483
|
+
});
|
|
484
|
+
bucket([TV.BOOTS], (d) => {
|
|
485
|
+
d.bootTotal++;
|
|
486
|
+
});
|
|
487
|
+
/* An EMPTY artifact slot, registered explicitly rather than left to the
|
|
488
|
+
* default: upstream distinguishes "no artifact here" (counts toward nothing)
|
|
489
|
+
* from "an item class I have no bucket for" (counts toward otherTotal), and
|
|
490
|
+
* the default arm can only express the second. */
|
|
491
|
+
bucket([TV.NULL], () => {
|
|
492
|
+
/* deliberately nothing */
|
|
493
|
+
});
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
/* ------------------------------------------------------------------ */
|
|
497
|
+
/* Ability counters (obj-randart.c L342-L1053) */
|
|
498
|
+
/* ------------------------------------------------------------------ */
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* count_weapon_abilities (obj-randart.c L342): handle weapon combat abilities.
|
|
502
|
+
*/
|
|
503
|
+
export function countWeaponAbilities(
|
|
504
|
+
reg: ObjRegistry,
|
|
505
|
+
art: Artifact,
|
|
506
|
+
data: ArtifactSetData,
|
|
507
|
+
): void {
|
|
508
|
+
const kind = reg.lookupKind(art.tval, art.sval);
|
|
509
|
+
if (!kind) return;
|
|
510
|
+
const minToH = rvMinimise(kind.toH);
|
|
511
|
+
const minToD = rvMinimise(kind.toD);
|
|
512
|
+
const minToA = rvMinimise(kind.toA);
|
|
513
|
+
|
|
514
|
+
/* To-hit and to-dam. */
|
|
515
|
+
let bonus = Math.trunc(
|
|
516
|
+
(art.toH - minToH - data.hitStartval) / data.hitIncrement,
|
|
517
|
+
);
|
|
518
|
+
if (bonus > 0) {
|
|
519
|
+
randartLogf(
|
|
520
|
+
() => `Adding ${bonus} instances of extra to-hit bonus for weapon\n`,
|
|
521
|
+
);
|
|
522
|
+
} else if (bonus < 0) {
|
|
523
|
+
randartLogf(
|
|
524
|
+
() => `Subtracting ${bonus} instances of extra to-hit bonus for weapon\n`,
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
data.artProbs[ART_IDX.WEAPON_HIT]! += bonus;
|
|
528
|
+
|
|
529
|
+
bonus = Math.trunc((art.toD - minToD - data.damStartval) / data.damIncrement);
|
|
530
|
+
/* Asymmetric with to-hit ON PURPOSE: the to-dam arm has no `< 0` test, so a
|
|
531
|
+
* bonus of exactly 0 logs "Subtracting 0" (obj-randart.c L359-363). */
|
|
532
|
+
if (bonus > 0) {
|
|
533
|
+
randartLogf(
|
|
534
|
+
() => `Adding ${bonus} instances of extra to-dam bonus for weapon\n`,
|
|
535
|
+
);
|
|
536
|
+
} else {
|
|
537
|
+
randartLogf(
|
|
538
|
+
() => `Subtracting ${bonus} instances of extra to-dam bonus for weapon\n`,
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
data.artProbs[ART_IDX.WEAPON_DAM]! += bonus;
|
|
542
|
+
|
|
543
|
+
/* Does this weapon have an unusual bonus to AC? */
|
|
544
|
+
bonus = Math.trunc((art.toA - minToA) / data.acIncrement);
|
|
545
|
+
if (art.toA > 20) {
|
|
546
|
+
randartLogf(() => `Adding ${bonus} for supercharged AC\n`);
|
|
547
|
+
data.artProbs[ART_IDX.MELEE_AC_SUPER]!++;
|
|
548
|
+
} else if (bonus > 0) {
|
|
549
|
+
randartLogf(
|
|
550
|
+
() => `Adding ${bonus} instances of extra AC bonus for weapon\n`,
|
|
551
|
+
);
|
|
552
|
+
data.artProbs[ART_IDX.MELEE_AC]! += bonus;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/* Check damage dice - are they more than normal? */
|
|
556
|
+
if (art.dd > kind.dd) {
|
|
557
|
+
if (art.dd - kind.dd > 2) {
|
|
558
|
+
randartLog(`Adding 1 for super-charged damage dice!\n`);
|
|
559
|
+
data.artProbs[ART_IDX.MELEE_DICE_SUPER]!++;
|
|
560
|
+
} else {
|
|
561
|
+
randartLog(`Adding 1 for extra damage dice.\n`);
|
|
562
|
+
data.artProbs[ART_IDX.MELEE_DICE]!++;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/* Check weight - is it different from normal? */
|
|
567
|
+
if (art.weight !== kind.weight) {
|
|
568
|
+
randartLog(`Adding 1 for unusual weight.\n`);
|
|
569
|
+
data.artProbs[ART_IDX.MELEE_WEIGHT]!++;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/* Do we have 3 or more extra blows? */
|
|
573
|
+
const blows = art.modifiers[OBJ_MOD.BLOWS] ?? 0;
|
|
574
|
+
if (blows > 2) {
|
|
575
|
+
randartLog(`Adding 1 for supercharged blows (3 or more!)\n`);
|
|
576
|
+
data.artProbs[ART_IDX.MELEE_BLOWS_SUPER]!++;
|
|
577
|
+
} else if (blows > 0) {
|
|
578
|
+
randartLog(`Adding 1 for extra blows\n`);
|
|
579
|
+
data.artProbs[ART_IDX.MELEE_BLOWS]!++;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/* Aggravation. */
|
|
583
|
+
if (art.flags.has(OF.AGGRAVATE)) {
|
|
584
|
+
randartLog(`Adding 1 for aggravation - weapon\n`);
|
|
585
|
+
data.artProbs[ART_IDX.WEAPON_AGGR]!++;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/* Blessed weapon? */
|
|
589
|
+
if (art.flags.has(OF.BLESSED)) {
|
|
590
|
+
randartLog(`Adding 1 for blessed weapon\n`);
|
|
591
|
+
data.artProbs[ART_IDX.MELEE_BLESS]!++;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/* See invisible? */
|
|
595
|
+
if (art.flags.has(OF.SEE_INVIS)) {
|
|
596
|
+
randartLog(`Adding 1 for see invisible (weapon case)\n`);
|
|
597
|
+
data.artProbs[ART_IDX.MELEE_SINV]!++;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/* Tunnelling ability. */
|
|
601
|
+
if ((art.modifiers[OBJ_MOD.TUNNEL] ?? 0) > 0) {
|
|
602
|
+
randartLog(`Adding 1 for tunnelling bonus.\n`);
|
|
603
|
+
data.artProbs[ART_IDX.MELEE_TUNN]!++;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/* Count brands and slays. */
|
|
607
|
+
if (art.slays) {
|
|
608
|
+
const n = countTrue(art.slays);
|
|
609
|
+
data.artProbs[ART_IDX.MELEE_SLAY]! += n;
|
|
610
|
+
randartLogf(() => `Adding ${n} for slays\n`);
|
|
611
|
+
}
|
|
612
|
+
if (art.brands) {
|
|
613
|
+
const n = countTrue(art.brands);
|
|
614
|
+
data.artProbs[ART_IDX.MELEE_BRAND]! += n;
|
|
615
|
+
randartLogf(() => `Adding ${n} for brands\n`);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* count_bow_abilities (obj-randart.c L444): count combat abilities on bows.
|
|
621
|
+
*/
|
|
622
|
+
export function countBowAbilities(
|
|
623
|
+
reg: ObjRegistry,
|
|
624
|
+
art: Artifact,
|
|
625
|
+
data: ArtifactSetData,
|
|
626
|
+
): void {
|
|
627
|
+
const kind = reg.lookupKind(art.tval, art.sval);
|
|
628
|
+
if (!kind) return;
|
|
629
|
+
const minToH = rvMinimise(kind.toH);
|
|
630
|
+
const minToD = rvMinimise(kind.toD);
|
|
631
|
+
const minToA = rvMinimise(kind.toA);
|
|
632
|
+
|
|
633
|
+
/* To-hit. */
|
|
634
|
+
let bonus = Math.trunc(
|
|
635
|
+
(art.toH - minToH - data.hitStartval) / data.hitIncrement,
|
|
636
|
+
);
|
|
637
|
+
if (bonus > 0) {
|
|
638
|
+
randartLogf(
|
|
639
|
+
() => `Adding ${bonus} instances of extra to-hit bonus for weapon\n`,
|
|
640
|
+
);
|
|
641
|
+
} else if (bonus < 0) {
|
|
642
|
+
randartLogf(
|
|
643
|
+
() => `Subtracting ${bonus} instances of extra to-hit bonus for weapon\n`,
|
|
644
|
+
);
|
|
645
|
+
}
|
|
646
|
+
data.artProbs[ART_IDX.WEAPON_HIT]! += bonus;
|
|
647
|
+
|
|
648
|
+
/* To-dam. */
|
|
649
|
+
bonus = Math.trunc((art.toD - minToD - data.damStartval) / data.damIncrement);
|
|
650
|
+
/* Plain `else`, as in count_weapon_abilities: the to-dam arm has no `< 0`
|
|
651
|
+
* test either here (obj-randart.c L461-466), so a bonus of exactly 0 logs
|
|
652
|
+
* "Subtracting 0". The to-hit arm above DOES have one. */
|
|
653
|
+
if (bonus > 0) {
|
|
654
|
+
randartLogf(
|
|
655
|
+
() => `Adding ${bonus} instances of extra to-dam bonus for weapon\n`,
|
|
656
|
+
);
|
|
657
|
+
} else {
|
|
658
|
+
randartLogf(
|
|
659
|
+
() => `Subtracting ${bonus} instances of extra to-dam bonus for weapon\n`,
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
data.artProbs[ART_IDX.WEAPON_DAM]! += bonus;
|
|
663
|
+
|
|
664
|
+
/* Armor class. */
|
|
665
|
+
bonus = Math.trunc((art.toA - minToA - data.acStartval) / data.acIncrement);
|
|
666
|
+
if (bonus > 0) {
|
|
667
|
+
randartLogf(() => `Adding ${bonus} for AC bonus - general\n`);
|
|
668
|
+
data.artProbs[ART_IDX.GEN_AC]! += bonus;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/* Aggravation. */
|
|
672
|
+
if (art.flags.has(OF.AGGRAVATE)) {
|
|
673
|
+
randartLog(`Adding 1 for aggravation - weapon\n`);
|
|
674
|
+
data.artProbs[ART_IDX.WEAPON_AGGR]!++;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/* Do we have more than 1 extra shot? */
|
|
678
|
+
const shots = art.modifiers[OBJ_MOD.SHOTS] ?? 0;
|
|
679
|
+
if (shots > 10) {
|
|
680
|
+
randartLog(`Adding 1 for supercharged shots (more than 1!)\n`);
|
|
681
|
+
data.artProbs[ART_IDX.BOW_SHOTS_SUPER]!++;
|
|
682
|
+
} else if (shots > 0) {
|
|
683
|
+
randartLog(`Adding 1 for extra shots\n`);
|
|
684
|
+
data.artProbs[ART_IDX.BOW_SHOTS]!++;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/* Do we have 3 or more extra might? */
|
|
688
|
+
const might = art.modifiers[OBJ_MOD.MIGHT] ?? 0;
|
|
689
|
+
if (might > 2) {
|
|
690
|
+
randartLog(`Adding 1 for supercharged might (3 or more!)\n`);
|
|
691
|
+
data.artProbs[ART_IDX.BOW_MIGHT_SUPER]!++;
|
|
692
|
+
} else if (might > 0) {
|
|
693
|
+
randartLog(`Adding 1 for extra might\n`);
|
|
694
|
+
data.artProbs[ART_IDX.BOW_MIGHT]!++;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/* Count brands and slays. */
|
|
698
|
+
if (art.slays) {
|
|
699
|
+
const n = countTrue(art.slays);
|
|
700
|
+
data.artProbs[ART_IDX.BOW_SLAY]! += n;
|
|
701
|
+
randartLogf(() => `Adding ${n} for slays\n`);
|
|
702
|
+
}
|
|
703
|
+
if (art.brands) {
|
|
704
|
+
const n = countTrue(art.brands);
|
|
705
|
+
data.artProbs[ART_IDX.BOW_BRAND]! += n;
|
|
706
|
+
randartLogf(() => `Adding ${n} for brands\n`);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* count_nonweapon_abilities (obj-randart.c L516): handle nonweapon combat
|
|
712
|
+
* abilities.
|
|
713
|
+
*/
|
|
714
|
+
export function countNonweaponAbilities(
|
|
715
|
+
reg: ObjRegistry,
|
|
716
|
+
art: Artifact,
|
|
717
|
+
data: ArtifactSetData,
|
|
718
|
+
): void {
|
|
719
|
+
const kind = reg.lookupKind(art.tval, art.sval);
|
|
720
|
+
if (!kind) return;
|
|
721
|
+
const toHit = art.toH - rvMinimise(kind.toH);
|
|
722
|
+
const toDam = art.toD - rvMinimise(kind.toD);
|
|
723
|
+
const toA = art.toA - rvMinimise(kind.toA) - data.acStartval;
|
|
724
|
+
let bonus = Math.trunc(toA / data.acIncrement);
|
|
725
|
+
|
|
726
|
+
/* Armor class. */
|
|
727
|
+
if (bonus > 0) {
|
|
728
|
+
if (art.toA > 20) {
|
|
729
|
+
randartLogf(() => `Adding ${bonus} for supercharged AC\n`);
|
|
730
|
+
data.artProbs[ART_IDX.GEN_AC_SUPER]!++;
|
|
731
|
+
} else if (art.tval === TV.BOOTS) {
|
|
732
|
+
randartLogf(() => `Adding ${bonus} for AC bonus - boots\n`);
|
|
733
|
+
data.artProbs[ART_IDX.BOOT_AC]! += bonus;
|
|
734
|
+
} else if (art.tval === TV.GLOVES) {
|
|
735
|
+
randartLogf(() => `Adding ${bonus} for AC bonus - gloves\n`);
|
|
736
|
+
data.artProbs[ART_IDX.GLOVE_AC]! += bonus;
|
|
737
|
+
} else if (art.tval === TV.HELM || art.tval === TV.CROWN) {
|
|
738
|
+
randartLogf(() => `Adding ${bonus} for AC bonus - hat\n`);
|
|
739
|
+
data.artProbs[ART_IDX.HELM_AC]! += bonus;
|
|
740
|
+
} else if (art.tval === TV.SHIELD) {
|
|
741
|
+
randartLogf(() => `Adding ${bonus} for AC bonus - shield\n`);
|
|
742
|
+
data.artProbs[ART_IDX.SHIELD_AC]! += bonus;
|
|
743
|
+
} else if (art.tval === TV.CLOAK) {
|
|
744
|
+
randartLogf(() => `Adding ${bonus} for AC bonus - cloak\n`);
|
|
745
|
+
data.artProbs[ART_IDX.CLOAK_AC]! += bonus;
|
|
746
|
+
} else if (
|
|
747
|
+
art.tval === TV.SOFT_ARMOR ||
|
|
748
|
+
art.tval === TV.HARD_ARMOR ||
|
|
749
|
+
art.tval === TV.DRAG_ARMOR
|
|
750
|
+
) {
|
|
751
|
+
randartLogf(() => `Adding ${bonus} for AC bonus - body armor\n`);
|
|
752
|
+
data.artProbs[ART_IDX.ARMOR_AC]! += bonus;
|
|
753
|
+
} else {
|
|
754
|
+
randartLogf(() => `Adding ${bonus} for AC bonus - general\n`);
|
|
755
|
+
data.artProbs[ART_IDX.GEN_AC]! += bonus;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
/* To hit and dam bonuses. */
|
|
760
|
+
if (toHit > 0 && toDam > 0) {
|
|
761
|
+
bonus = Math.trunc(
|
|
762
|
+
(toHit + toDam) / (data.hitIncrement + data.damIncrement),
|
|
763
|
+
);
|
|
764
|
+
if (bonus > 0) {
|
|
765
|
+
if (art.tval === TV.GLOVES) {
|
|
766
|
+
randartLogf(
|
|
767
|
+
() =>
|
|
768
|
+
`Adding ${bonus} instances of extra to-hit and to-dam bonus for gloves\n`,
|
|
769
|
+
);
|
|
770
|
+
data.artProbs[ART_IDX.GLOVE_HIT_DAM]! += bonus;
|
|
771
|
+
} else {
|
|
772
|
+
randartLogf(
|
|
773
|
+
() =>
|
|
774
|
+
`Adding ${bonus} instances of extra to-hit and to-dam bonus for non-weapon\n`,
|
|
775
|
+
);
|
|
776
|
+
data.artProbs[ART_IDX.NONWEAPON_HIT_DAM]! += bonus;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
} else if (toHit > 0) {
|
|
780
|
+
bonus = Math.trunc(toHit / data.hitIncrement);
|
|
781
|
+
if (bonus > 0) {
|
|
782
|
+
randartLogf(
|
|
783
|
+
() => `Adding ${bonus} instances of extra to-hit bonus for non-weapon\n`,
|
|
784
|
+
);
|
|
785
|
+
data.artProbs[ART_IDX.NONWEAPON_HIT]! += bonus;
|
|
786
|
+
}
|
|
787
|
+
} else if (toDam > 0) {
|
|
788
|
+
bonus = Math.trunc(toDam / data.damIncrement);
|
|
789
|
+
if (bonus > 0) {
|
|
790
|
+
randartLogf(
|
|
791
|
+
() => `Adding ${bonus} instances of extra to-dam bonus for non-weapon\n`,
|
|
792
|
+
);
|
|
793
|
+
data.artProbs[ART_IDX.NONWEAPON_DAM]! += bonus;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
/* Check weight - is it different from normal? */
|
|
798
|
+
if (art.weight !== kind.weight) {
|
|
799
|
+
randartLog(`Adding 1 for unusual weight.\n`);
|
|
800
|
+
data.artProbs[ART_IDX.ALLARMOR_WEIGHT]!++;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
/* Aggravation. */
|
|
804
|
+
if (art.flags.has(OF.AGGRAVATE)) {
|
|
805
|
+
randartLog(`Adding 1 for aggravation - nonweapon\n`);
|
|
806
|
+
data.artProbs[ART_IDX.NONWEAPON_AGGR]!++;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/* Count brands and slays. */
|
|
810
|
+
if (art.slays) {
|
|
811
|
+
const n = countTrue(art.slays);
|
|
812
|
+
data.artProbs[ART_IDX.NONWEAPON_SLAY]! += n;
|
|
813
|
+
randartLogf(() => `Adding ${n} for slays\n`);
|
|
814
|
+
}
|
|
815
|
+
if (art.brands) {
|
|
816
|
+
const n = countTrue(art.brands);
|
|
817
|
+
data.artProbs[ART_IDX.NONWEAPON_BRAND]! += n;
|
|
818
|
+
randartLogf(() => `Adding ${n} for brands\n`);
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
/* Blows. */
|
|
822
|
+
if ((art.modifiers[OBJ_MOD.BLOWS] ?? 0) > 0) {
|
|
823
|
+
randartLog(`Adding 1 for extra blows on nonweapon\n`);
|
|
824
|
+
data.artProbs[ART_IDX.NONWEAPON_BLOWS]!++;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
/* Shots. */
|
|
828
|
+
if ((art.modifiers[OBJ_MOD.SHOTS] ?? 0) > 0) {
|
|
829
|
+
randartLog(`Adding 1 for extra shots on nonweapon\n`);
|
|
830
|
+
data.artProbs[ART_IDX.NONWEAPON_SHOTS]!++;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
/* Tunnelling ability. */
|
|
834
|
+
if ((art.modifiers[OBJ_MOD.TUNNEL] ?? 0) > 0) {
|
|
835
|
+
randartLog(`Adding 1 for tunnelling bonus - general.\n`);
|
|
836
|
+
data.artProbs[ART_IDX.GEN_TUNN]!++;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* count_modifiers (obj-randart.c L630): count stat and other modifier bonuses.
|
|
842
|
+
*/
|
|
843
|
+
export function countModifiers(art: Artifact, data: ArtifactSetData): void {
|
|
844
|
+
let num = 0;
|
|
845
|
+
|
|
846
|
+
/* Stat bonuses. Add up the number of individual bonuses. */
|
|
847
|
+
if ((art.modifiers[OBJ_MOD.STR] ?? 0) > 0) num++;
|
|
848
|
+
if ((art.modifiers[OBJ_MOD.INT] ?? 0) > 0) num++;
|
|
849
|
+
if ((art.modifiers[OBJ_MOD.WIS] ?? 0) > 0) num++;
|
|
850
|
+
if ((art.modifiers[OBJ_MOD.DEX] ?? 0) > 0) num++;
|
|
851
|
+
if ((art.modifiers[OBJ_MOD.CON] ?? 0) > 0) num++;
|
|
852
|
+
|
|
853
|
+
/* Handle a few special cases separately. */
|
|
854
|
+
if (
|
|
855
|
+
(art.tval === TV.HELM || art.tval === TV.CROWN) &&
|
|
856
|
+
((art.modifiers[OBJ_MOD.WIS] ?? 0) > 0 ||
|
|
857
|
+
(art.modifiers[OBJ_MOD.INT] ?? 0) > 0)
|
|
858
|
+
) {
|
|
859
|
+
if ((art.modifiers[OBJ_MOD.WIS] ?? 0) > 0) {
|
|
860
|
+
randartLog("Adding 1 for WIS bonus on headgear.\n");
|
|
861
|
+
data.artProbs[ART_IDX.HELM_WIS]!++;
|
|
862
|
+
num--;
|
|
863
|
+
}
|
|
864
|
+
if ((art.modifiers[OBJ_MOD.INT] ?? 0) > 0) {
|
|
865
|
+
randartLog("Adding 1 for INT bonus on headgear.\n");
|
|
866
|
+
data.artProbs[ART_IDX.HELM_INT]!++;
|
|
867
|
+
num--;
|
|
868
|
+
}
|
|
869
|
+
} else if (
|
|
870
|
+
(art.tval === TV.SOFT_ARMOR ||
|
|
871
|
+
art.tval === TV.HARD_ARMOR ||
|
|
872
|
+
art.tval === TV.DRAG_ARMOR) &&
|
|
873
|
+
(art.modifiers[OBJ_MOD.CON] ?? 0) > 0
|
|
874
|
+
) {
|
|
875
|
+
randartLog("Adding 1 for CON bonus on body armor.\n");
|
|
876
|
+
data.artProbs[ART_IDX.ARMOR_CON]!++;
|
|
877
|
+
num--;
|
|
878
|
+
} else if (art.tval === TV.GLOVES && (art.modifiers[OBJ_MOD.DEX] ?? 0) > 0) {
|
|
879
|
+
randartLog("Adding 1 for DEX bonus on gloves.\n");
|
|
880
|
+
data.artProbs[ART_IDX.GLOVE_DEX]!++;
|
|
881
|
+
num--;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/* Now the general case. */
|
|
885
|
+
if (num > 0) {
|
|
886
|
+
randartLogf(() => `Adding ${num} for stat bonuses - general.\n`);
|
|
887
|
+
data.artProbs[ART_IDX.GEN_STAT]! += num;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
/* Handle stealth, including a couple of special cases. */
|
|
891
|
+
if ((art.modifiers[OBJ_MOD.STEALTH] ?? 0) > 0) {
|
|
892
|
+
if (art.tval === TV.BOOTS) {
|
|
893
|
+
randartLog("Adding 1 for stealth bonus on boots.\n");
|
|
894
|
+
data.artProbs[ART_IDX.BOOT_STEALTH]!++;
|
|
895
|
+
} else if (art.tval === TV.CLOAK) {
|
|
896
|
+
randartLog("Adding 1 for stealth bonus on cloak.\n");
|
|
897
|
+
data.artProbs[ART_IDX.CLOAK_STEALTH]!++;
|
|
898
|
+
} else if (
|
|
899
|
+
art.tval === TV.SOFT_ARMOR ||
|
|
900
|
+
art.tval === TV.HARD_ARMOR ||
|
|
901
|
+
art.tval === TV.DRAG_ARMOR
|
|
902
|
+
) {
|
|
903
|
+
randartLog("Adding 1 for stealth bonus on armor.\n");
|
|
904
|
+
data.artProbs[ART_IDX.ARMOR_STEALTH]!++;
|
|
905
|
+
} else {
|
|
906
|
+
randartLog("Adding 1 for stealth bonus - general.\n");
|
|
907
|
+
data.artProbs[ART_IDX.GEN_STEALTH]!++;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
/* Searching bonus - fully generic. */
|
|
912
|
+
if ((art.modifiers[OBJ_MOD.SEARCH] ?? 0) > 0) {
|
|
913
|
+
randartLog("Adding 1 for search bonus - general.\n");
|
|
914
|
+
data.artProbs[ART_IDX.GEN_SEARCH]!++;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
/* Infravision bonus - fully generic. */
|
|
918
|
+
if ((art.modifiers[OBJ_MOD.INFRA] ?? 0) > 0) {
|
|
919
|
+
randartLog("Adding 1 for infravision bonus - general.\n");
|
|
920
|
+
data.artProbs[ART_IDX.GEN_INFRA]!++;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
/* Damage reduction bonus - fully generic. */
|
|
924
|
+
if ((art.modifiers[OBJ_MOD.DAM_RED] ?? 0) > 0) {
|
|
925
|
+
randartLog("Adding 1 for damage reduction bonus - general.\n");
|
|
926
|
+
data.artProbs[ART_IDX.GEN_DAM_RED]!++;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/* Moves bonus. */
|
|
930
|
+
if ((art.modifiers[OBJ_MOD.MOVES] ?? 0) > 0) {
|
|
931
|
+
if (art.tval === TV.BOOTS) {
|
|
932
|
+
randartLog("Adding 1 for moves bonus on boots.\n");
|
|
933
|
+
data.artProbs[ART_IDX.BOOT_MOVES]!++;
|
|
934
|
+
} else {
|
|
935
|
+
randartLog("Adding 1 for moves bonus - general.\n");
|
|
936
|
+
data.artProbs[ART_IDX.GEN_MOVES]!++;
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/* Speed - boots handled separately, supercharge shares its frequency. */
|
|
941
|
+
const speed = art.modifiers[OBJ_MOD.SPEED] ?? 0;
|
|
942
|
+
if (speed > 0) {
|
|
943
|
+
if (speed > 7) {
|
|
944
|
+
randartLog("Adding 1 for supercharged speed bonus!\n");
|
|
945
|
+
data.artProbs[ART_IDX.GEN_SPEED_SUPER]!++;
|
|
946
|
+
} else if (art.tval === TV.BOOTS) {
|
|
947
|
+
randartLog("Adding 1 for normal speed bonus on boots.\n");
|
|
948
|
+
data.artProbs[ART_IDX.BOOT_SPEED]!++;
|
|
949
|
+
} else {
|
|
950
|
+
randartLog("Adding 1 for normal speed bonus - general.\n");
|
|
951
|
+
data.artProbs[ART_IDX.GEN_SPEED]!++;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
/* Permanent light. */
|
|
956
|
+
if ((art.modifiers[OBJ_MOD.LIGHT] ?? 0) > 0) {
|
|
957
|
+
randartLog("Adding 1 for light radius - general.\n");
|
|
958
|
+
data.artProbs[ART_IDX.GEN_LIGHT]!++;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* count_low_resists (obj-randart.c L764): count low resists and immunities.
|
|
964
|
+
*/
|
|
965
|
+
export function countLowResists(art: Artifact, data: ArtifactSetData): void {
|
|
966
|
+
let num = 0;
|
|
967
|
+
|
|
968
|
+
/* Count up immunities for this item, if any. */
|
|
969
|
+
if ((art.elInfo[ELEM.ACID] as ElementInfo).resLevel === 3) num++;
|
|
970
|
+
if ((art.elInfo[ELEM.ELEC] as ElementInfo).resLevel === 3) num++;
|
|
971
|
+
if ((art.elInfo[ELEM.FIRE] as ElementInfo).resLevel === 3) num++;
|
|
972
|
+
if ((art.elInfo[ELEM.COLD] as ElementInfo).resLevel === 3) num++;
|
|
973
|
+
|
|
974
|
+
randartLogf(() => `Adding ${num} for immunities.\n`);
|
|
975
|
+
data.artProbs[ART_IDX.GEN_IMMUNE]! += num;
|
|
976
|
+
|
|
977
|
+
/* Count up low resists (not the type, just the number). */
|
|
978
|
+
num = 0;
|
|
979
|
+
if ((art.elInfo[ELEM.ACID] as ElementInfo).resLevel === 1) num++;
|
|
980
|
+
if ((art.elInfo[ELEM.ELEC] as ElementInfo).resLevel === 1) num++;
|
|
981
|
+
if ((art.elInfo[ELEM.FIRE] as ElementInfo).resLevel === 1) num++;
|
|
982
|
+
if ((art.elInfo[ELEM.COLD] as ElementInfo).resLevel === 1) num++;
|
|
983
|
+
|
|
984
|
+
if (num) {
|
|
985
|
+
if (art.tval === TV.SHIELD) {
|
|
986
|
+
randartLogf(() => `Adding ${num} for low resists on shield.\n`);
|
|
987
|
+
data.artProbs[ART_IDX.SHIELD_LRES]! += num;
|
|
988
|
+
} else if (
|
|
989
|
+
art.tval === TV.SOFT_ARMOR ||
|
|
990
|
+
art.tval === TV.HARD_ARMOR ||
|
|
991
|
+
art.tval === TV.DRAG_ARMOR
|
|
992
|
+
) {
|
|
993
|
+
if (num === 4) {
|
|
994
|
+
randartLog("Adding 1 for ALL LOW RESISTS on body armor.\n");
|
|
995
|
+
data.artProbs[ART_IDX.ARMOR_ALLRES]!++;
|
|
996
|
+
} else {
|
|
997
|
+
randartLogf(() => `Adding ${num} for low resists on body armor.\n`);
|
|
998
|
+
data.artProbs[ART_IDX.ARMOR_LRES]! += num;
|
|
999
|
+
}
|
|
1000
|
+
} else {
|
|
1001
|
+
randartLogf(() => `Adding ${num} for low resists - general.\n`);
|
|
1002
|
+
data.artProbs[ART_IDX.GEN_LRES]! += num;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
/**
|
|
1008
|
+
* count_high_resists (obj-randart.c L816): count high resists and protections.
|
|
1009
|
+
*/
|
|
1010
|
+
export function countHighResists(art: Artifact, data: ArtifactSetData): void {
|
|
1011
|
+
let num = 0;
|
|
1012
|
+
|
|
1013
|
+
/* Body armor: count all high resists as an aggregate first. */
|
|
1014
|
+
if (
|
|
1015
|
+
art.tval === TV.SOFT_ARMOR ||
|
|
1016
|
+
art.tval === TV.HARD_ARMOR ||
|
|
1017
|
+
art.tval === TV.DRAG_ARMOR
|
|
1018
|
+
) {
|
|
1019
|
+
if ((art.elInfo[ELEM.POIS] as ElementInfo).resLevel === 1) num++;
|
|
1020
|
+
if (art.flags.has(OF.PROT_FEAR)) num++;
|
|
1021
|
+
if ((art.elInfo[ELEM.LIGHT] as ElementInfo).resLevel === 1) num++;
|
|
1022
|
+
if ((art.elInfo[ELEM.DARK] as ElementInfo).resLevel === 1) num++;
|
|
1023
|
+
if (art.flags.has(OF.PROT_BLIND)) num++;
|
|
1024
|
+
if (art.flags.has(OF.PROT_CONF)) num++;
|
|
1025
|
+
if ((art.elInfo[ELEM.SOUND] as ElementInfo).resLevel === 1) num++;
|
|
1026
|
+
if ((art.elInfo[ELEM.SHARD] as ElementInfo).resLevel === 1) num++;
|
|
1027
|
+
if ((art.elInfo[ELEM.NEXUS] as ElementInfo).resLevel === 1) num++;
|
|
1028
|
+
if ((art.elInfo[ELEM.NETHER] as ElementInfo).resLevel === 1) num++;
|
|
1029
|
+
if ((art.elInfo[ELEM.CHAOS] as ElementInfo).resLevel === 1) num++;
|
|
1030
|
+
if ((art.elInfo[ELEM.DISEN] as ElementInfo).resLevel === 1) num++;
|
|
1031
|
+
if (art.flags.has(OF.PROT_STUN)) num++;
|
|
1032
|
+
randartLogf(() => `Adding ${num} for high resists on body armor.\n`);
|
|
1033
|
+
data.artProbs[ART_IDX.ARMOR_HRES]! += num;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
/* Now do the high resists individually. */
|
|
1037
|
+
if ((art.elInfo[ELEM.POIS] as ElementInfo).resLevel === 1) {
|
|
1038
|
+
randartLog("Adding 1 for resist poison - general.\n");
|
|
1039
|
+
data.artProbs[ART_IDX.GEN_RPOIS]!++;
|
|
1040
|
+
}
|
|
1041
|
+
if (art.flags.has(OF.PROT_FEAR)) {
|
|
1042
|
+
randartLog("Adding 1 for resist fear - general.\n");
|
|
1043
|
+
data.artProbs[ART_IDX.GEN_RFEAR]!++;
|
|
1044
|
+
}
|
|
1045
|
+
if ((art.elInfo[ELEM.LIGHT] as ElementInfo).resLevel === 1) {
|
|
1046
|
+
randartLog("Adding 1 for resist light - general.\n");
|
|
1047
|
+
data.artProbs[ART_IDX.GEN_RLIGHT]!++;
|
|
1048
|
+
}
|
|
1049
|
+
if ((art.elInfo[ELEM.DARK] as ElementInfo).resLevel === 1) {
|
|
1050
|
+
randartLog("Adding 1 for resist dark - general.\n");
|
|
1051
|
+
data.artProbs[ART_IDX.GEN_RDARK]!++;
|
|
1052
|
+
}
|
|
1053
|
+
if (art.flags.has(OF.PROT_BLIND)) {
|
|
1054
|
+
if (art.tval === TV.HELM || art.tval === TV.CROWN) {
|
|
1055
|
+
randartLog("Adding 1 for resist blindness - headgear.\n");
|
|
1056
|
+
data.artProbs[ART_IDX.HELM_RBLIND]!++;
|
|
1057
|
+
} else {
|
|
1058
|
+
randartLog("Adding 1 for resist blindness - general.\n");
|
|
1059
|
+
data.artProbs[ART_IDX.GEN_RBLIND]!++;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
if (art.flags.has(OF.PROT_CONF)) {
|
|
1063
|
+
randartLog("Adding 1 for resist confusion - general.\n");
|
|
1064
|
+
data.artProbs[ART_IDX.GEN_RCONF]!++;
|
|
1065
|
+
}
|
|
1066
|
+
if ((art.elInfo[ELEM.SOUND] as ElementInfo).resLevel === 1) {
|
|
1067
|
+
randartLog("Adding 1 for resist sound - general.\n");
|
|
1068
|
+
data.artProbs[ART_IDX.GEN_RSOUND]!++;
|
|
1069
|
+
}
|
|
1070
|
+
if ((art.elInfo[ELEM.SHARD] as ElementInfo).resLevel === 1) {
|
|
1071
|
+
randartLog("Adding 1 for resist shards - general.\n");
|
|
1072
|
+
data.artProbs[ART_IDX.GEN_RSHARD]!++;
|
|
1073
|
+
}
|
|
1074
|
+
if ((art.elInfo[ELEM.NEXUS] as ElementInfo).resLevel === 1) {
|
|
1075
|
+
randartLog("Adding 1 for resist nexus - general.\n");
|
|
1076
|
+
data.artProbs[ART_IDX.GEN_RNEXUS]!++;
|
|
1077
|
+
}
|
|
1078
|
+
if ((art.elInfo[ELEM.NETHER] as ElementInfo).resLevel === 1) {
|
|
1079
|
+
randartLog("Adding 1 for resist nether - general.\n");
|
|
1080
|
+
data.artProbs[ART_IDX.GEN_RNETHER]!++;
|
|
1081
|
+
}
|
|
1082
|
+
if ((art.elInfo[ELEM.CHAOS] as ElementInfo).resLevel === 1) {
|
|
1083
|
+
randartLog("Adding 1 for resist chaos - general.\n");
|
|
1084
|
+
data.artProbs[ART_IDX.GEN_RCHAOS]!++;
|
|
1085
|
+
}
|
|
1086
|
+
if ((art.elInfo[ELEM.DISEN] as ElementInfo).resLevel === 1) {
|
|
1087
|
+
randartLog("Adding 1 for resist disenchantment - general.\n");
|
|
1088
|
+
data.artProbs[ART_IDX.GEN_RDISEN]!++;
|
|
1089
|
+
}
|
|
1090
|
+
if (art.flags.has(OF.PROT_STUN)) {
|
|
1091
|
+
randartLog("Adding 1 for res_stun - general.\n");
|
|
1092
|
+
data.artProbs[ART_IDX.GEN_PSTUN]!++;
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
/**
|
|
1097
|
+
* count_abilities (obj-randart.c L943): general abilities, adding some to a
|
|
1098
|
+
* specific item-type tally depending on the base item.
|
|
1099
|
+
*/
|
|
1100
|
+
export function countAbilities(
|
|
1101
|
+
reg: ObjRegistry,
|
|
1102
|
+
art: Artifact,
|
|
1103
|
+
data: ArtifactSetData,
|
|
1104
|
+
): void {
|
|
1105
|
+
const kind = reg.lookupKind(art.tval, art.sval);
|
|
1106
|
+
|
|
1107
|
+
/* Sustains. */
|
|
1108
|
+
if (
|
|
1109
|
+
art.flags.has(OF.SUST_STR) ||
|
|
1110
|
+
art.flags.has(OF.SUST_INT) ||
|
|
1111
|
+
art.flags.has(OF.SUST_WIS) ||
|
|
1112
|
+
art.flags.has(OF.SUST_DEX) ||
|
|
1113
|
+
art.flags.has(OF.SUST_CON)
|
|
1114
|
+
) {
|
|
1115
|
+
let num = 0;
|
|
1116
|
+
if (art.flags.has(OF.SUST_STR)) num++;
|
|
1117
|
+
if (art.flags.has(OF.SUST_INT)) num++;
|
|
1118
|
+
if (art.flags.has(OF.SUST_WIS)) num++;
|
|
1119
|
+
if (art.flags.has(OF.SUST_DEX)) num++;
|
|
1120
|
+
if (art.flags.has(OF.SUST_CON)) num++;
|
|
1121
|
+
randartLogf(() => `Adding ${num} for stat sustains.\n`);
|
|
1122
|
+
data.artProbs[ART_IDX.GEN_SUST]! += num;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
/* Free action - handle gloves separately. */
|
|
1126
|
+
if (art.flags.has(OF.FREE_ACT)) {
|
|
1127
|
+
if (art.tval === TV.GLOVES) {
|
|
1128
|
+
randartLog("Adding 1 for free action on gloves.\n");
|
|
1129
|
+
data.artProbs[ART_IDX.GLOVE_FA]!++;
|
|
1130
|
+
} else {
|
|
1131
|
+
randartLog("Adding 1 for free action - general.\n");
|
|
1132
|
+
data.artProbs[ART_IDX.GEN_FA]!++;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
/* Hold life - do body armor separately. */
|
|
1137
|
+
if (art.flags.has(OF.HOLD_LIFE)) {
|
|
1138
|
+
if (
|
|
1139
|
+
art.tval === TV.SOFT_ARMOR ||
|
|
1140
|
+
art.tval === TV.HARD_ARMOR ||
|
|
1141
|
+
art.tval === TV.DRAG_ARMOR
|
|
1142
|
+
) {
|
|
1143
|
+
randartLog("Adding 1 for hold life on armor.\n");
|
|
1144
|
+
data.artProbs[ART_IDX.ARMOR_HLIFE]!++;
|
|
1145
|
+
} else {
|
|
1146
|
+
randartLog("Adding 1 for hold life - general.\n");
|
|
1147
|
+
data.artProbs[ART_IDX.GEN_HLIFE]!++;
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
/* Feather fall - handle boots separately. */
|
|
1152
|
+
if (art.flags.has(OF.FEATHER)) {
|
|
1153
|
+
if (art.tval === TV.BOOTS) {
|
|
1154
|
+
randartLog("Adding 1 for feather fall on boots.\n");
|
|
1155
|
+
data.artProbs[ART_IDX.BOOT_FEATHER]!++;
|
|
1156
|
+
} else {
|
|
1157
|
+
randartLog("Adding 1 for feather fall - general.\n");
|
|
1158
|
+
data.artProbs[ART_IDX.GEN_FEATHER]!++;
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
/* See invisible - do helms/crowns separately (weapons already handled). */
|
|
1163
|
+
if (art.flags.has(OF.SEE_INVIS)) {
|
|
1164
|
+
if (
|
|
1165
|
+
!(
|
|
1166
|
+
art.tval === TV.DIGGING ||
|
|
1167
|
+
art.tval === TV.HAFTED ||
|
|
1168
|
+
art.tval === TV.POLEARM ||
|
|
1169
|
+
art.tval === TV.SWORD
|
|
1170
|
+
)
|
|
1171
|
+
) {
|
|
1172
|
+
if (art.tval === TV.HELM || art.tval === TV.CROWN) {
|
|
1173
|
+
randartLog("Adding 1 for see invisible - headgear.\n");
|
|
1174
|
+
data.artProbs[ART_IDX.HELM_SINV]!++;
|
|
1175
|
+
} else {
|
|
1176
|
+
randartLog("Adding 1 for see invisible - general.\n");
|
|
1177
|
+
data.artProbs[ART_IDX.GEN_SINV]!++;
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
/* ESP - handle helms/crowns separately. */
|
|
1183
|
+
if (art.flags.has(OF.TELEPATHY)) {
|
|
1184
|
+
if (art.tval === TV.HELM || art.tval === TV.CROWN) {
|
|
1185
|
+
randartLog("Adding 1 for ESP on headgear.\n");
|
|
1186
|
+
data.artProbs[ART_IDX.HELM_ESP]!++;
|
|
1187
|
+
} else {
|
|
1188
|
+
randartLog("Adding 1 for ESP - general.\n");
|
|
1189
|
+
data.artProbs[ART_IDX.GEN_ESP]!++;
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
/* Slow digestion - generic. */
|
|
1194
|
+
if (art.flags.has(OF.SLOW_DIGEST)) {
|
|
1195
|
+
randartLog("Adding 1 for slow digestion - general.\n");
|
|
1196
|
+
data.artProbs[ART_IDX.GEN_SDIG]!++;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
/* Regeneration - generic. */
|
|
1200
|
+
if (art.flags.has(OF.REGEN)) {
|
|
1201
|
+
randartLog("Adding 1 for regeneration - general.\n");
|
|
1202
|
+
data.artProbs[ART_IDX.GEN_REGEN]!++;
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
/* Trap immunity - handle boots separately. */
|
|
1206
|
+
if (art.flags.has(OF.TRAP_IMMUNE)) {
|
|
1207
|
+
if (art.tval === TV.BOOTS) {
|
|
1208
|
+
randartLog("Adding 1 for trap immunity on boots.\n");
|
|
1209
|
+
data.artProbs[ART_IDX.BOOT_TRAP_IMM]!++;
|
|
1210
|
+
} else {
|
|
1211
|
+
randartLog("Adding 1 for trap immunity - general.\n");
|
|
1212
|
+
data.artProbs[ART_IDX.GEN_TRAP_IMM]!++;
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
/* Activation. */
|
|
1217
|
+
if (art.activation || kind?.activation) {
|
|
1218
|
+
randartLog("Adding 1 for activation.\n");
|
|
1219
|
+
data.artProbs[ART_IDX.GEN_ACTIV]!++;
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
/* ------------------------------------------------------------------ */
|
|
1224
|
+
/* collect_artifact_data (obj-randart.c L1059) */
|
|
1225
|
+
/* ------------------------------------------------------------------ */
|
|
1226
|
+
|
|
1227
|
+
/**
|
|
1228
|
+
* collect_artifact_data (obj-randart.c L1059): parse the standard artifacts and
|
|
1229
|
+
* count up the frequencies of the various abilities.
|
|
1230
|
+
*/
|
|
1231
|
+
export function collectArtifactCounts(
|
|
1232
|
+
reg: ObjRegistry,
|
|
1233
|
+
arts: readonly (Artifact | null)[],
|
|
1234
|
+
data: ArtifactSetData,
|
|
1235
|
+
): void {
|
|
1236
|
+
const aMax = arts.length;
|
|
1237
|
+
|
|
1238
|
+
for (let i = 0; i < aMax; i++) {
|
|
1239
|
+
const art = arts[i] ?? null;
|
|
1240
|
+
|
|
1241
|
+
/* obj-randart.c:1066-1067 logs the index BEFORE any skip, so a cursed,
|
|
1242
|
+
* tval-0 or absent entry still prints its line. Upstream reads a_info[i]
|
|
1243
|
+
* out of a dense array and never has a null to guard, so the port's own
|
|
1244
|
+
* null check has to come after this to keep the counts aligned. */
|
|
1245
|
+
randartLogf(() => `Current artifact index is ${i}\n`);
|
|
1246
|
+
if (!art) continue;
|
|
1247
|
+
|
|
1248
|
+
/* Don't parse cursed or null items. */
|
|
1249
|
+
if ((data.basePower[i] ?? 0) < 0 || art.tval === 0) continue;
|
|
1250
|
+
|
|
1251
|
+
const kind = reg.lookupKind(art.tval, art.sval);
|
|
1252
|
+
if (!kind) continue;
|
|
1253
|
+
|
|
1254
|
+
/* Special cases -- don't parse these! */
|
|
1255
|
+
if (art.name.includes("The One Ring") || kind.kindFlags.has(KF.QUEST_ART)) {
|
|
1256
|
+
continue;
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
/* Add the base item tval to the tv_probs array. */
|
|
1260
|
+
data.tvProbs[kind.tval] = (data.tvProbs[kind.tval] ?? 0) + 1;
|
|
1261
|
+
randartLogf(() => `Base item is ${kind.kidx}\n`);
|
|
1262
|
+
|
|
1263
|
+
/* Count combat abilities broken up by type. */
|
|
1264
|
+
if (
|
|
1265
|
+
art.tval === TV.DIGGING ||
|
|
1266
|
+
art.tval === TV.HAFTED ||
|
|
1267
|
+
art.tval === TV.POLEARM ||
|
|
1268
|
+
art.tval === TV.SWORD
|
|
1269
|
+
) {
|
|
1270
|
+
countWeaponAbilities(reg, art, data);
|
|
1271
|
+
} else if (art.tval === TV.BOW) {
|
|
1272
|
+
countBowAbilities(reg, art, data);
|
|
1273
|
+
} else {
|
|
1274
|
+
countNonweaponAbilities(reg, art, data);
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
/* Count other properties. */
|
|
1278
|
+
countModifiers(art, data);
|
|
1279
|
+
countLowResists(art, data);
|
|
1280
|
+
countHighResists(art, data);
|
|
1281
|
+
countAbilities(reg, art, data);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
/* ------------------------------------------------------------------ */
|
|
1286
|
+
/* Frequency rescaling (obj-randart.c L1124-L1265) */
|
|
1287
|
+
/* ------------------------------------------------------------------ */
|
|
1288
|
+
|
|
1289
|
+
/** Rescale one index group by total / denom (integer division, in place). */
|
|
1290
|
+
function rescaleGroup(
|
|
1291
|
+
data: ArtifactSetData,
|
|
1292
|
+
group: readonly number[],
|
|
1293
|
+
denom: number,
|
|
1294
|
+
): void {
|
|
1295
|
+
for (const idx of group) {
|
|
1296
|
+
data.artProbs[idx] = Math.trunc((data.artProbs[idx]! * data.total) / denom);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
/**
|
|
1301
|
+
* rescale_freqs (obj-randart.c L1124): rescale item-dependent ability
|
|
1302
|
+
* frequencies as though the whole set were made of that item type, so
|
|
1303
|
+
* dependent and independent abilities become comparable.
|
|
1304
|
+
*/
|
|
1305
|
+
export function rescaleFreqs(data: ArtifactSetData): void {
|
|
1306
|
+
/* Bow-only abilities. */
|
|
1307
|
+
rescaleGroup(data, artIdxBow, data.bowTotal);
|
|
1308
|
+
|
|
1309
|
+
/* All weapon abilities. */
|
|
1310
|
+
rescaleGroup(data, artIdxWeapon, data.bowTotal + data.meleeTotal);
|
|
1311
|
+
|
|
1312
|
+
/* Corresponding non-weapon abilities. */
|
|
1313
|
+
const nonweaponDenom = data.total - data.meleeTotal - data.bowTotal;
|
|
1314
|
+
rescaleGroup(data, artIdxNonweapon, nonweaponDenom);
|
|
1315
|
+
|
|
1316
|
+
/* All melee weapon abilities. */
|
|
1317
|
+
rescaleGroup(data, artIdxMelee, data.meleeTotal);
|
|
1318
|
+
|
|
1319
|
+
/* All general armor abilities. */
|
|
1320
|
+
const allArmorDenom =
|
|
1321
|
+
data.armorTotal +
|
|
1322
|
+
data.bootTotal +
|
|
1323
|
+
data.shieldTotal +
|
|
1324
|
+
data.headgearTotal +
|
|
1325
|
+
data.cloakTotal +
|
|
1326
|
+
data.gloveTotal;
|
|
1327
|
+
rescaleGroup(data, artIdxAllarmor, allArmorDenom);
|
|
1328
|
+
|
|
1329
|
+
/* Boots. */
|
|
1330
|
+
rescaleGroup(data, artIdxBoot, data.bootTotal);
|
|
1331
|
+
/* Gloves. */
|
|
1332
|
+
rescaleGroup(data, artIdxGlove, data.gloveTotal);
|
|
1333
|
+
/* Headgear. */
|
|
1334
|
+
rescaleGroup(data, artIdxHeadgear, data.headgearTotal);
|
|
1335
|
+
/* Shields. */
|
|
1336
|
+
rescaleGroup(data, artIdxShield, data.shieldTotal);
|
|
1337
|
+
/* Cloaks. */
|
|
1338
|
+
rescaleGroup(data, artIdxCloak, data.cloakTotal);
|
|
1339
|
+
/* Body armor. */
|
|
1340
|
+
rescaleGroup(data, artIdxArmor, data.armorTotal);
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
/**
|
|
1344
|
+
* adjust_freqs (obj-randart.c L1214): enforce minimum frequencies for
|
|
1345
|
+
* abilities that might be missing from the standard set, and halve the
|
|
1346
|
+
* aggravation frequencies (which are counted twice).
|
|
1347
|
+
*/
|
|
1348
|
+
export function adjustFreqs(data: ArtifactSetData): void {
|
|
1349
|
+
const atLeast = (idx: number, min: number): void => {
|
|
1350
|
+
if (data.artProbs[idx]! < min) data.artProbs[idx] = min;
|
|
1351
|
+
};
|
|
1352
|
+
|
|
1353
|
+
atLeast(ART_IDX.GEN_RFEAR, 5);
|
|
1354
|
+
atLeast(ART_IDX.MELEE_DICE_SUPER, 5);
|
|
1355
|
+
atLeast(ART_IDX.BOW_SHOTS_SUPER, 5);
|
|
1356
|
+
atLeast(ART_IDX.BOW_MIGHT_SUPER, 5);
|
|
1357
|
+
atLeast(ART_IDX.MELEE_BLOWS_SUPER, 5);
|
|
1358
|
+
atLeast(ART_IDX.GEN_SPEED_SUPER, 5);
|
|
1359
|
+
atLeast(ART_IDX.GEN_AC, 5);
|
|
1360
|
+
atLeast(ART_IDX.GEN_TUNN, 5);
|
|
1361
|
+
atLeast(ART_IDX.NONWEAPON_BRAND, 2);
|
|
1362
|
+
atLeast(ART_IDX.NONWEAPON_SLAY, 1);
|
|
1363
|
+
atLeast(ART_IDX.BOW_BRAND, 2);
|
|
1364
|
+
atLeast(ART_IDX.BOW_SLAY, 2);
|
|
1365
|
+
atLeast(ART_IDX.NONWEAPON_BLOWS, 1);
|
|
1366
|
+
atLeast(ART_IDX.NONWEAPON_SHOTS, 1);
|
|
1367
|
+
atLeast(ART_IDX.GEN_AC_SUPER, 5);
|
|
1368
|
+
atLeast(ART_IDX.MELEE_AC, 5);
|
|
1369
|
+
atLeast(ART_IDX.GEN_PSTUN, 3);
|
|
1370
|
+
|
|
1371
|
+
/* Cut aggravation frequencies in half since they're used twice. */
|
|
1372
|
+
data.artProbs[ART_IDX.NONWEAPON_AGGR] = Math.trunc(
|
|
1373
|
+
data.artProbs[ART_IDX.NONWEAPON_AGGR]! / 2,
|
|
1374
|
+
);
|
|
1375
|
+
data.artProbs[ART_IDX.WEAPON_AGGR] = Math.trunc(
|
|
1376
|
+
data.artProbs[ART_IDX.WEAPON_AGGR]! / 2,
|
|
1377
|
+
);
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
/**
|
|
1381
|
+
* parse_frequencies (obj-randart.c L1273): parse the artifacts and write
|
|
1382
|
+
* frequencies of their abilities and base object kinds, building the dynamic
|
|
1383
|
+
* generation probabilities.
|
|
1384
|
+
*/
|
|
1385
|
+
export function parseFrequencies(
|
|
1386
|
+
reg: ObjRegistry,
|
|
1387
|
+
arts: readonly (Artifact | null)[],
|
|
1388
|
+
data: ArtifactSetData,
|
|
1389
|
+
): void {
|
|
1390
|
+
randartLog("\n****** BEGINNING GENERATION OF FREQUENCIES\n\n");
|
|
1391
|
+
|
|
1392
|
+
/* Zero the frequencies for artifact attributes. */
|
|
1393
|
+
for (let i = 0; i < ART_IDX_TOTAL; i++) data.artProbs[i] = 0;
|
|
1394
|
+
|
|
1395
|
+
collectArtifactCounts(reg, arts, data);
|
|
1396
|
+
|
|
1397
|
+
/* Big hack, reduce frequencies of sharp weapons. */
|
|
1398
|
+
for (let i = 0; i < TV_MAX; i++) {
|
|
1399
|
+
if (i === TV.SWORD || i === TV.POLEARM) {
|
|
1400
|
+
data.tvProbs[i] = Math.trunc((data.tvProbs[i]! * 2) / 3);
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
/* "Print out some of the abilities, to make sure that everything's fine"
|
|
1405
|
+
* (obj-randart.c:1295-1301). Both loops run to their FULL extent, before any
|
|
1406
|
+
* rescaling - the pre- and post-rescale dumps are what make the log usable
|
|
1407
|
+
* for comparing two runs. */
|
|
1408
|
+
for (let i = 0; i < ART_IDX_TOTAL; i++) {
|
|
1409
|
+
randartLogf(() => `Frequency of ability ${i}: ${data.artProbs[i]}\n`);
|
|
1410
|
+
}
|
|
1411
|
+
for (let i = 0; i < TV_MAX; i++) {
|
|
1412
|
+
randartLogf(
|
|
1413
|
+
() => `Frequency of ${tvalFindName(i)}: ${data.tvProbs[i]}\n`,
|
|
1414
|
+
);
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
/* Rescale frequencies. */
|
|
1418
|
+
rescaleFreqs(data);
|
|
1419
|
+
|
|
1420
|
+
/* Perform any additional rescaling and adjustment. */
|
|
1421
|
+
adjustFreqs(data);
|
|
1422
|
+
|
|
1423
|
+
/* "Log the final frequencies to check that everything's correct" (:1309). */
|
|
1424
|
+
for (let i = 0; i < ART_IDX_TOTAL; i++) {
|
|
1425
|
+
randartLogf(
|
|
1426
|
+
() => `Rescaled frequency of ability ${i}: ${data.artProbs[i]}\n`,
|
|
1427
|
+
);
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
/* Build a cumulative frequency table for tvals. */
|
|
1431
|
+
for (let i = 0; i < TV_MAX; i++) {
|
|
1432
|
+
for (let j = i; j < TV_MAX; j++) {
|
|
1433
|
+
data.tvFreq[j] = (data.tvFreq[j] ?? 0) + (data.tvProbs[i] ?? 0);
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
/* "Print out the frequency table, for verification" (:1319). */
|
|
1438
|
+
for (let i = 0; i < TV_MAX; i++) {
|
|
1439
|
+
randartLogf(
|
|
1440
|
+
() => `Cumulative frequency of ${tvalFindName(i)} is: ${data.tvFreq[i]}\n`,
|
|
1441
|
+
);
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1445
|
+
/* ------------------------------------------------------------------ */
|
|
1446
|
+
/* Generation of a random artifact (header) */
|
|
1447
|
+
/* ------------------------------------------------------------------ */
|
|
1448
|
+
|
|
1449
|
+
/**
|
|
1450
|
+
* get_base_item_tval (obj-randart.c L1332): pick a random base item tval from
|
|
1451
|
+
* the original artifact tval frequencies.
|
|
1452
|
+
*/
|
|
1453
|
+
export function getBaseItemTval(data: ArtifactSetData, rng: Rng): number {
|
|
1454
|
+
let tval = 0;
|
|
1455
|
+
const r = rng.randint1(data.tvFreq[TV_MAX - 1]!);
|
|
1456
|
+
while (r > (data.tvFreq[tval] ?? 0)) {
|
|
1457
|
+
tval++;
|
|
1458
|
+
}
|
|
1459
|
+
return tval;
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
/* ------------------------------------------------------------------ */
|
|
1463
|
+
/* artifact_set_data allocation (obj-randart.c L2993) */
|
|
1464
|
+
/* ------------------------------------------------------------------ */
|
|
1465
|
+
|
|
1466
|
+
/** INHIBIT_POWER: the power ceiling above which arts are treated as uber. */
|
|
1467
|
+
const INHIBIT_POWER = 20000;
|
|
1468
|
+
|
|
1469
|
+
/**
|
|
1470
|
+
* artifact_set_data_new (obj-randart.c L2993): allocate and initialize a new
|
|
1471
|
+
* artifact set data structure. Power/level/prob arrays are sized by the number
|
|
1472
|
+
* of artifact slots (a_max, i.e. reg.artifacts.length); the tval arrays by
|
|
1473
|
+
* TV_MAX and the ability array by ART_IDX_TOTAL.
|
|
1474
|
+
*/
|
|
1475
|
+
export function artifactSetDataNew(reg: ObjRegistry): ArtifactSetData {
|
|
1476
|
+
const aMax = reg.artifacts.length;
|
|
1477
|
+
const zeros = (n: number): number[] => new Array<number>(n).fill(0);
|
|
1478
|
+
|
|
1479
|
+
return {
|
|
1480
|
+
/* Mean start and increment values for to_hit, to_dam and AC. */
|
|
1481
|
+
hitIncrement: 4,
|
|
1482
|
+
damIncrement: 4,
|
|
1483
|
+
hitStartval: 10,
|
|
1484
|
+
damStartval: 10,
|
|
1485
|
+
acStartval: 15,
|
|
1486
|
+
acIncrement: 5,
|
|
1487
|
+
|
|
1488
|
+
artProbs: zeros(ART_IDX_TOTAL),
|
|
1489
|
+
tvProbs: zeros(TV_MAX),
|
|
1490
|
+
tvNum: zeros(TV_MAX),
|
|
1491
|
+
bowTotal: 0,
|
|
1492
|
+
meleeTotal: 0,
|
|
1493
|
+
bootTotal: 0,
|
|
1494
|
+
gloveTotal: 0,
|
|
1495
|
+
headgearTotal: 0,
|
|
1496
|
+
shieldTotal: 0,
|
|
1497
|
+
cloakTotal: 0,
|
|
1498
|
+
armorTotal: 0,
|
|
1499
|
+
otherTotal: 0,
|
|
1500
|
+
total: 0,
|
|
1501
|
+
negPowerTotal: 0,
|
|
1502
|
+
|
|
1503
|
+
tvFreq: zeros(TV_MAX),
|
|
1504
|
+
|
|
1505
|
+
basePower: zeros(aMax),
|
|
1506
|
+
maxPower: 0,
|
|
1507
|
+
minPower: 0,
|
|
1508
|
+
avgPower: 0,
|
|
1509
|
+
varPower: 0,
|
|
1510
|
+
avgTvPower: zeros(TV_MAX),
|
|
1511
|
+
minTvPower: zeros(TV_MAX),
|
|
1512
|
+
maxTvPower: zeros(TV_MAX),
|
|
1513
|
+
|
|
1514
|
+
baseItemLevel: zeros(aMax),
|
|
1515
|
+
baseItemProb: zeros(aMax),
|
|
1516
|
+
baseArtAlloc: zeros(aMax),
|
|
1517
|
+
};
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
/**
|
|
1521
|
+
* Allocate an ArtifactSetData and run the measurement pipeline over `arts`:
|
|
1522
|
+
* store_base_power, then parse_frequencies (which runs collect_artifact_data,
|
|
1523
|
+
* rescale_freqs and adjust_freqs). Returns the populated data. `rng` is drawn
|
|
1524
|
+
* from, not merely threaded: store_base_power powers every artifact, and
|
|
1525
|
+
* make_fake_artifact rolls a timeout per cursed slot (see
|
|
1526
|
+
* makeFakeArtifactPower). Over the standard set that is a handful of draws;
|
|
1527
|
+
* over a generated set it is one per curse the design loop added.
|
|
1528
|
+
*
|
|
1529
|
+
* WHICH SET is a parameter because do_randart measures TWICE (obj-randart.c
|
|
1530
|
+
* L3175-L3186): once over the standard artifacts, and once more over the
|
|
1531
|
+
* finished ones. Upstream can leave it implicit because create_artifact_set
|
|
1532
|
+
* overwrites the a_info global in place, so "the artifacts" means a different
|
|
1533
|
+
* set the second time round without anything being passed. This port generates
|
|
1534
|
+
* into a fresh array and leaves reg.artifacts alone, so the set being measured
|
|
1535
|
+
* has to be handed in.
|
|
1536
|
+
*/
|
|
1537
|
+
export function collectArtifactData(
|
|
1538
|
+
reg: ObjRegistry,
|
|
1539
|
+
constants: Constants,
|
|
1540
|
+
arts: readonly (Artifact | null)[],
|
|
1541
|
+
rng: Rng,
|
|
1542
|
+
): ArtifactSetData {
|
|
1543
|
+
const data = artifactSetDataNew(reg);
|
|
1544
|
+
storeBasePower(reg, constants, arts, data, rng);
|
|
1545
|
+
parseFrequencies(reg, arts, data);
|
|
1546
|
+
return data;
|
|
1547
|
+
}
|