@maka/maka-cli 5.3.17 → 5.4.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/bundle/typescript/package.json +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.d.ts +43 -0
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.js +131 -0
- package/bundle/typescript/src/commands/game/sideQuest/archetypes.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/assense.d.ts +14 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/assense.js +79 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/assense.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/attack.d.ts +42 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js +224 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/attack.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.d.ts +28 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js +101 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/bypass-command.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.d.ts +19 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.js +149 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/call.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.d.ts +58 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js +378 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/cast.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/command-registry.d.ts +11 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/command-registry.js +8 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/command-registry.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/command.d.ts +6 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/command.js +4 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/command.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/drone.d.ts +15 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js +60 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/drone.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/edge.d.ts +13 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/edge.js +31 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/edge.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/end-call.d.ts +6 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/end-call.js +27 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/end-call.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/equip.d.ts +4 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js +40 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/equip.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.d.ts +13 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js +43 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/equipment.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/give.js +7 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/give.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.d.ts +11 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js +115 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/go.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.d.ts +25 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js +176 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/hack.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/inv.d.ts +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js +39 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/inv.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/jack.d.ts +17 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/jack.js +64 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/jack.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/kill.d.ts +10 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/kill.js +11 -33
- package/bundle/typescript/src/commands/game/sideQuest/commands/kill.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js +35 -4
- package/bundle/typescript/src/commands/game/sideQuest/commands/look.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/map.d.ts +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/map.js +46 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/map.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/pan.d.ts +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/pan.js +55 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/pan.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/pick.d.ts +9 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js +18 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/pick.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/project.d.ts +19 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/project.js +54 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/project.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/read.js +6 -5
- package/bundle/typescript/src/commands/game/sideQuest/commands/read.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/reboot.d.ts +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/reboot.js +52 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/reboot.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/reload.d.ts +14 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/reload.js +40 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/reload.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/rest.d.ts +15 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js +59 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/rest.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/say.js +23 -2
- package/bundle/typescript/src/commands/game/sideQuest/commands/say.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js +20 -3
- package/bundle/typescript/src/commands/game/sideQuest/commands/search.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.d.ts +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js +49 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/sheet.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/silent.d.ts +13 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/silent.js +50 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/silent.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js +32 -11
- package/bundle/typescript/src/commands/game/sideQuest/commands/solve.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/spells.d.ts +14 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/spells.js +65 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/spells.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/stance.d.ts +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/stance.js +41 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/stance.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/subdue.d.ts +21 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/subdue.js +43 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/subdue.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/surrender.d.ts +20 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/surrender.js +45 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/surrender.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.d.ts +8 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.js +80 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/take.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/unlock.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/use.d.ts +24 -0
- package/bundle/typescript/src/commands/game/sideQuest/commands/use.js +101 -1
- package/bundle/typescript/src/commands/game/sideQuest/commands/use.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/item-factory.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/item-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/npc-factory.js +7 -2
- package/bundle/typescript/src/commands/game/sideQuest/factories/npc-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.js +2 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/puzzle-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/room-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.d.ts +8 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js +138 -21
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-factory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.d.ts +119 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js +816 -0
- package/bundle/typescript/src/commands/game/sideQuest/factories/scene-seed-generator.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/game.d.ts +70 -9
- package/bundle/typescript/src/commands/game/sideQuest/game.js +403 -164
- package/bundle/typescript/src/commands/game/sideQuest/game.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/minigames/hack-minigame.d.ts +16 -0
- package/bundle/typescript/src/commands/game/sideQuest/minigames/hack-minigame.js +101 -0
- package/bundle/typescript/src/commands/game/sideQuest/minigames/hack-minigame.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/minigames/lockpick-minigame.d.ts +15 -0
- package/bundle/typescript/src/commands/game/sideQuest/minigames/lockpick-minigame.js +95 -0
- package/bundle/typescript/src/commands/game/sideQuest/minigames/lockpick-minigame.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/door.d.ts +10 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/door.js +15 -2
- package/bundle/typescript/src/commands/game/sideQuest/models/door.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/inventory.d.ts +10 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/inventory.js +54 -4
- package/bundle/typescript/src/commands/game/sideQuest/models/inventory.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/item.d.ts +41 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/item.js +106 -3
- package/bundle/typescript/src/commands/game/sideQuest/models/item.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.d.ts +25 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js +220 -47
- package/bundle/typescript/src/commands/game/sideQuest/models/npc.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/player.d.ts +213 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js +525 -9
- package/bundle/typescript/src/commands/game/sideQuest/models/player.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.d.ts +75 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js +174 -6
- package/bundle/typescript/src/commands/game/sideQuest/models/puzzle.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/room.d.ts +20 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js +39 -18
- package/bundle/typescript/src/commands/game/sideQuest/models/room.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.d.ts +69 -0
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js +175 -2
- package/bundle/typescript/src/commands/game/sideQuest/models/scene.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/scenes/scene1.json +80 -1
- package/bundle/typescript/src/commands/game/sideQuest/scenes/scene2.json +7 -2
- package/bundle/typescript/src/commands/game/sideQuest/types/player-equipment.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/exit-seed.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/item-seed.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/npc-seed.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/player-seed.d.ts +34 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/puzzle-seed.d.ts +15 -1
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/room-seed.d.ts +3 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/scene-seed.d.ts +5 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/win-condition-seed.d.ts +15 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/win-condition-seed.js +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/seed/win-condition-seed.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.js +5 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/shared/abstracts.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/types/shared/item-enum.d.ts +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/shared/item-enum.js +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/types/shared/item-enum.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/ui.d.ts +3 -0
- package/bundle/typescript/src/commands/game/sideQuest/ui.js +95 -5
- package/bundle/typescript/src/commands/game/sideQuest/ui.js.map +1 -1
- package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.d.ts +60 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.js +138 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/auto-fight.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.d.ts +143 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js +328 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/combat-exchange.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/comm-style.d.ts +2 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/comm-style.js +12 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/comm-style.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.d.ts +22 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js +34 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/dice.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.d.ts +36 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.js +92 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/fuzzy-match.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.d.ts +44 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js +193 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/planes.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/pursuit.d.ts +16 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/pursuit.js +36 -0
- package/bundle/typescript/src/commands/game/sideQuest/utilities/pursuit.js.map +1 -0
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js +54 -7
- package/bundle/typescript/src/commands/game/sideQuest.sub.cmd.js.map +1 -1
- package/bundle/typescript/src/commands/set/global.sub.cmd.js +59 -5
- package/bundle/typescript/src/commands/set/global.sub.cmd.js.map +1 -1
- package/bundle/typescript/src/tools/ai/ai.class.d.ts +35 -0
- package/bundle/typescript/src/tools/ai/ai.class.js +112 -0
- package/bundle/typescript/src/tools/ai/ai.class.js.map +1 -0
- package/bundle/typescript/src/tools/fsi/fsi.interfaces.d.ts +1 -0
- package/bundle/typescript/src/tools/fsi/fsi.interfaces.js.map +1 -1
- package/bundle/typescript/src/tools/https/https.class.d.ts +2 -1
- package/bundle/typescript/src/tools/https/https.class.js +43 -0
- package/bundle/typescript/src/tools/https/https.class.js.map +1 -1
- package/bundle/typescript/src/tools/https/https.interface.d.ts +8 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maka/maka-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"summary": "A command line tool for scaffolding Meteor 2.x applications using either React.",
|
|
6
6
|
"description": "A command line tool for scaffolding Meteor 2.x applications using React.",
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ICombatAttributes } from './models/player.js';
|
|
2
|
+
import { Item } from './models/item.js';
|
|
3
|
+
import { Size, Category, Rating } from './types/shared/item-enum.js';
|
|
4
|
+
/**
|
|
5
|
+
* Playable archetypes -- the SR5e core-book spreads, picked at game launch
|
|
6
|
+
* (see sideQuest.sub.cmd.ts). This is deliberately archetype-pick rather
|
|
7
|
+
* than point-buy: one quick select and you're on the street. Each spread
|
|
8
|
+
* trades away as much as it gains against the balanced Runner baseline
|
|
9
|
+
* (body 4 / agility 4 / reaction 4 / skill 3 / str 3 / wil 3 / log 3 /
|
|
10
|
+
* int 3 / cha 3 / edge 2), and the premium attributes are the identity:
|
|
11
|
+
* magic makes a caster, magic+adept makes an adept, resonance makes a
|
|
12
|
+
* technomancer, logic 7 makes a decker.
|
|
13
|
+
*
|
|
14
|
+
* REQUISITES: `gear` is the archetype's signature kit, granted (and
|
|
15
|
+
* auto-equipped where wearable) at character creation ON TOP of the
|
|
16
|
+
* scene's generic starting loadout. A Decker without a deck isn't a
|
|
17
|
+
* decker -- the gear is part of the build.
|
|
18
|
+
*/
|
|
19
|
+
export interface IArchetypeGearDef {
|
|
20
|
+
name: string;
|
|
21
|
+
description: string;
|
|
22
|
+
size: Size;
|
|
23
|
+
category: Category;
|
|
24
|
+
rating: Rating;
|
|
25
|
+
weight: number;
|
|
26
|
+
shape: string;
|
|
27
|
+
color: string;
|
|
28
|
+
texture: string;
|
|
29
|
+
}
|
|
30
|
+
export interface IArchetype {
|
|
31
|
+
name: string;
|
|
32
|
+
description: string;
|
|
33
|
+
combat: ICombatAttributes;
|
|
34
|
+
gear?: IArchetypeGearDef[];
|
|
35
|
+
}
|
|
36
|
+
export declare const ARCHETYPES: IArchetype[];
|
|
37
|
+
export declare function getArchetype(name?: string): IArchetype;
|
|
38
|
+
/**
|
|
39
|
+
* Instantiates an archetype's requisite gear (see IArchetype.gear).
|
|
40
|
+
* ui.ts grants these at character creation and auto-equips the wearable
|
|
41
|
+
* ones -- a samurai starts with the Predator IN HAND, not in a duffel.
|
|
42
|
+
*/
|
|
43
|
+
export declare function createArchetypeGear(archetype: IArchetype): Item[];
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Item } from './models/item.js';
|
|
2
|
+
import { Size, Category, Rating } from './types/shared/item-enum.js';
|
|
3
|
+
const gearDef = (partial) => ({
|
|
4
|
+
size: Size.Small,
|
|
5
|
+
weight: 1,
|
|
6
|
+
shape: 'Gear',
|
|
7
|
+
color: 'Black',
|
|
8
|
+
texture: 'Matte',
|
|
9
|
+
...partial,
|
|
10
|
+
});
|
|
11
|
+
export const ARCHETYPES = [
|
|
12
|
+
{
|
|
13
|
+
name: 'Runner',
|
|
14
|
+
description: 'The balanced default: decent at everything, spectacular at nothing.',
|
|
15
|
+
combat: { body: 4, agility: 4, reaction: 4, combatSkill: 3, strength: 3, willpower: 3, logic: 3, intuition: 3, charisma: 3, edge: 2, magic: 0 },
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'Street Samurai',
|
|
19
|
+
description: 'Chrome and trigger discipline. Hits hard, soaks harder, thinks later.',
|
|
20
|
+
combat: { body: 5, agility: 5, reaction: 4, combatSkill: 5, strength: 4, willpower: 3, logic: 2, intuition: 3, charisma: 2, edge: 2, magic: 0 },
|
|
21
|
+
gear: [
|
|
22
|
+
gearDef({ name: 'Ares Predator V', description: 'The iconic heavy pistol of the shadows -- smartgun-linked, and it never jams when it matters.', category: Category.RangedWeapon, rating: Rating.Rare, shape: 'Pistol', weight: 2 }),
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
// Physical magic: counts as Awakened (auras, assensing) but casts
|
|
27
|
+
// nothing and cannot project -- half their magic rides every meat
|
|
28
|
+
// attack and defense pool instead (see Player.adept).
|
|
29
|
+
name: 'Adept',
|
|
30
|
+
description: 'Magic as muscle: faster than chrome, no spells, no projection -- the body IS the focus.',
|
|
31
|
+
combat: { body: 4, agility: 4, reaction: 4, combatSkill: 4, strength: 4, willpower: 4, logic: 2, intuition: 3, charisma: 2, edge: 2, magic: 5, adept: true },
|
|
32
|
+
gear: [
|
|
33
|
+
gearDef({ name: 'Weapon Focus Katana', description: 'A blade that drinks its wielder\'s magic -- the edge sings at frequencies steel shouldn\'t reach.', category: Category.MeleeWeapon, rating: Rating.Rare, size: Size.Medium, shape: 'Sword', color: 'Silver', texture: 'Folded Steel', weight: 1.5 }),
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'Covert Ops',
|
|
38
|
+
description: 'In through the vents, out before the alarm. Locks are suggestions.',
|
|
39
|
+
combat: { body: 3, agility: 5, reaction: 4, combatSkill: 3, strength: 3, willpower: 3, logic: 3, intuition: 5, charisma: 3, edge: 3, magic: 0 },
|
|
40
|
+
gear: [
|
|
41
|
+
gearDef({ name: 'Lockpick Set', description: 'Precision picks, tension bars, and a maglock passkey of arguable legality.', category: Category.Tool, rating: Rating.Standard, size: Size.Tiny, weight: 0.3 }),
|
|
42
|
+
gearDef({ name: 'Chameleon Suit', description: 'Ruthenium-coated infiltration wear that drinks the light around it.', category: Category.ArmorClothing, rating: Rating.Standard, size: Size.Medium, shape: 'Suit', color: 'Shifting Gray', texture: 'Ruthenium Weave', weight: 2 }),
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'Face',
|
|
47
|
+
description: 'Talks the job open before anyone draws. Charm, luck, and just enough gun.',
|
|
48
|
+
combat: { body: 3, agility: 3, reaction: 3, combatSkill: 3, strength: 3, willpower: 4, logic: 3, intuition: 4, charisma: 6, edge: 3, magic: 0 },
|
|
49
|
+
gear: [
|
|
50
|
+
gearDef({ name: 'Transys Avalon', description: 'A top-shelf commlink -- the AR overlay alone is worth the felony it took to afford it.', category: Category.Commlink, rating: Rating.Rare, size: Size.Tiny, weight: 0.2 }),
|
|
51
|
+
gearDef({ name: 'Berwick Suit', description: 'Tailored armor-weave that reads boardroom, not battlefield.', category: Category.ArmorClothing, rating: Rating.Standard, size: Size.Medium, shape: 'Suit', color: 'Charcoal', texture: 'Armored Silk', weight: 2 }),
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'Street Doc',
|
|
56
|
+
description: 'Keeps the team breathing: brains, steady hands, and a bag full of trauma kits.',
|
|
57
|
+
combat: { body: 3, agility: 3, reaction: 3, combatSkill: 2, strength: 3, willpower: 4, logic: 6, intuition: 4, charisma: 3, edge: 2, magic: 0 },
|
|
58
|
+
gear: [
|
|
59
|
+
gearDef({ name: 'Trauma Kit', description: 'A doc-grade field kit: sprays, staples, and things that hiss.', category: Category.Medical, rating: Rating.Rare, weight: 1.5 }),
|
|
60
|
+
gearDef({ name: 'Kamikaze Stim Patch', description: 'A combat stim slap-patch. The crash is tomorrow\'s problem.', category: Category.StimPatch, rating: Rating.Standard, size: Size.Tiny, weight: 0.1 }),
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'Combat Mage',
|
|
65
|
+
description: 'Awakened artillery: manabolts through milspec armor, if the drain doesn\'t eat you first.',
|
|
66
|
+
combat: { body: 3, agility: 3, reaction: 3, combatSkill: 2, strength: 2, willpower: 5, logic: 4, intuition: 4, charisma: 3, edge: 2, magic: 6 },
|
|
67
|
+
gear: [
|
|
68
|
+
gearDef({ name: 'Spellcasting Focus', description: 'An orichalcum-threaded ring that gathers mana the way a lens gathers light.', category: Category.Focus, rating: Rating.Standard, size: Size.Tiny, shape: 'Ring', color: 'Gold', texture: 'Orichalcum', weight: 0.1 }),
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'Street Shaman',
|
|
73
|
+
description: 'Awakened the hard way: iron will, sharp instincts, spirits on speed dial.',
|
|
74
|
+
combat: { body: 3, agility: 2, reaction: 3, combatSkill: 2, strength: 2, willpower: 6, logic: 3, intuition: 5, charisma: 4, edge: 2, magic: 5 },
|
|
75
|
+
gear: [
|
|
76
|
+
gearDef({ name: 'Spirit Talisman', description: 'Feathers, bone, and braided wire -- a focus that hums when the other world leans close.', category: Category.Focus, rating: Rating.Standard, size: Size.Tiny, shape: 'Talisman', color: 'Bone White', texture: 'Feather and Wire', weight: 0.2 }),
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
// Logic drives EVERYTHING a decker cares about: Matrix attack pools,
|
|
81
|
+
// firewall soak, thought-speed initiative, hacking hosts -- and the
|
|
82
|
+
// deck is the requisite: its quality feeds program damage and
|
|
83
|
+
// firewall, and its hardware track is what the ice chews on.
|
|
84
|
+
name: 'Decker',
|
|
85
|
+
description: 'A ghost in the grid: hosts crack, ice burns, maglocks open. Just don\'t get caught in meatspace.',
|
|
86
|
+
combat: { body: 3, agility: 2, reaction: 3, combatSkill: 2, strength: 2, willpower: 4, logic: 7, intuition: 5, charisma: 2, edge: 3, magic: 0 },
|
|
87
|
+
gear: [
|
|
88
|
+
gearDef({ name: 'Novatech Navigator', description: 'A workhorse cyberdeck -- scuffed case, immaculate boards. Your ticket into the Matrix.', category: Category.Cyberdeck, rating: Rating.Standard, weight: 2 }),
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
// The living persona (see ICombatAttributes.resonance): no deck, no
|
|
93
|
+
// commlink -- and no hardware between their stun track and the ice.
|
|
94
|
+
name: 'Technomancer',
|
|
95
|
+
description: 'The Matrix answers when they think at it. No deck to brick -- only a mind to burn.',
|
|
96
|
+
combat: { body: 2, agility: 2, reaction: 3, combatSkill: 2, strength: 2, willpower: 5, logic: 5, intuition: 4, charisma: 3, edge: 3, magic: 0, resonance: 6 },
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
// The drone is the mechanic: "drone" launches the Fly-Spy for live
|
|
100
|
+
// recon of every adjacent room (see commands/drone.ts). Jumped-in
|
|
101
|
+
// drone rigging can build on this later.
|
|
102
|
+
name: 'Rigger',
|
|
103
|
+
description: 'Eyes everywhere: the Fly-Spy scouts the next room so your body never has to.',
|
|
104
|
+
combat: { body: 3, agility: 3, reaction: 5, combatSkill: 3, strength: 3, willpower: 3, logic: 5, intuition: 4, charisma: 2, edge: 2, magic: 0 },
|
|
105
|
+
gear: [
|
|
106
|
+
gearDef({ name: 'Fly-Spy Drone', description: 'A palm-sized surveillance drone, quiet as a moth and twice as nosy.', category: Category.Drone, rating: Rating.Standard, size: Size.Tiny, shape: 'Insectoid', color: 'Gunmetal', texture: 'Micro-rotor', weight: 0.5 }),
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
];
|
|
110
|
+
export function getArchetype(name) {
|
|
111
|
+
return ARCHETYPES.find(a => a.name === name) ?? ARCHETYPES[0];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Instantiates an archetype's requisite gear (see IArchetype.gear).
|
|
115
|
+
* ui.ts grants these at character creation and auto-equips the wearable
|
|
116
|
+
* ones -- a samurai starts with the Predator IN HAND, not in a duffel.
|
|
117
|
+
*/
|
|
118
|
+
export function createArchetypeGear(archetype) {
|
|
119
|
+
return (archetype.gear ?? []).map(def => new Item({
|
|
120
|
+
name: def.name,
|
|
121
|
+
description: def.description,
|
|
122
|
+
size: def.size,
|
|
123
|
+
category: def.category,
|
|
124
|
+
shape: def.shape,
|
|
125
|
+
color: def.color,
|
|
126
|
+
texture: def.texture,
|
|
127
|
+
rating: def.rating,
|
|
128
|
+
weight: def.weight,
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=archetypes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archetypes.js","sourceRoot":"","sources":["../../../../../../src/commands/game/sideQuest/archetypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Command, ICommand } from './command.js';
|
|
2
|
+
/**
|
|
3
|
+
* Astral perception: read the world's auras without (or while) leaving
|
|
4
|
+
* your body. Awakened only. "assense" reads the room -- wards, the magical
|
|
5
|
+
* temperature; "assense <name>" reads a person: health, whether they're
|
|
6
|
+
* Awakened, the emotional weather on them, and the magic they carry. This
|
|
7
|
+
* is the recon tool that makes a mage the crew's lie detector and
|
|
8
|
+
* ward-spotter.
|
|
9
|
+
*/
|
|
10
|
+
export declare class AssenseCommand extends Command implements ICommand {
|
|
11
|
+
protected static verb: string;
|
|
12
|
+
protected static description: string;
|
|
13
|
+
execute(args?: string[]): Promise<string>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Command } from './command.js';
|
|
2
|
+
import { fuzzyPickName } from '../utilities/fuzzy-match.js';
|
|
3
|
+
/**
|
|
4
|
+
* Astral perception: read the world's auras without (or while) leaving
|
|
5
|
+
* your body. Awakened only. "assense" reads the room -- wards, the magical
|
|
6
|
+
* temperature; "assense <name>" reads a person: health, whether they're
|
|
7
|
+
* Awakened, the emotional weather on them, and the magic they carry. This
|
|
8
|
+
* is the recon tool that makes a mage the crew's lie detector and
|
|
9
|
+
* ward-spotter.
|
|
10
|
+
*/
|
|
11
|
+
export class AssenseCommand extends Command {
|
|
12
|
+
static verb = 'assense';
|
|
13
|
+
static description = 'Read auras (Awakened only): "assense" for the room and its wards, "assense <name>" for someone\'s health, nature, and the magic on them.';
|
|
14
|
+
async execute(args = []) {
|
|
15
|
+
const actor = this.actor;
|
|
16
|
+
if (!actor.isAwakened()) {
|
|
17
|
+
return `You squint. Nothing happens. Reading auras takes the Awakened gift.`;
|
|
18
|
+
}
|
|
19
|
+
if (actor.plane === 'matrix') {
|
|
20
|
+
return `There are no auras in here -- only geometry and other people's code.`;
|
|
21
|
+
}
|
|
22
|
+
const room = actor.currentLocation;
|
|
23
|
+
// Bare assense: the room's astral weather.
|
|
24
|
+
if (!args || args.length === 0) {
|
|
25
|
+
const lines = [`You open your astral senses:`];
|
|
26
|
+
lines.push(room.warded
|
|
27
|
+
? ` • This place is WARDED -- an astral barrier seals it against projection.`
|
|
28
|
+
: ` • No wards here -- the astral is open ground.`);
|
|
29
|
+
if (room.hasNode) {
|
|
30
|
+
lines.push(` • The room's tech hums with dataflow -- a live Matrix node (nothing astral, but a decker would care).`);
|
|
31
|
+
}
|
|
32
|
+
const others = this.scene.getActorsInRoom(room).filter(a => a !== actor && actor.canPerceive(a));
|
|
33
|
+
if (others.length === 0) {
|
|
34
|
+
lines.push(` • No living auras nearby.`);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
lines.push(` • Auras present: ${others.map(a => a.name).join(', ')} -- "assense <name>" to read one.`);
|
|
38
|
+
}
|
|
39
|
+
return lines.join('\n');
|
|
40
|
+
}
|
|
41
|
+
// Targeted assense: one aura, read deep.
|
|
42
|
+
const candidates = this.scene.getActorsInRoom(room).filter(a => a !== actor && actor.canPerceive(a));
|
|
43
|
+
const picked = fuzzyPickName(args.join(' '), candidates.map(a => a.name));
|
|
44
|
+
const target = picked ? candidates.find(a => a.name === picked) : undefined;
|
|
45
|
+
if (!target) {
|
|
46
|
+
const present = candidates.map(a => a.name).join(', ') || 'no one';
|
|
47
|
+
return `No aura by that name here. Present: ${present}.`;
|
|
48
|
+
}
|
|
49
|
+
const physHurt = target.damageTaken > 0;
|
|
50
|
+
const stunHurt = target.stunTaken > 0;
|
|
51
|
+
const health = !physHurt && !stunHurt
|
|
52
|
+
? `whole and unhurt`
|
|
53
|
+
: `marred${physHurt ? ` -- physical trauma (${target.damageTaken}/${target.maxConditionBoxes})` : ''}${stunHurt ? ` -- exhaustion and shock (${target.stunTaken}/${target.maxStunBoxes})` : ''}`;
|
|
54
|
+
const lines = [`You read ${target.name}'s aura:`];
|
|
55
|
+
lines.push(` • Health: ${health}.`);
|
|
56
|
+
lines.push(target.isAwakened()
|
|
57
|
+
? ` • They BURN -- Awakened, magic ${target.magic}. Treat accordingly.`
|
|
58
|
+
: ` • Mundane -- no spark in them.`);
|
|
59
|
+
if (target.surrendered) {
|
|
60
|
+
lines.push(` • The fight has gone out of them entirely -- the surrender is genuine.`);
|
|
61
|
+
}
|
|
62
|
+
else if (target.combatOpponent) {
|
|
63
|
+
lines.push(` • Violence swirls close to the surface -- they're in a fight, or barely out of one.`);
|
|
64
|
+
}
|
|
65
|
+
const magicGear = target.inventory.getAllItems().filter(i => {
|
|
66
|
+
const c = String(i.category).toLowerCase();
|
|
67
|
+
return c.includes('focus') || c.includes('grimoire') || c.includes('spellformula') || c.includes('spell formula');
|
|
68
|
+
});
|
|
69
|
+
if (magicGear.length > 0) {
|
|
70
|
+
lines.push(` • Enchantment clings to their gear: ${magicGear.map(i => i.name).join(', ')}.`);
|
|
71
|
+
}
|
|
72
|
+
if (target.plane === 'meat' && actor.plane === 'astral') {
|
|
73
|
+
lines.push(` • They can't see you watching.`);
|
|
74
|
+
}
|
|
75
|
+
this.logger.write(`${actor.name} assensed ${target.name}.`);
|
|
76
|
+
return lines.join('\n');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=assense.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assense.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/assense.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D;;;;;;;GAOG;AACH,MAAM,OAAO,cAAe,SAAQ,OAAO;IAC/B,MAAM,CAAC,IAAI,GAAG,SAAS,CAAC;IACxB,MAAM,CAAC,WAAW,GAAG,0IAA0I,CAAC;IAE1K,KAAK,CAAC,OAAO,CAAC,OAAiB,EAAE;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAEzB,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;YACxB,OAAO,qEAAqE,CAAC;QAC/E,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAO,sEAAsE,CAAC;QAChF,CAAC;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,eAAe,CAAC;QAEnC,2CAA2C;QAC3C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,CAAC,8BAA8B,CAAC,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM;gBACpB,CAAC,CAAC,4EAA4E;gBAC9E,CAAC,CAAC,iDAAiD,CAAC,CAAC;YACvD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,KAAK,CAAC,IAAI,CAAC,yGAAyG,CAAC,CAAC;YACxH,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YACjG,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,sBAAsB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;YAC1G,CAAC;YACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAED,yCAAyC;QACzC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QACrG,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1E,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;YACnE,OAAO,uCAAuC,OAAO,GAAG,CAAC;QAC3D,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,CAAC,QAAQ,IAAI,CAAC,QAAQ;YACnC,CAAC,CAAC,kBAAkB;YACpB,CAAC,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,wBAAwB,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,6BAA6B,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAEnM,MAAM,KAAK,GAAG,CAAC,YAAY,MAAM,CAAC,IAAI,UAAU,CAAC,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,eAAe,MAAM,GAAG,CAAC,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;YAC5B,CAAC,CAAC,oCAAoC,MAAM,CAAC,KAAK,sBAAsB;YACxE,CAAC,CAAC,kCAAkC,CAAC,CAAC;QACxC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAC;QACzF,CAAC;aAAM,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,uFAAuF,CAAC,CAAC;QACtG,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YAC1D,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;YAC3C,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QACpH,CAAC,CAAC,CAAC;QACH,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,yCAAyC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChG,CAAC;QACD,IAAI,MAAM,CAAC,KAAK,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACxD,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,aAAa,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;QAC5D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Command, ICommand } from './command.js';
|
|
2
|
+
import { CombatExchange, IStrikeProfile } from '../utilities/combat-exchange.js';
|
|
3
|
+
import { Player } from '../models/player.js';
|
|
4
|
+
import { NPC } from '../models/npc.js';
|
|
5
|
+
/**
|
|
6
|
+
* Shadowrun-style dice-pool combat, one full exchange per command:
|
|
7
|
+
*
|
|
8
|
+
* 1. Attacker rolls Agility + combat skill + weapon bonus, opposed by the
|
|
9
|
+
* defender's Reaction. Net hits land the blow.
|
|
10
|
+
* 2. Damage = weapon DV + net hits, soaked by Body + armor (each soak hit
|
|
11
|
+
* cancels one box).
|
|
12
|
+
* 3. Whatever gets through fills the defender's condition monitor; a full
|
|
13
|
+
* track is death.
|
|
14
|
+
* 4. If the defender survives, they immediately strike back with the same
|
|
15
|
+
* math reversed -- starting a fight means eating one, so a fight is a
|
|
16
|
+
* real decision, not a free action.
|
|
17
|
+
*
|
|
18
|
+
* Wound modifiers (-1 die per 3 boxes taken) apply to every pool on both
|
|
19
|
+
* sides, so a fight tilts as it goes. Pools/derivations live on Player
|
|
20
|
+
* (getAttackPool() etc.); narration pacing, strike resolution, and death
|
|
21
|
+
* handling live in CombatExchange (shared with spell combat -- see
|
|
22
|
+
* cast.ts). This command only orchestrates the weapon exchange.
|
|
23
|
+
*/
|
|
24
|
+
export declare class AttackCommand extends Command implements ICommand {
|
|
25
|
+
protected static verb: string;
|
|
26
|
+
protected static description: string;
|
|
27
|
+
execute(args?: string[]): Promise<string>;
|
|
28
|
+
/** subdue.ts overrides to false: its strike ignores the equipped gun entirely. */
|
|
29
|
+
protected usesEquippedWeapon(): boolean;
|
|
30
|
+
/** Overridden by subdue.ts to swap in a stun-dealing strike. undefined = weapon default. */
|
|
31
|
+
protected strikeProfile(_exchange: CombatExchange, _target: Player | NPC): IStrikeProfile | undefined;
|
|
32
|
+
/** The verb observers see ("attacks" / "moves to subdue"). */
|
|
33
|
+
protected actionVerb(): string;
|
|
34
|
+
/**
|
|
35
|
+
* Post-strike incapacitation, both flavors: a full physical track is a
|
|
36
|
+
* death; a full stun track (only reachable via a stun-dealing strike,
|
|
37
|
+
* or its overflow) is a live capture. Returns the narration, or null if
|
|
38
|
+
* the fallen still stands. Either combatant can be the one who falls --
|
|
39
|
+
* initiative order means the aggressor eats preemptive strikes too.
|
|
40
|
+
*/
|
|
41
|
+
protected resolveTakedown(exchange: CombatExchange, fallen: Player | NPC, killer: Player | NPC): Promise<string[] | null>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { Command } from './command.js';
|
|
2
|
+
import { CombatExchange } from '../utilities/combat-exchange.js';
|
|
3
|
+
import { fuzzyPickName } from '../utilities/fuzzy-match.js';
|
|
4
|
+
import { describeFledTarget } from '../utilities/pursuit.js';
|
|
5
|
+
import { shellsInRoom, resolveBodyAttack } from '../utilities/planes.js';
|
|
6
|
+
/**
|
|
7
|
+
* Shadowrun-style dice-pool combat, one full exchange per command:
|
|
8
|
+
*
|
|
9
|
+
* 1. Attacker rolls Agility + combat skill + weapon bonus, opposed by the
|
|
10
|
+
* defender's Reaction. Net hits land the blow.
|
|
11
|
+
* 2. Damage = weapon DV + net hits, soaked by Body + armor (each soak hit
|
|
12
|
+
* cancels one box).
|
|
13
|
+
* 3. Whatever gets through fills the defender's condition monitor; a full
|
|
14
|
+
* track is death.
|
|
15
|
+
* 4. If the defender survives, they immediately strike back with the same
|
|
16
|
+
* math reversed -- starting a fight means eating one, so a fight is a
|
|
17
|
+
* real decision, not a free action.
|
|
18
|
+
*
|
|
19
|
+
* Wound modifiers (-1 die per 3 boxes taken) apply to every pool on both
|
|
20
|
+
* sides, so a fight tilts as it goes. Pools/derivations live on Player
|
|
21
|
+
* (getAttackPool() etc.); narration pacing, strike resolution, and death
|
|
22
|
+
* handling live in CombatExchange (shared with spell combat -- see
|
|
23
|
+
* cast.ts). This command only orchestrates the weapon exchange.
|
|
24
|
+
*/
|
|
25
|
+
export class AttackCommand extends Command {
|
|
26
|
+
static verb = 'attack';
|
|
27
|
+
static description = 'Attack someone in the room -- dice-pool combat with your equipped weapon. They WILL hit back.';
|
|
28
|
+
async execute(args = []) {
|
|
29
|
+
if (!args || args.length === 0) {
|
|
30
|
+
return 'Who do you want to attack? Try: `attack <name>`';
|
|
31
|
+
}
|
|
32
|
+
// The dead (and the unconscious) don't fight. Covers a downed player
|
|
33
|
+
// (who stays in the scene -- endGame only freezes input) and a downed
|
|
34
|
+
// NPC whose in-flight AI loop is still issuing commands after removal
|
|
35
|
+
// from the scene.
|
|
36
|
+
if (this.actor.isIncapacitated()) {
|
|
37
|
+
return `You're down. The fight is over.`;
|
|
38
|
+
}
|
|
39
|
+
const room = this.actor.currentLocation;
|
|
40
|
+
if (!room) {
|
|
41
|
+
return 'You are not in a valid location to fight anyone.';
|
|
42
|
+
}
|
|
43
|
+
// Same fuzzy matching "take" uses (see utilities/fuzzy-match.ts) --
|
|
44
|
+
// punctuation, case, typos, and partial names all resolve, but an
|
|
45
|
+
// ambiguous guess deliberately misses rather than shooting someone
|
|
46
|
+
// at random. You can only fight what shares your plane: meat can't
|
|
47
|
+
// touch a Matrix persona or an astral form, and vice versa.
|
|
48
|
+
const targetName = args.join(' ');
|
|
49
|
+
const candidates = this.scene.getActorsInRoom(room).filter(a => a !== this.actor && a.plane === this.actor.plane);
|
|
50
|
+
const pickedName = fuzzyPickName(targetName, candidates.map(a => a.name));
|
|
51
|
+
const target = pickedName ? candidates.find(a => a.name === pickedName) : undefined;
|
|
52
|
+
if (!target) {
|
|
53
|
+
// An empty body IS attackable from the meat plane -- one unanswered
|
|
54
|
+
// strike, and its owner gets slammed back into it (see planes.ts).
|
|
55
|
+
if (this.actor.plane === 'meat') {
|
|
56
|
+
const shells = shellsInRoom(this.scene, room);
|
|
57
|
+
const shellPick = fuzzyPickName(targetName, shells.map(s => s.name));
|
|
58
|
+
const shell = shellPick ? shells.find(s => s.name === shellPick) : undefined;
|
|
59
|
+
if (shell) {
|
|
60
|
+
const lines = resolveBodyAttack(this.scene, this.actor, shell);
|
|
61
|
+
const exchange = new CombatExchange(this.scene, this.logger, this.actor);
|
|
62
|
+
await exchange.announce(lines);
|
|
63
|
+
if (shell.isDown()) {
|
|
64
|
+
const death = await exchange.resolveDeath(shell, this.actor, {
|
|
65
|
+
fallLine: `${shell.name}'s body never wakes -- whatever came rushing back arrived too late. Their gear scatters across ${room.name}.`,
|
|
66
|
+
});
|
|
67
|
+
lines.push(...death);
|
|
68
|
+
}
|
|
69
|
+
return this.actor === this.scene.getPlayer() ? '' : lines.join('\n');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// If they exist but fled the room, say WHERE and how to chase --
|
|
73
|
+
// this result is what lands in a pursuing NPC's AI history, and
|
|
74
|
+
// without the explicit direction a hostile NPC just spams failed
|
|
75
|
+
// attacks at the empty room instead of following (real session:
|
|
76
|
+
// dozens of them while the player ping-ponged between two rooms).
|
|
77
|
+
const fled = describeFledTarget(this.scene, room, targetName);
|
|
78
|
+
if (fled)
|
|
79
|
+
return fled;
|
|
80
|
+
const present = candidates.map(a => a.name).join(', ') || 'no one';
|
|
81
|
+
return `You don't see anyone named "${targetName}" here to attack. Present: ${present}.`;
|
|
82
|
+
}
|
|
83
|
+
// The dead can't be fought either. A downed NPC is removed from the
|
|
84
|
+
// scene, so a still-present downed target can only be the dead player
|
|
85
|
+
// -- found via a real session where the killer's AI loop, with nothing
|
|
86
|
+
// gating this, beat the player's corpse for a full minute, re-running
|
|
87
|
+
// the whole death sequence every swing. The plain-text result below is
|
|
88
|
+
// what actually lands in the attacker's AI history and tells it the
|
|
89
|
+
// fight is over.
|
|
90
|
+
if (target.isIncapacitated()) {
|
|
91
|
+
return `${target.name} is already down. The fight is over -- there's nothing left to attack.`;
|
|
92
|
+
}
|
|
93
|
+
// One exchange at a time per combatant: overlapping AI loops firing
|
|
94
|
+
// parallel exchanges once double-killed a target (two death events,
|
|
95
|
+
// two narrations). The player is refused cleanly (they can just retype
|
|
96
|
+
// in the lull); an NPC's attack instead WAITS for the lull and re-runs
|
|
97
|
+
// -- discarding it meant NPCs never got a single action off, because
|
|
98
|
+
// their AI always reacts while the player's exchange is still beating
|
|
99
|
+
// out (see CombatExchange.waitForLull).
|
|
100
|
+
if (this.actor.inExchange || target.inExchange) {
|
|
101
|
+
if (this.actor === this.scene.getPlayer()) {
|
|
102
|
+
return this.actor.inExchange
|
|
103
|
+
? `You're already mid-exchange -- let it resolve.`
|
|
104
|
+
: `${target.name} is already trading fire -- wait for that exchange to resolve.`;
|
|
105
|
+
}
|
|
106
|
+
if (this.actor.waitingForLull) {
|
|
107
|
+
return `You're already waiting for an opening -- one move at a time.`;
|
|
108
|
+
}
|
|
109
|
+
this.actor.waitingForLull = true;
|
|
110
|
+
try {
|
|
111
|
+
const settled = await CombatExchange.waitForLull([this.actor, target]);
|
|
112
|
+
if (!settled) {
|
|
113
|
+
return `You're already mid-exchange -- let it resolve.`;
|
|
114
|
+
}
|
|
115
|
+
this.logger.write(`${this.actor.name}'s attack waited out an exchange and now retries.`);
|
|
116
|
+
return await this.execute(args);
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
this.actor.waitingForLull = false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// A deliberately INITIATED attack with a dry gun is blocked with a
|
|
123
|
+
// reload prompt -- the involuntary strikes (retaliation) auto-fall-back
|
|
124
|
+
// to fists instead (see CombatExchange.weaponProfile).
|
|
125
|
+
const weaponItem = this.actor.equipment.rightHand?.weapon ?? this.actor.equipment.leftHand?.weapon;
|
|
126
|
+
if (this.usesEquippedWeapon() && weaponItem?.isFirearm() && weaponItem.jammed) {
|
|
127
|
+
return `The ${weaponItem.name}'s smartlink is LOCKED -- someone cracked your PAN. "reboot" to clear it, or go in swinging.`;
|
|
128
|
+
}
|
|
129
|
+
if (this.usesEquippedWeapon() && weaponItem?.isFirearm() && weaponItem.ammo <= 0) {
|
|
130
|
+
return `Click -- the ${weaponItem.name} is dry. "reload" (needs ammunition), or go in swinging with something else.`;
|
|
131
|
+
}
|
|
132
|
+
const exchange = new CombatExchange(this.scene, this.logger, this.actor);
|
|
133
|
+
const report = [];
|
|
134
|
+
// Movement locks for the duration of the exchange when the player is a
|
|
135
|
+
// combatant (see go.ts) -- the try/finally is exception safety so a
|
|
136
|
+
// crash mid-exchange can never leave the player permanently rooted.
|
|
137
|
+
exchange.beginExchange(target);
|
|
138
|
+
try {
|
|
139
|
+
this.actor.performAction(this.actionVerb(), target.name);
|
|
140
|
+
this.scene.addWorldEvent(`${this.actor.name} ${this.actionVerb()} ${target.name} in ${room.name}.`);
|
|
141
|
+
// ---- Initiative decides who acts first (see rollInitiative) ----
|
|
142
|
+
const init = exchange.rollInitiative(this.actor, target);
|
|
143
|
+
report.push(...init.lines);
|
|
144
|
+
await exchange.announce(init.lines);
|
|
145
|
+
// ---- The two strikes, in initiative order. The aggressor's strike
|
|
146
|
+
// uses this command's profile (weapon, or subdue's stun hold); the
|
|
147
|
+
// defender's answer is always their own lethal weapon. Being
|
|
148
|
+
// preempted and dropped means your swing never happens. ----
|
|
149
|
+
for (const striker of [init.first, init.second]) {
|
|
150
|
+
if (striker.isIncapacitated())
|
|
151
|
+
continue;
|
|
152
|
+
const defender = striker === this.actor ? target : this.actor;
|
|
153
|
+
if (defender.isIncapacitated())
|
|
154
|
+
break;
|
|
155
|
+
// A mid-exchange forced dump (cold-sim persona crash) yanks a
|
|
156
|
+
// combatant off this plane -- the fight is over, not continued
|
|
157
|
+
// across realities.
|
|
158
|
+
if (striker.plane !== defender.plane)
|
|
159
|
+
break;
|
|
160
|
+
const profile = striker === this.actor ? this.strikeProfile(exchange, target) : undefined;
|
|
161
|
+
const prefix = striker === init.second ? [`${striker.name} retaliates!`] : [];
|
|
162
|
+
const strike = [...prefix, ...exchange.resolveStrike(striker, defender, profile)];
|
|
163
|
+
report.push('', ...strike);
|
|
164
|
+
await exchange.announce(strike);
|
|
165
|
+
const takedown = await this.resolveTakedown(exchange, defender, striker);
|
|
166
|
+
if (takedown) {
|
|
167
|
+
report.push(...takedown);
|
|
168
|
+
return await exchange.finishExchange(report);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// ---- The initiative pass: a decisive winner presses the advantage
|
|
172
|
+
// with one extra strike. ----
|
|
173
|
+
if (init.extraStriker && !init.extraStriker.isIncapacitated()) {
|
|
174
|
+
const defender = init.extraStriker === this.actor ? target : this.actor;
|
|
175
|
+
if (!defender.isIncapacitated() && init.extraStriker.plane === defender.plane) {
|
|
176
|
+
const profile = init.extraStriker === this.actor ? this.strikeProfile(exchange, target) : undefined;
|
|
177
|
+
const strike = [`${init.extraStriker.name} presses the advantage!`, ...exchange.resolveStrike(init.extraStriker, defender, profile)];
|
|
178
|
+
report.push('', ...strike);
|
|
179
|
+
await exchange.announce(strike);
|
|
180
|
+
const takedown = await this.resolveTakedown(exchange, defender, init.extraStriker);
|
|
181
|
+
if (takedown)
|
|
182
|
+
report.push(...takedown);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return await exchange.finishExchange(report);
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
this.scene.endPlayerExchange();
|
|
189
|
+
exchange.releaseExchange();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/** subdue.ts overrides to false: its strike ignores the equipped gun entirely. */
|
|
193
|
+
usesEquippedWeapon() {
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
/** Overridden by subdue.ts to swap in a stun-dealing strike. undefined = weapon default. */
|
|
197
|
+
strikeProfile(_exchange, _target) {
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
/** The verb observers see ("attacks" / "moves to subdue"). */
|
|
201
|
+
actionVerb() {
|
|
202
|
+
return 'attacks';
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Post-strike incapacitation, both flavors: a full physical track is a
|
|
206
|
+
* death; a full stun track (only reachable via a stun-dealing strike,
|
|
207
|
+
* or its overflow) is a live capture. Returns the narration, or null if
|
|
208
|
+
* the fallen still stands. Either combatant can be the one who falls --
|
|
209
|
+
* initiative order means the aggressor eats preemptive strikes too.
|
|
210
|
+
*/
|
|
211
|
+
async resolveTakedown(exchange, fallen, killer) {
|
|
212
|
+
if (fallen.isDown()) {
|
|
213
|
+
return exchange.resolveDeath(fallen, killer);
|
|
214
|
+
}
|
|
215
|
+
if (fallen.isUnconscious()) {
|
|
216
|
+
return exchange.resolveDeath(fallen, killer, {
|
|
217
|
+
fatal: false,
|
|
218
|
+
fallLine: `${fallen.name} sags and drops -- out cold, breathing. Their gear scatters across ${fallen.currentLocation.name}.`,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=attack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attack.js","sourceRoot":"","sources":["../../../../../../../src/commands/game/sideQuest/commands/attack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Command, ICommand } from './command.js';
|
|
2
|
+
import { PuzzleBypassType } from '../types/seed/puzzle-seed.js';
|
|
3
|
+
/**
|
|
4
|
+
* Shared implementation for pick/hack/cast. The gate check (already
|
|
5
|
+
* solved? prerequisite met? does this puzzle even have this bypassType?)
|
|
6
|
+
* always runs first and synchronously, so a doomed attempt never makes the
|
|
7
|
+
* player sit through an interactive challenge they were never going to be
|
|
8
|
+
* allowed to attempt. Each concrete command differs in its verb,
|
|
9
|
+
* description, bypass type, the "nothing to do that to" message, and
|
|
10
|
+
* optionally how the outcome itself gets determined (see
|
|
11
|
+
* determineOutcome() -- defaults to a coin flip; lockpicking overrides it
|
|
12
|
+
* with a real minigame).
|
|
13
|
+
*/
|
|
14
|
+
export declare abstract class BypassCommand extends Command implements ICommand {
|
|
15
|
+
protected abstract bypassType: PuzzleBypassType;
|
|
16
|
+
protected abstract noPuzzleMessage: string;
|
|
17
|
+
/** Default: a flat coin flip. Override for a type with its own minigame. */
|
|
18
|
+
protected determineOutcome(): Promise<boolean>;
|
|
19
|
+
/**
|
|
20
|
+
* There's no typed answer here to disambiguate with (unlike solve.ts),
|
|
21
|
+
* so with more than one barrier in the room the player has to name which
|
|
22
|
+
* one: a direction ("pick north", for a locked door) or a word from the
|
|
23
|
+
* barrier's own name ("pick maglock"). With only one candidate, a bare
|
|
24
|
+
* "pick" still works exactly as before.
|
|
25
|
+
*/
|
|
26
|
+
private resolveTarget;
|
|
27
|
+
execute(args: string[]): Promise<string>;
|
|
28
|
+
}
|