@maka/maka-cli 5.122.0 → 5.123.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.
Files changed (119) hide show
  1. package/bundle/typescript/package.json +1 -1
  2. package/bundle/typescript/src/commands/deploy/ubuntu.sub.cmd.js +12 -8
  3. package/bundle/typescript/src/commands/deploy/ubuntu.sub.cmd.js.map +1 -1
  4. package/bundle/typescript/src/commands/game/sideQuest/adept-powers.d.ts +15 -0
  5. package/bundle/typescript/src/commands/game/sideQuest/adept-powers.js +12 -0
  6. package/bundle/typescript/src/commands/game/sideQuest/adept-powers.js.map +1 -1
  7. package/bundle/typescript/src/commands/game/sideQuest/archetypes.d.ts +10 -0
  8. package/bundle/typescript/src/commands/game/sideQuest/archetypes.js +40 -14
  9. package/bundle/typescript/src/commands/game/sideQuest/archetypes.js.map +1 -1
  10. package/bundle/typescript/src/commands/game/sideQuest/augmentations.d.ts +33 -10
  11. package/bundle/typescript/src/commands/game/sideQuest/augmentations.js +155 -72
  12. package/bundle/typescript/src/commands/game/sideQuest/augmentations.js.map +1 -1
  13. package/bundle/typescript/src/commands/game/sideQuest/commands/advance.js +15 -6
  14. package/bundle/typescript/src/commands/game/sideQuest/commands/advance.js.map +1 -1
  15. package/bundle/typescript/src/commands/game/sideQuest/commands/ask.js +1 -1
  16. package/bundle/typescript/src/commands/game/sideQuest/commands/ask.js.map +1 -1
  17. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js +1 -1
  18. package/bundle/typescript/src/commands/game/sideQuest/commands/bluff.js.map +1 -1
  19. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js +33 -33
  20. package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js.map +1 -1
  21. package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js +1 -1
  22. package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js.map +1 -1
  23. package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +1 -1
  24. package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
  25. package/bundle/typescript/src/commands/game/sideQuest/commands/grapple.js +5 -1
  26. package/bundle/typescript/src/commands/game/sideQuest/commands/grapple.js.map +1 -1
  27. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +6 -6
  28. package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js.map +1 -1
  29. package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.js +4 -4
  30. package/bundle/typescript/src/commands/game/sideQuest/commands/haggle.js.map +1 -1
  31. package/bundle/typescript/src/commands/game/sideQuest/commands/hop.js +1 -1
  32. package/bundle/typescript/src/commands/game/sideQuest/commands/hop.js.map +1 -1
  33. package/bundle/typescript/src/commands/game/sideQuest/commands/initiate.d.ts +20 -0
  34. package/bundle/typescript/src/commands/game/sideQuest/commands/initiate.js +9 -0
  35. package/bundle/typescript/src/commands/game/sideQuest/commands/initiate.js.map +1 -1
  36. package/bundle/typescript/src/commands/game/sideQuest/commands/lead.js +7 -3
  37. package/bundle/typescript/src/commands/game/sideQuest/commands/lead.js.map +1 -1
  38. package/bundle/typescript/src/commands/game/sideQuest/commands/move.js +3 -3
  39. package/bundle/typescript/src/commands/game/sideQuest/commands/move.js.map +1 -1
  40. package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.js +1 -1
  41. package/bundle/typescript/src/commands/game/sideQuest/commands/persuade.js.map +1 -1
  42. package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js +3 -3
  43. package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js.map +1 -1
  44. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js +10 -10
  45. package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js.map +1 -1
  46. package/bundle/typescript/src/commands/game/sideQuest/commands/tap.js +1 -1
  47. package/bundle/typescript/src/commands/game/sideQuest/commands/tap.js.map +1 -1
  48. package/bundle/typescript/src/commands/game/sideQuest/factories/chargen-factory.d.ts +24 -0
  49. package/bundle/typescript/src/commands/game/sideQuest/factories/chargen-factory.js +95 -0
  50. package/bundle/typescript/src/commands/game/sideQuest/factories/chargen-factory.js.map +1 -1
  51. package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +45 -1
  52. package/bundle/typescript/src/commands/game/sideQuest/game.js +119 -8
  53. package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
  54. package/bundle/typescript/src/commands/game/sideQuest/metatypes.d.ts +53 -0
  55. package/bundle/typescript/src/commands/game/sideQuest/metatypes.js +86 -0
  56. package/bundle/typescript/src/commands/game/sideQuest/metatypes.js.map +1 -0
  57. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +8 -2
  58. package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
  59. package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +215 -18
  60. package/bundle/typescript/src/commands/game/sideQuest/models/player.js +548 -117
  61. package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
  62. package/bundle/typescript/src/commands/game/sideQuest/models/scene.d.ts +2 -1
  63. package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +3 -2
  64. package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
  65. package/bundle/typescript/src/commands/game/sideQuest/qualities.d.ts +96 -4
  66. package/bundle/typescript/src/commands/game/sideQuest/qualities.js +290 -11
  67. package/bundle/typescript/src/commands/game/sideQuest/qualities.js.map +1 -1
  68. package/bundle/typescript/src/commands/game/sideQuest/skill-groups.d.ts +11 -1
  69. package/bundle/typescript/src/commands/game/sideQuest/skill-groups.js +13 -1
  70. package/bundle/typescript/src/commands/game/sideQuest/skill-groups.js.map +1 -1
  71. package/bundle/typescript/src/commands/game/sideQuest/skills.d.ts +17 -0
  72. package/bundle/typescript/src/commands/game/sideQuest/skills.js +23 -0
  73. package/bundle/typescript/src/commands/game/sideQuest/skills.js.map +1 -0
  74. package/bundle/typescript/src/commands/game/sideQuest/spells.d.ts +76 -3
  75. package/bundle/typescript/src/commands/game/sideQuest/spells.js +48 -21
  76. package/bundle/typescript/src/commands/game/sideQuest/spells.js.map +1 -1
  77. package/bundle/typescript/src/commands/game/sideQuest/types/save-file.d.ts +8 -0
  78. package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog-data.d.ts +90 -82
  79. package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog-data.js +277 -10
  80. package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog-data.js.map +1 -1
  81. package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog.d.ts +121 -2
  82. package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog.js +342 -18
  83. package/bundle/typescript/src/commands/game/sideQuest/utilities/catalog.js.map +1 -1
  84. package/bundle/typescript/src/commands/game/sideQuest/utilities/cloud-saves.d.ts +65 -2
  85. package/bundle/typescript/src/commands/game/sideQuest/utilities/cloud-saves.js +74 -7
  86. package/bundle/typescript/src/commands/game/sideQuest/utilities/cloud-saves.js.map +1 -1
  87. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +1 -1
  88. package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js.map +1 -1
  89. package/bundle/typescript/src/commands/game/sideQuest/utilities/effects.d.ts +248 -0
  90. package/bundle/typescript/src/commands/game/sideQuest/utilities/effects.js +38 -0
  91. package/bundle/typescript/src/commands/game/sideQuest/utilities/effects.js.map +1 -0
  92. package/bundle/typescript/src/commands/game/sideQuest/utilities/first-aid.js +1 -2
  93. package/bundle/typescript/src/commands/game/sideQuest/utilities/first-aid.js.map +1 -1
  94. package/bundle/typescript/src/commands/game/sideQuest/utilities/perception.js +1 -2
  95. package/bundle/typescript/src/commands/game/sideQuest/utilities/perception.js.map +1 -1
  96. package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js +5 -0
  97. package/bundle/typescript/src/commands/game/sideQuest/utilities/persistence.js.map +1 -1
  98. package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js +5 -1
  99. package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js.map +1 -1
  100. package/bundle/typescript/src/commands/game/sideQuest/utilities/pregen-worksheet.js +22 -12
  101. package/bundle/typescript/src/commands/game/sideQuest/utilities/pregen-worksheet.js.map +1 -1
  102. package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js +1 -2
  103. package/bundle/typescript/src/commands/game/sideQuest/utilities/spots.js.map +1 -1
  104. package/bundle/typescript/src/commands/game/sideQuest/utilities/web-character-generator.d.ts +1 -0
  105. package/bundle/typescript/src/commands/game/sideQuest/utilities/web-character-generator.js +20 -0
  106. package/bundle/typescript/src/commands/game/sideQuest/utilities/web-character-generator.js.map +1 -1
  107. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +31 -0
  108. package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
  109. package/bundle/typescript/src/commands/login.js +19 -1
  110. package/bundle/typescript/src/commands/login.js.map +1 -1
  111. package/bundle/typescript/src/commands/logout.js +16 -1
  112. package/bundle/typescript/src/commands/logout.js.map +1 -1
  113. package/bundle/typescript/src/tools/guarded-file/guarded-file.class.d.ts +59 -0
  114. package/bundle/typescript/src/tools/guarded-file/guarded-file.class.js +120 -0
  115. package/bundle/typescript/src/tools/guarded-file/guarded-file.class.js.map +1 -0
  116. package/bundle/typescript/src/tools/mpi/mpi.class.d.ts +16 -0
  117. package/bundle/typescript/src/tools/mpi/mpi.class.js +25 -7
  118. package/bundle/typescript/src/tools/mpi/mpi.class.js.map +1 -1
  119. package/package.json +1 -1
@@ -131,8 +131,9 @@ export type SimMode = 'cold' | 'hot';
131
131
  * this not-yet-carried list; all three are now real and hooked, one per
132
132
  * command file beside them.)
133
133
  */
134
- export type SkillName = 'blades' | 'clubs' | 'unarmed' | 'gunnery' | 'astral-combat' | 'cybercombat' | 'sneaking' | 'perception' | 'palming' | 'escape-artist' | 'disguise' | 'hacking' | 'locksmith' | 'computer' | 'electronic-warfare' | 'hardware' | 'negotiation' | 'con' | 'intimidation' | 'etiquette' | 'leadership' | 'performance' | 'instruction' | 'first-aid' | 'medicine' | 'assensing' | 'spellcasting' | 'counterspelling' | 'piloting' | 'conjuring' | 'compiling' | 'decompiling' | 'registering' | 'software' | 'impersonation' | 'ritual-spellcasting' | 'gymnastics' | 'running' | 'swimming' | 'automatics' | 'pistols' | 'longarms' | 'banishing' | 'summoning' | 'binding' | 'cybertechnology' | 'alchemy' | 'disenchanting' | 'artificing' | 'aeronautics-mechanic' | 'industrial-mechanic' | 'automotive-mechanic' | 'nautical-mechanic' | 'navigation' | 'tracking' | 'survival' | 'archery' | 'free-fall' | 'heavy-weapons' | 'throwing-weapons' | 'exotic-melee' | 'exotic-ranged';
135
- export declare const SKILL_NAMES: SkillName[];
134
+ export { SKILL_NAMES } from '../skills.js';
135
+ export type { SkillName } from '../skills.js';
136
+ import type { SkillName } from '../skills.js';
136
137
  /**
137
138
  * Skills that fall back to the legacy `combatSkill` attribute when no
138
139
  * explicit rating is given -- this is what keeps every existing NPC seed
@@ -908,13 +909,42 @@ export declare class Player extends AbstractPlayer {
908
909
  essence: number;
909
910
  grade?: string;
910
911
  }): void;
911
- /** Every effect that applies right now, with the rating it scales by. */
912
+ /**
913
+ * Which SOURCE an effect came from. The single accessor `bonus()`
914
+ * sums them all; the older per-source getters each sum their own,
915
+ * which is what lets the call sites migrate one at a time instead of
916
+ * in one unreviewable commit.
917
+ */
918
+ /** Every effect applying right now, with its source and its scale. */
912
919
  private applyingEffects;
920
+ /**
921
+ * Sums one kind of effect. `lanes` narrows to particular sources --
922
+ * omitted means EVERY source, which is what the unified `bonus()`
923
+ * wants; the legacy getters each pass their own single lane so that
924
+ * a call site still adding two of them by hand cannot double.
925
+ */
926
+ /**
927
+ * The spells being sustained, and what each scales by.
928
+ *
929
+ * READS THE STATE cast.ts ALREADY KEEPS rather than a second map:
930
+ * the armor spell stores its hits, and the other two are booleans
931
+ * whose rows carry a flat value, so 1 is the right multiplier for
932
+ * them. Adding a parallel store would be two places to forget to
933
+ * update, which is the shape this whole pass has been removing.
934
+ */
935
+ private sustainedMagnitudes;
913
936
  private sumEffects;
914
937
  /**
915
- * Dice the gear adds to a pool or a skill's tests (cf. augBonus,
916
- * qualityBonus): `kind` is a pool kind or a SkillName; `only` names a
917
- * narrowing an effect may carry ('haggle', 'silent', 'matrix-search').
938
+ * Dice the GEAR LANE adds, and nothing else.
939
+ *
940
+ * A LANE READER, NOT A POOL. Every pool in the game reads `bonus()`
941
+ * now; this survives as the way to ask what one source contributes,
942
+ * which is what the behaviour fixture interrogates and what a "where
943
+ * did that die come from" answer would need. It has no production
944
+ * caller of its own, and that is the correct state for it rather than
945
+ * a sign it should go: deleting it would delete the fixture's ability
946
+ * to see the lanes apart, which is the only thing that can catch one
947
+ * lane being counted twice.
918
948
  */
919
949
  gearBonus(kind: string, opts?: {
920
950
  only?: string;
@@ -923,32 +953,164 @@ export declare class Player extends AbstractPlayer {
923
953
  gearLimit(kind: 'physical' | 'mental' | 'social' | 'accuracy', opts?: {
924
954
  only?: string;
925
955
  }): number;
926
- /** A capability the gear grants (dni, smartlink, no-fog, low-light...), by key. */
927
- hasCapability(key: string): boolean;
928
956
  /**
929
- * The single tap every pool reads chrome through. Wired Reflexes tiers
930
- * don't stack -- the higher tier wins (II supersedes I) -- but the
931
- * synaptic-vs-wired conflict is the clinic's job, not this getter's.
957
+ * EVERY die the character has for this pool or skill, from every
958
+ * source -- gear, chrome, qualities, adept powers, metamagics, a
959
+ * metatype trait, a sustained spell.
960
+ *
961
+ * `only` names a narrowing an effect may carry ('haggle', 'silent',
962
+ * 'matrix-search'). `skill` lets a combat pool pick up dice that were
963
+ * declared against the SKILL being rolled rather than the pool --
964
+ * a smartlink says `firearms`, and the attack pool has to see it.
965
+ *
966
+ * The sources that have not yet moved onto the shared shape are added
967
+ * explicitly below, each named, so that migrating one is a matter of
968
+ * deleting its line here rather than hunting for what it fed.
969
+ */
970
+ bonus(kind: string, opts?: {
971
+ only?: string;
972
+ skill?: string;
973
+ }): number;
974
+ /**
975
+ * What a source adds to the initiative SCORE -- the number you roll
976
+ * against -- as opposed to `bonus('initiative')`, which is the DICE.
977
+ *
978
+ * The `initiative` effect arm has existed since the gear pass and
979
+ * was read by nothing at all until the Increase Reflexes spell came
980
+ * onto the lane (2026-09-04). Two different quantities sharing the
981
+ * word "initiative" is exactly why the arm is separate.
982
+ */
983
+ initiativeBonus(of: 'score' | 'dice'): number;
984
+ /** Every point on a LIMIT, from every source. */
985
+ limitBonus(kind: 'physical' | 'mental' | 'social' | 'accuracy', opts?: {
986
+ only?: string;
987
+ }): number;
988
+ /**
989
+ * How much further this character may raise one skill or attribute
990
+ * than anyone else -- Aptitude's chosen skill (p.72), Exceptional
991
+ * Attribute's chosen attribute (p.73-74).
992
+ *
993
+ * The book states absolute numbers against ITS ceilings (a skill at 7
994
+ * rather than 6 at creation, 13 rather than 12 after). This engine
995
+ * caps lower than the book does, so what carries across is the DELTA
996
+ * -- one step further than anyone else gets -- applied to whatever
997
+ * ceiling the engine is enforcing. Writing the book's 13 over a house
998
+ * cap of 7 would not be more faithful, only a bigger number in the
999
+ * wrong system.
1000
+ *
1001
+ * A `chosen` ceiling resolves through the holder's own pick, so a
1002
+ * quality bought but never answered lifts nothing at all.
1003
+ */
1004
+ capBonus(of: 'skill' | 'attribute', name: string): number;
1005
+ /**
1006
+
1007
+
1008
+ /** A capability the character has, from any source, by key. */
1009
+ can(key: string): boolean;
1010
+ /**
1011
+ * THE CHROME THAT ACTUALLY COUNTS: everything installed, minus the
1012
+ * wired-reflex tiers a higher tier supersedes.
1013
+ *
1014
+ * Wired Reflexes I, II and III do not stack -- the best one wins (a
1015
+ * synaptic booster is bioware and rides on top of whichever that is).
1016
+ * That is a relationship BETWEEN rows, so no row can declare it and it
1017
+ * has to live in code; it lives HERE, in the one place the resolver
1018
+ * reads, rather than inside a getter, where only that getter would
1019
+ * have been right and every other reader would have double-counted.
1020
+ *
1021
+ * The synaptic-vs-wired legality conflict remains the clinic's job.
1022
+ */
1023
+ private chromeThatCounts;
1024
+ /**
1025
+ * The chrome lane, by pool. A LANE READER, like gearBonus above.
1026
+ *
1027
+ * Every pool now reads `bonus()`, with exactly two deliberate
1028
+ * exceptions, both in smartlinkTier and both commented there: that
1029
+ * method asks which TIER of smartlink you have, implant or clip-on,
1030
+ * and only the chrome lane can answer it.
932
1031
  */
933
1032
  augBonus(kind: AugBonusKind): number;
934
1033
  /** Installed qualities, by catalog key (see QUALITIES). */
935
1034
  qualities: Set<string>;
1035
+ /**
1036
+ * IS THIS SKILL OR ATTRIBUTE FORBIDDEN OUTRIGHT to this character?
1037
+ *
1038
+ * Reads the same lane every other rule reads, so a second quality
1039
+ * (or a piece of chrome, or a metatype trait) that bars something
1040
+ * needs no new reader. A `chosen` forbid resolves through the
1041
+ * holder's pick, and where the pick names a skill GROUP the bar
1042
+ * falls on every member -- which is what Incompetent actually is
1043
+ * (p.81: "all skills in the skill group").
1044
+ */
1045
+ isForbidden(of: 'skill' | 'attribute', name: string): boolean;
1046
+ /**
1047
+ * Incompetent (p.81) names ONE skill group, and this is the only place
1048
+ * that knows how to ask which. It was three separate reads of
1049
+ * `hasQuality(`incompetent-${skill}`)` -- the slug convention -- and a
1050
+ * fourth that counted slugs by prefix for notoriety. The quality is
1051
+ * now 'incompetent' with a pick, and a legacy slug resolves to the
1052
+ * same thing on load (qualities.ts LEGACY_CHOICE_KEYS), so this
1053
+ * answers the same for an old save and a new one.
1054
+ */
1055
+ isIncompetentAt(skill: string): boolean;
936
1056
  hasQuality(key: string): boolean;
937
1057
  /**
938
1058
  * Records a quality and applies its one-time creation effect. Lucky is
939
1059
  * the only quality that edits an attribute (RAW raises the Edge ceiling;
940
1060
  * with no attribute point-buy here, the point lands directly).
941
1061
  */
1062
+ /**
1063
+ * WHAT THE HOLDER PICKED, per ROW that demands a pick (ICatalogChoice):
1064
+ * slug -> the skill or attribute named.
1065
+ *
1066
+ * KEYED BY SLUG, NOT BY QUALITY (mjmcee, 2026-09-04). A Hardwire is an
1067
+ * augmentation that gives +2 to a chosen skill and asks exactly the
1068
+ * question Aptitude asks; a map that only qualities could reach would
1069
+ * mean a second map for chrome and a third for spells. One map, one
1070
+ * picker, one payload field.
1071
+ */
1072
+ picks: Map<string, string>;
1073
+ /**
1074
+ * The former name for `picks`, back when only qualities could ask.
1075
+ * Kept as the SAME Map -- not a copy -- so a save written or read
1076
+ * through the old name still lands in one place.
1077
+ */
1078
+ get qualityChoices(): Map<string, string>;
942
1079
  /** Rating per rated quality (qualities.ts maxRating); absent = 1. */
943
1080
  qualityRatings: Map<string, number>;
944
1081
  /** The rating held, 0 when the quality is not held; a flat quality reads 1. */
945
1082
  qualityRating(key: string): number;
946
1083
  addQuality(rawKey: string, rating?: number): void;
1084
+ /**
1085
+ * A quality that MOVES AN ATTRIBUTE does it once, here, at install.
1086
+ *
1087
+ * Unlike a dice effect -- which qualityBonus re-reads on every roll
1088
+ * -- an attribute is a stored number, so it is edited rather than
1089
+ * summed. Lucky (p.76) is the long-standing case: RAW it raises the
1090
+ * Edge CEILING, and with no attribute point-buy here the point lands
1091
+ * directly. It used to be an `if (key === 'lucky')` in addQuality;
1092
+ * it is data now, which is what let Ugly and Doesn't Care (Cutting
1093
+ * Aces p.152-153) arrive as data too instead of as a second `if`.
1094
+ *
1095
+ * The floor is 1: no quality reduces an attribute below the minimum
1096
+ * a metahuman can have, and Ugly and Doesn't Care says so in as many
1097
+ * words ("minimum 1").
1098
+ */
1099
+ private applyQualityAttributes;
947
1100
  /**
948
1101
  * The single tap every pool reads qualities through (cf. augBonus).
949
1102
  *
1103
+ * DATA, NOT A SWITCH (2026-09-04). Every number below used to be a
1104
+ * `case` here; each one now lives on its own quality in qualities.ts
1105
+ * as an `effects` entry, in the same vocabulary gear and chrome
1106
+ * already speak. A quality that adds dice therefore needs no edit to
1107
+ * this method -- which is the property that matters, because the
1108
+ * cost of the old shape was that the catalog could only ever print a
1109
+ * quality's PROSE while its actual numbers lived somewhere a reader
1110
+ * could not reach.
1111
+ *
950
1112
  * `perception` and `social` mirror the augBonus kinds of the same
951
- * names, and are read at the same call sites, so a quality and a piece
1113
+ * names and are read at the same call sites, so a quality and a piece
952
1114
  * of chrome that do the same thing are added the same way.
953
1115
  *
954
1116
  * `sleaze` and `attack` are the two Matrix ACTIONS this engine names
@@ -957,9 +1119,36 @@ export declare class Player extends AbstractPlayer {
957
1119
  * a mark IS one of those two. They exist because Codeslinger and
958
1120
  * Codeblock (p.72 / p.80) modify ONE chosen Matrix action rather than
959
1121
  * Matrix work in general, so a `hacking`-wide bonus would be a
960
- * different quality wearing the name.
961
- */
962
- qualityBonus(kind: 'sneak' | 'athletics' | 'matrix' | 'hacking' | 'piloting' | 'soak' | 'healing' | 'perception' | 'social' | 'sleaze' | 'attack'): number;
1122
+ * different quality wearing the name. In the DATA they are spelled
1123
+ * `matrix-attack` / `matrix-sleaze`: EffectPool already spends the
1124
+ * bare word `attack` on the COMBAT attack pool, and a quality that
1125
+ * fired in a firefight because it shared a word with a Matrix action
1126
+ * would be a bug nobody would look for.
1127
+ */
1128
+ qualityBonus(kind: 'sneak' | 'athletics' | 'matrix' | 'hacking' | 'piloting' | 'soak' | 'healing' | 'perception' | 'social' | 'sleaze' | 'attack' | 'leadership' | 'escape-artist' | 'biofeedback'): number;
1129
+ /**
1130
+ * Dice the QUALITIES add to one pool or skill. Deliberately its own
1131
+ * summation rather than a source inside applyingEffects(): the pools
1132
+ * are read as `augBonus(k) + qualityBonus(k)` at call sites that do
1133
+ * NOT also add gearBonus(k), and folding qualities into the shared
1134
+ * effect walk would have made every site that DOES add gearBonus
1135
+ * count a quality twice, silently, in a number nobody prints.
1136
+ */
1137
+ /**
1138
+ * How much further this character may raise one skill or attribute
1139
+ * than anyone else -- Aptitude's chosen skill (p.72), Exceptional
1140
+ * Attribute's chosen attribute (p.73-74).
1141
+ *
1142
+ * The book states absolute numbers against ITS ceilings (a skill at
1143
+ * 7 rather than 6 at creation, 13 rather than 12 after). This engine
1144
+ * caps lower than the book does, so what carries across is the DELTA
1145
+ * -- one step further than anyone else gets -- applied to whatever
1146
+ * ceiling the engine is enforcing. Writing the book's 13 over a house
1147
+ * cap of 7 would not be more faithful, it would just be a bigger
1148
+ * number in the wrong system.
1149
+ */
1150
+ qualityCap(of: 'skill' | 'attribute', name: string): number;
1151
+ private sumQualityEffects;
963
1152
  private _firstImpressionUsed;
964
1153
  /** Spends the first impression: +2 for the social roll happening NOW. */
965
1154
  consumeFirstImpression(): number;
@@ -1511,13 +1700,21 @@ export declare class Player extends AbstractPlayer {
1511
1700
  * Combat Sense. The Power Point metamagic stays what it always was --
1512
1701
  * a point of magic-as-muscle on the STRIKING side only.
1513
1702
  */
1703
+ /**
1704
+ * The COMPRESSED adept's flat bonus, or zero for anyone who chose
1705
+ * powers. Split out of adeptAttackBonus so the combat pools can read
1706
+ * `bonus()` for every other source without counting the chosen powers
1707
+ * twice -- they arrive through the adept lane, and this is the only
1708
+ * part of the adept that never became data.
1709
+ */
1710
+ private adeptCompressedBonus;
1514
1711
  adeptAttackBonus(): number;
1515
1712
  adeptDefenseBonus(): number;
1516
1713
  /** Mystic Armor (p.309): +1 Armor per level. Zero under the compressed
1517
1714
  * model -- the flat pool bonus never granted armor, so none is owed. */
1518
1715
  adeptArmorBonus(): number;
1519
- /** Improved Reflexes (p.309): +level Reaction, read by the defence and
1520
- * initiative math. Zero under the compressed model. */
1716
+ /** Improved Reflexes (p.309): the initiative dice it adds. Zero under
1717
+ * the compressed model. */
1521
1718
  adeptReactionBonus(): number;
1522
1719
  /** Killing Hands (p.309): unarmed strikes deal PHYSICAL damage. */
1523
1720
  hasKillingHands(): boolean;
@@ -1623,7 +1820,7 @@ export declare class Player extends AbstractPlayer {
1623
1820
  /** Static Veil: +2 to matrix defense while sustained. */
1624
1821
  get formDefenseBonus(): number;
1625
1822
  /** The Force each sustained spell was cast at (cast.ts records it) -- Focused Concentration reads it. */
1626
- sustainedForces: Map<"armor" | "invisibility" | "reflexes", number>;
1823
+ sustainedForces: Map<"armor" | "reflexes" | "invisibility", number>;
1627
1824
  noteSustainedForce(kind: 'armor' | 'invisibility' | 'reflexes', force: number): void;
1628
1825
  /** GREMLINS (p.81): the 1s a glitch needs, one fewer per rating, on external equipment -- the deck. */
1629
1826
  get deckGremlins(): number;