@lippelt/srd-gumshoe 0.1.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 +35 -0
- package/dist/index.cjs +205 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +36 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.js +177 -0
- package/dist/index.js.map +1 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @lippelt/srd-gumshoe
|
|
2
|
+
|
|
3
|
+
Módulo GUMSHOE (mecânica genérica) para [@lippelt/srd-core](../core).
|
|
4
|
+
|
|
5
|
+
Baseado no [GUMSHOE SRD](https://site.pelgranepress.com/index.php/the-gumshoe-system-reference-document/) de Robin D. Laws / Pelgrane Press, sob a **Creative Commons Attribution 3.0 Unported**.
|
|
6
|
+
|
|
7
|
+
> Trail of Cthulhu, Night's Black Agents, Ashen Stars, Esoterrorists, Mutant City Blues, Fear Itself são Product Identity da Pelgrane Press — não estão neste pacote.
|
|
8
|
+
|
|
9
|
+
## O que inclui
|
|
10
|
+
|
|
11
|
+
- **10 dice presets** — d6 + variantes de spend (d6+1 a d6+4), 5 categorias de dano (d6−2 a d6+2)
|
|
12
|
+
- **8 conditions** — Hurt, Seriously Wounded, Shaken, Stunned, Unconscious, Insane, Pursued, Connected
|
|
13
|
+
- **4 tracker fields** — Stability, Sanity, Athletics pool, Sense Trouble pool
|
|
14
|
+
- **Rules:**
|
|
15
|
+
- `roll('general' | 'check', { spend?, difficulty? })` — 1d6 + pontos gastos vs DC (padrão 4)
|
|
16
|
+
- `roll('stability' | 'sanity', { spend?, difficulty? })` — mesma mecânica, marcada como teste de Estabilidade
|
|
17
|
+
- `roll('damage', { modifier })` — 1d6 + modificador da arma
|
|
18
|
+
- **`investigativeSpend(ability, amount)`** — não rola; registra gasto de pool de perícia de investigação (no GUMSHOE, achar pistas é automático; pontos compram informação extra)
|
|
19
|
+
|
|
20
|
+
## Não inclui
|
|
21
|
+
|
|
22
|
+
Settings específicos (Cthulhu Mythos, anomalies do Mutant City Blues, etc) são Product Identity. Use este pacote como base genérica e adicione conteúdo do livro original na sua mesa.
|
|
23
|
+
|
|
24
|
+
## Uso
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { register } from '@lippelt/srd-core'
|
|
28
|
+
import { gumshoe } from '@lippelt/srd-gumshoe'
|
|
29
|
+
|
|
30
|
+
register(gumshoe)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Licença
|
|
34
|
+
|
|
35
|
+
[MIT](LICENSE) (código). Mecânica deriva do GUMSHOE SRD (CC-BY 3.0).
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
gumshoe: () => gumshoe,
|
|
24
|
+
investigativeSpend: () => investigativeSpend,
|
|
25
|
+
resetRoller: () => resetRoller,
|
|
26
|
+
setRoller: () => setRoller
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(index_exports);
|
|
29
|
+
var roller = (sides) => Math.floor(Math.random() * sides) + 1;
|
|
30
|
+
function setRoller(fn) {
|
|
31
|
+
roller = fn;
|
|
32
|
+
}
|
|
33
|
+
function resetRoller() {
|
|
34
|
+
roller = (sides) => Math.floor(Math.random() * sides) + 1;
|
|
35
|
+
}
|
|
36
|
+
function roll(sides, count = 1) {
|
|
37
|
+
const out = [];
|
|
38
|
+
for (let i = 0; i < count; i++) out.push(roller(sides));
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
function investigativeSpend(ability, amount) {
|
|
42
|
+
const cost = Math.max(0, Math.trunc(amount));
|
|
43
|
+
return { ability: String(ability).slice(0, 40), amount: cost, cost };
|
|
44
|
+
}
|
|
45
|
+
var DICE_PRESETS = [
|
|
46
|
+
{ id: "d6", label: "d6", notation: "1d6", category: "check", description: "Teste de per\xEDcia geral GUMSHOE: 1d6 + pontos gastos vs Dificuldade (padr\xE3o 4)." },
|
|
47
|
+
{ id: "d6+1", label: "d6+1", notation: "1d6+1", category: "check", description: "Teste com 1 ponto gasto do pool." },
|
|
48
|
+
{ id: "d6+2", label: "d6+2", notation: "1d6+2", category: "check", description: "Teste com 2 pontos gastos." },
|
|
49
|
+
{ id: "d6+3", label: "d6+3", notation: "1d6+3", category: "check", description: "Teste com 3 pontos gastos." },
|
|
50
|
+
{ id: "d6+4", label: "d6+4", notation: "1d6+4", category: "check", description: "Teste com 4 pontos gastos." },
|
|
51
|
+
{ id: "damage-d6-2", label: "Dano d6\u22122", notation: "1d6-2", category: "damage", description: "Soco/chute desarmado t\xEDpico." },
|
|
52
|
+
{ id: "damage-d6-1", label: "Dano d6\u22121", notation: "1d6-1", category: "damage", description: "Faca pequena." },
|
|
53
|
+
{ id: "damage-d6", label: "Dano d6", notation: "1d6", category: "damage", description: "Pistola leve/faca grande." },
|
|
54
|
+
{ id: "damage-d6+1", label: "Dano d6+1", notation: "1d6+1", category: "damage", description: "Pistola pesada/arma de cano longo." },
|
|
55
|
+
{ id: "damage-d6+2", label: "Dano d6+2", notation: "1d6+2", category: "damage", description: "Espingarda \xE0 queima-roupa." }
|
|
56
|
+
];
|
|
57
|
+
var CONDITIONS = [
|
|
58
|
+
{
|
|
59
|
+
id: "hurt",
|
|
60
|
+
label: "Hurt",
|
|
61
|
+
summary: "Ferido \u2014 penalidades em testes envolvendo esfor\xE7o f\xEDsico at\xE9 receber cuidados."
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: "seriously-wounded",
|
|
65
|
+
label: "Seriously Wounded",
|
|
66
|
+
summary: "Gravemente ferido \u2014 em risco de morrer; a\xE7\xF5es limitadas at\xE9 estabilizar."
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: "shaken",
|
|
70
|
+
label: "Shaken",
|
|
71
|
+
summary: "Abalado \u2014 penalidades em testes mentais at\xE9 se recompor."
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "stunned",
|
|
75
|
+
label: "Stunned",
|
|
76
|
+
summary: "Atordoado \u2014 perde a pr\xF3xima a\xE7\xE3o significativa."
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: "unconscious",
|
|
80
|
+
label: "Unconscious",
|
|
81
|
+
summary: "Inconsciente \u2014 n\xE3o age, n\xE3o percebe; vulner\xE1vel."
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: "insane",
|
|
85
|
+
label: "Insane",
|
|
86
|
+
summary: "Insanidade tempor\xE1ria ou permanente \u2014 comportamento determinado pelo GM ou trauma."
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "pursued",
|
|
90
|
+
label: "Pursued",
|
|
91
|
+
summary: "Sob persegui\xE7\xE3o \u2014 encontros aleat\xF3rios mais frequentes at\xE9 despistar."
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: "connected",
|
|
95
|
+
label: "Connected",
|
|
96
|
+
summary: "Em contato com o sobrenatural/anomalia \u2014 risco de Stability/Sanity loss em cenas adjacentes."
|
|
97
|
+
}
|
|
98
|
+
];
|
|
99
|
+
var TRACKER_FIELDS = [
|
|
100
|
+
{
|
|
101
|
+
key: "stability",
|
|
102
|
+
label: "Estab",
|
|
103
|
+
kind: "integer",
|
|
104
|
+
min: -12,
|
|
105
|
+
max: 20,
|
|
106
|
+
default: 8,
|
|
107
|
+
description: "Estabilidade emocional \u2014 perda em encontros mentalmente abalando."
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
key: "sanity",
|
|
111
|
+
label: "Sanid",
|
|
112
|
+
kind: "integer",
|
|
113
|
+
min: 0,
|
|
114
|
+
max: 15,
|
|
115
|
+
default: 10,
|
|
116
|
+
description: "Sanidade de longo prazo \u2014 esgotar pode ser permanente."
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
key: "athletics",
|
|
120
|
+
label: "Atlet",
|
|
121
|
+
kind: "integer",
|
|
122
|
+
min: 0,
|
|
123
|
+
max: 20,
|
|
124
|
+
default: 8,
|
|
125
|
+
description: "Pool da per\xEDcia geral Athletics (gasto em testes f\xEDsicos/movimento)."
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
key: "sense-trouble",
|
|
129
|
+
label: "STro",
|
|
130
|
+
kind: "integer",
|
|
131
|
+
min: 0,
|
|
132
|
+
max: 20,
|
|
133
|
+
default: 6,
|
|
134
|
+
description: "Pool da per\xEDcia Sense Trouble (gasto em testes de percep\xE7\xE3o/iniciativa)."
|
|
135
|
+
}
|
|
136
|
+
];
|
|
137
|
+
function rollGeneralTest({ spend = 0, difficulty = 4 }) {
|
|
138
|
+
const d6 = roll(6)[0];
|
|
139
|
+
const spent = Math.max(0, Math.trunc(spend));
|
|
140
|
+
const total = d6 + spent;
|
|
141
|
+
const notes = [];
|
|
142
|
+
notes.push(total >= difficulty ? "sucesso" : "falha");
|
|
143
|
+
notes.push(`DC ${difficulty}`);
|
|
144
|
+
if (spent > 0) notes.push(`gastou ${spent} do pool`);
|
|
145
|
+
if (d6 === 6) notes.push("6 natural");
|
|
146
|
+
return {
|
|
147
|
+
rolls: [d6],
|
|
148
|
+
modifier: spent,
|
|
149
|
+
total,
|
|
150
|
+
notation: spent === 0 ? "1d6" : `1d6+${spent}`,
|
|
151
|
+
notes
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function rollStabilityTest({ spend = 0, difficulty = 4 }) {
|
|
155
|
+
const r = rollGeneralTest({ spend, difficulty });
|
|
156
|
+
return {
|
|
157
|
+
...r,
|
|
158
|
+
notes: ["teste de Estabilidade", ...r.notes ?? []]
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function rollDamage({ modifier = 0 }) {
|
|
162
|
+
const d6 = roll(6)[0];
|
|
163
|
+
const total = Math.max(0, d6 + modifier);
|
|
164
|
+
const modStr = modifier === 0 ? "" : modifier > 0 ? `+${modifier}` : `${modifier}`;
|
|
165
|
+
return {
|
|
166
|
+
rolls: [d6],
|
|
167
|
+
modifier,
|
|
168
|
+
total,
|
|
169
|
+
notation: `1d6${modStr}`
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
var RULES = {
|
|
173
|
+
roll(kind, params) {
|
|
174
|
+
switch (kind) {
|
|
175
|
+
case "check":
|
|
176
|
+
case "general":
|
|
177
|
+
return rollGeneralTest(params);
|
|
178
|
+
case "stability":
|
|
179
|
+
case "sanity":
|
|
180
|
+
return rollStabilityTest(params);
|
|
181
|
+
case "damage":
|
|
182
|
+
return rollDamage(params);
|
|
183
|
+
default:
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
var gumshoe = {
|
|
189
|
+
id: "gumshoe",
|
|
190
|
+
name: "GUMSHOE",
|
|
191
|
+
ruleVersion: "SRD (CC-BY 3.0)",
|
|
192
|
+
attribution: "Based on the GUMSHOE System by Robin D. Laws, published by Pelgrane Press under the Creative Commons Attribution 3.0 Unported License (https://creativecommons.org/licenses/by/3.0/).",
|
|
193
|
+
dicePresets: DICE_PRESETS,
|
|
194
|
+
conditions: CONDITIONS,
|
|
195
|
+
trackerFields: TRACKER_FIELDS,
|
|
196
|
+
rules: RULES
|
|
197
|
+
};
|
|
198
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
199
|
+
0 && (module.exports = {
|
|
200
|
+
gumshoe,
|
|
201
|
+
investigativeSpend,
|
|
202
|
+
resetRoller,
|
|
203
|
+
setRoller
|
|
204
|
+
});
|
|
205
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * GUMSHOE — system genérico de investigação (Robin D. Laws / Pelgrane Press).\n *\n * Implementado a partir do GUMSHOE SRD (CC-BY 3.0 Unported, Pelgrane Press).\n * https://site.pelgranepress.com/index.php/the-gumshoe-system-reference-document/\n *\n * Este pacote cobre a MECÂNICA GENÉRICA. Produtos específicos como\n * Trail of Cthulhu, Night's Black Agents, Ashen Stars, Esoterrorists,\n * Mutant City Blues, Fear Itself são Product Identity da Pelgrane Press\n * e NÃO são incluídos aqui.\n */\n\nimport type {\n ConditionDef,\n DicePreset,\n RollResult,\n System,\n SystemRules,\n TrackerField,\n} from '@lippelt/srd-core'\n\n// ============================================================================\n// Random helper\n// ============================================================================\n\ntype Roller = (sides: number) => number\n\nlet roller: Roller = (sides: number) => Math.floor(Math.random() * sides) + 1\n\nexport function setRoller(fn: Roller): void {\n roller = fn\n}\n\nexport function resetRoller(): void {\n roller = (sides: number) => Math.floor(Math.random() * sides) + 1\n}\n\nfunction roll(sides: number, count = 1): number[] {\n const out: number[] = []\n for (let i = 0; i < count; i++) out.push(roller(sides))\n return out\n}\n\n// ============================================================================\n// Investigative spend — não é um \"roll\", é gasto direto. Mantido aqui pra\n// documentar a outra metade do GUMSHOE: investigative abilities NÃO usam\n// dados. Achar pistas básicas é automático; gastar pontos compra cluês extras.\n// ============================================================================\n\n/**\n * Representa um \"investigative spend\": gasto direto de pontos de uma\n * perícia de investigação para ganhar informação adicional. Não rola.\n */\nexport interface InvestigativeSpend {\n ability: string\n amount: number\n /** Custo deduzido do pool da perícia. */\n cost: number\n}\n\n/**\n * Resolve um gasto de investigação. O custo é simplesmente o amount —\n * a UI subtrai do pool da perícia no tracker, se houver. Sucesso é\n * automático: GUMSHOE garante que pistas básicas estão sempre disponíveis.\n */\nexport function investigativeSpend(ability: string, amount: number): InvestigativeSpend {\n const cost = Math.max(0, Math.trunc(amount))\n return { ability: String(ability).slice(0, 40), amount: cost, cost }\n}\n\n// ============================================================================\n// Presets de dados — General Ability tests usam 1d6 + spend vs DC (default 4).\n// ============================================================================\n\nconst DICE_PRESETS: DicePreset[] = [\n { id: 'd6', label: 'd6', notation: '1d6', category: 'check', description: 'Teste de perícia geral GUMSHOE: 1d6 + pontos gastos vs Dificuldade (padrão 4).' },\n { id: 'd6+1', label: 'd6+1', notation: '1d6+1', category: 'check', description: 'Teste com 1 ponto gasto do pool.' },\n { id: 'd6+2', label: 'd6+2', notation: '1d6+2', category: 'check', description: 'Teste com 2 pontos gastos.' },\n { id: 'd6+3', label: 'd6+3', notation: '1d6+3', category: 'check', description: 'Teste com 3 pontos gastos.' },\n { id: 'd6+4', label: 'd6+4', notation: '1d6+4', category: 'check', description: 'Teste com 4 pontos gastos.' },\n { id: 'damage-d6-2', label: 'Dano d6−2', notation: '1d6-2', category: 'damage', description: 'Soco/chute desarmado típico.' },\n { id: 'damage-d6-1', label: 'Dano d6−1', notation: '1d6-1', category: 'damage', description: 'Faca pequena.' },\n { id: 'damage-d6', label: 'Dano d6', notation: '1d6', category: 'damage', description: 'Pistola leve/faca grande.' },\n { id: 'damage-d6+1', label: 'Dano d6+1', notation: '1d6+1', category: 'damage', description: 'Pistola pesada/arma de cano longo.' },\n { id: 'damage-d6+2', label: 'Dano d6+2', notation: '1d6+2', category: 'damage', description: 'Espingarda à queima-roupa.' },\n]\n\n// ============================================================================\n// Conditions — termos genéricos cobertos pelo SRD GUMSHOE\n// ============================================================================\n\nconst CONDITIONS: ConditionDef[] = [\n {\n id: 'hurt',\n label: 'Hurt',\n summary: 'Ferido — penalidades em testes envolvendo esforço físico até receber cuidados.',\n },\n {\n id: 'seriously-wounded',\n label: 'Seriously Wounded',\n summary: 'Gravemente ferido — em risco de morrer; ações limitadas até estabilizar.',\n },\n {\n id: 'shaken',\n label: 'Shaken',\n summary: 'Abalado — penalidades em testes mentais até se recompor.',\n },\n {\n id: 'stunned',\n label: 'Stunned',\n summary: 'Atordoado — perde a próxima ação significativa.',\n },\n {\n id: 'unconscious',\n label: 'Unconscious',\n summary: 'Inconsciente — não age, não percebe; vulnerável.',\n },\n {\n id: 'insane',\n label: 'Insane',\n summary: 'Insanidade temporária ou permanente — comportamento determinado pelo GM ou trauma.',\n },\n {\n id: 'pursued',\n label: 'Pursued',\n summary: 'Sob perseguição — encontros aleatórios mais frequentes até despistar.',\n },\n {\n id: 'connected',\n label: 'Connected',\n summary: 'Em contato com o sobrenatural/anomalia — risco de Stability/Sanity loss em cenas adjacentes.',\n },\n]\n\n// ============================================================================\n// Tracker fields — pools comuns do GUMSHOE\n// ============================================================================\n\nconst TRACKER_FIELDS: TrackerField[] = [\n {\n key: 'stability',\n label: 'Estab',\n kind: 'integer',\n min: -12,\n max: 20,\n default: 8,\n description: 'Estabilidade emocional — perda em encontros mentalmente abalando.',\n },\n {\n key: 'sanity',\n label: 'Sanid',\n kind: 'integer',\n min: 0,\n max: 15,\n default: 10,\n description: 'Sanidade de longo prazo — esgotar pode ser permanente.',\n },\n {\n key: 'athletics',\n label: 'Atlet',\n kind: 'integer',\n min: 0,\n max: 20,\n default: 8,\n description: 'Pool da perícia geral Athletics (gasto em testes físicos/movimento).',\n },\n {\n key: 'sense-trouble',\n label: 'STro',\n kind: 'integer',\n min: 0,\n max: 20,\n default: 6,\n description: 'Pool da perícia Sense Trouble (gasto em testes de percepção/iniciativa).',\n },\n]\n\n// ============================================================================\n// Rules — General test, Stability test, damage\n// ============================================================================\n\ninterface GeneralTestParams {\n /** Pontos gastos do pool (somam ao d6). */\n spend?: number\n /** Dificuldade alvo. Padrão GUMSHOE: 4. */\n difficulty?: number\n}\n\n/**\n * Teste de perícia geral GUMSHOE: 1d6 + pontos gastos vs Dificuldade.\n * Padrão Difficulty 4. 6 natural sempre passa; 1 natural raramente é\n * tratado como falha automática (deixamos a critério do narrador).\n */\nfunction rollGeneralTest({ spend = 0, difficulty = 4 }: GeneralTestParams): RollResult {\n const d6 = roll(6)[0]!\n const spent = Math.max(0, Math.trunc(spend))\n const total = d6 + spent\n const notes: string[] = []\n notes.push(total >= difficulty ? 'sucesso' : 'falha')\n notes.push(`DC ${difficulty}`)\n if (spent > 0) notes.push(`gastou ${spent} do pool`)\n if (d6 === 6) notes.push('6 natural')\n return {\n rolls: [d6],\n modifier: spent,\n total,\n notation: spent === 0 ? '1d6' : `1d6+${spent}`,\n notes,\n }\n}\n\n/**\n * Stability test — variação semântica do General test (estabilidade emocional).\n * Mesma mecânica, mas notas mencionam \"stability\".\n */\nfunction rollStabilityTest({ spend = 0, difficulty = 4 }: GeneralTestParams): RollResult {\n const r = rollGeneralTest({ spend, difficulty })\n return {\n ...r,\n notes: ['teste de Estabilidade', ...(r.notes ?? [])],\n }\n}\n\ninterface DamageParams {\n /** Modificador da arma (-2 a +2 típico em GUMSHOE). */\n modifier?: number\n}\n\n/** Damage roll GUMSHOE: 1d6 + modificador da arma (não há armor flat). */\nfunction rollDamage({ modifier = 0 }: DamageParams): RollResult {\n const d6 = roll(6)[0]!\n const total = Math.max(0, d6 + modifier)\n const modStr = modifier === 0 ? '' : modifier > 0 ? `+${modifier}` : `${modifier}`\n return {\n rolls: [d6],\n modifier,\n total,\n notation: `1d6${modStr}`,\n }\n}\n\nconst RULES: SystemRules = {\n roll(kind, params) {\n switch (kind) {\n case 'check':\n case 'general':\n return rollGeneralTest(params as unknown as GeneralTestParams)\n case 'stability':\n case 'sanity':\n return rollStabilityTest(params as unknown as GeneralTestParams)\n case 'damage':\n return rollDamage(params as unknown as DamageParams)\n default:\n return null\n }\n },\n}\n\n// ============================================================================\n// Bundle\n// ============================================================================\n\nexport const gumshoe: System = {\n id: 'gumshoe',\n name: 'GUMSHOE',\n ruleVersion: 'SRD (CC-BY 3.0)',\n attribution:\n 'Based on the GUMSHOE System by Robin D. Laws, published by Pelgrane Press under the Creative Commons Attribution 3.0 Unported License (https://creativecommons.org/licenses/by/3.0/).',\n dicePresets: DICE_PRESETS,\n conditions: CONDITIONS,\n trackerFields: TRACKER_FIELDS,\n rules: RULES,\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { System } from '@lippelt/srd-core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* GUMSHOE — system genérico de investigação (Robin D. Laws / Pelgrane Press).
|
|
5
|
+
*
|
|
6
|
+
* Implementado a partir do GUMSHOE SRD (CC-BY 3.0 Unported, Pelgrane Press).
|
|
7
|
+
* https://site.pelgranepress.com/index.php/the-gumshoe-system-reference-document/
|
|
8
|
+
*
|
|
9
|
+
* Este pacote cobre a MECÂNICA GENÉRICA. Produtos específicos como
|
|
10
|
+
* Trail of Cthulhu, Night's Black Agents, Ashen Stars, Esoterrorists,
|
|
11
|
+
* Mutant City Blues, Fear Itself são Product Identity da Pelgrane Press
|
|
12
|
+
* e NÃO são incluídos aqui.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
type Roller = (sides: number) => number;
|
|
16
|
+
declare function setRoller(fn: Roller): void;
|
|
17
|
+
declare function resetRoller(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Representa um "investigative spend": gasto direto de pontos de uma
|
|
20
|
+
* perícia de investigação para ganhar informação adicional. Não rola.
|
|
21
|
+
*/
|
|
22
|
+
interface InvestigativeSpend {
|
|
23
|
+
ability: string;
|
|
24
|
+
amount: number;
|
|
25
|
+
/** Custo deduzido do pool da perícia. */
|
|
26
|
+
cost: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve um gasto de investigação. O custo é simplesmente o amount —
|
|
30
|
+
* a UI subtrai do pool da perícia no tracker, se houver. Sucesso é
|
|
31
|
+
* automático: GUMSHOE garante que pistas básicas estão sempre disponíveis.
|
|
32
|
+
*/
|
|
33
|
+
declare function investigativeSpend(ability: string, amount: number): InvestigativeSpend;
|
|
34
|
+
declare const gumshoe: System;
|
|
35
|
+
|
|
36
|
+
export { type InvestigativeSpend, gumshoe, investigativeSpend, resetRoller, setRoller };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { System } from '@lippelt/srd-core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* GUMSHOE — system genérico de investigação (Robin D. Laws / Pelgrane Press).
|
|
5
|
+
*
|
|
6
|
+
* Implementado a partir do GUMSHOE SRD (CC-BY 3.0 Unported, Pelgrane Press).
|
|
7
|
+
* https://site.pelgranepress.com/index.php/the-gumshoe-system-reference-document/
|
|
8
|
+
*
|
|
9
|
+
* Este pacote cobre a MECÂNICA GENÉRICA. Produtos específicos como
|
|
10
|
+
* Trail of Cthulhu, Night's Black Agents, Ashen Stars, Esoterrorists,
|
|
11
|
+
* Mutant City Blues, Fear Itself são Product Identity da Pelgrane Press
|
|
12
|
+
* e NÃO são incluídos aqui.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
type Roller = (sides: number) => number;
|
|
16
|
+
declare function setRoller(fn: Roller): void;
|
|
17
|
+
declare function resetRoller(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Representa um "investigative spend": gasto direto de pontos de uma
|
|
20
|
+
* perícia de investigação para ganhar informação adicional. Não rola.
|
|
21
|
+
*/
|
|
22
|
+
interface InvestigativeSpend {
|
|
23
|
+
ability: string;
|
|
24
|
+
amount: number;
|
|
25
|
+
/** Custo deduzido do pool da perícia. */
|
|
26
|
+
cost: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve um gasto de investigação. O custo é simplesmente o amount —
|
|
30
|
+
* a UI subtrai do pool da perícia no tracker, se houver. Sucesso é
|
|
31
|
+
* automático: GUMSHOE garante que pistas básicas estão sempre disponíveis.
|
|
32
|
+
*/
|
|
33
|
+
declare function investigativeSpend(ability: string, amount: number): InvestigativeSpend;
|
|
34
|
+
declare const gumshoe: System;
|
|
35
|
+
|
|
36
|
+
export { type InvestigativeSpend, gumshoe, investigativeSpend, resetRoller, setRoller };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var roller = (sides) => Math.floor(Math.random() * sides) + 1;
|
|
3
|
+
function setRoller(fn) {
|
|
4
|
+
roller = fn;
|
|
5
|
+
}
|
|
6
|
+
function resetRoller() {
|
|
7
|
+
roller = (sides) => Math.floor(Math.random() * sides) + 1;
|
|
8
|
+
}
|
|
9
|
+
function roll(sides, count = 1) {
|
|
10
|
+
const out = [];
|
|
11
|
+
for (let i = 0; i < count; i++) out.push(roller(sides));
|
|
12
|
+
return out;
|
|
13
|
+
}
|
|
14
|
+
function investigativeSpend(ability, amount) {
|
|
15
|
+
const cost = Math.max(0, Math.trunc(amount));
|
|
16
|
+
return { ability: String(ability).slice(0, 40), amount: cost, cost };
|
|
17
|
+
}
|
|
18
|
+
var DICE_PRESETS = [
|
|
19
|
+
{ id: "d6", label: "d6", notation: "1d6", category: "check", description: "Teste de per\xEDcia geral GUMSHOE: 1d6 + pontos gastos vs Dificuldade (padr\xE3o 4)." },
|
|
20
|
+
{ id: "d6+1", label: "d6+1", notation: "1d6+1", category: "check", description: "Teste com 1 ponto gasto do pool." },
|
|
21
|
+
{ id: "d6+2", label: "d6+2", notation: "1d6+2", category: "check", description: "Teste com 2 pontos gastos." },
|
|
22
|
+
{ id: "d6+3", label: "d6+3", notation: "1d6+3", category: "check", description: "Teste com 3 pontos gastos." },
|
|
23
|
+
{ id: "d6+4", label: "d6+4", notation: "1d6+4", category: "check", description: "Teste com 4 pontos gastos." },
|
|
24
|
+
{ id: "damage-d6-2", label: "Dano d6\u22122", notation: "1d6-2", category: "damage", description: "Soco/chute desarmado t\xEDpico." },
|
|
25
|
+
{ id: "damage-d6-1", label: "Dano d6\u22121", notation: "1d6-1", category: "damage", description: "Faca pequena." },
|
|
26
|
+
{ id: "damage-d6", label: "Dano d6", notation: "1d6", category: "damage", description: "Pistola leve/faca grande." },
|
|
27
|
+
{ id: "damage-d6+1", label: "Dano d6+1", notation: "1d6+1", category: "damage", description: "Pistola pesada/arma de cano longo." },
|
|
28
|
+
{ id: "damage-d6+2", label: "Dano d6+2", notation: "1d6+2", category: "damage", description: "Espingarda \xE0 queima-roupa." }
|
|
29
|
+
];
|
|
30
|
+
var CONDITIONS = [
|
|
31
|
+
{
|
|
32
|
+
id: "hurt",
|
|
33
|
+
label: "Hurt",
|
|
34
|
+
summary: "Ferido \u2014 penalidades em testes envolvendo esfor\xE7o f\xEDsico at\xE9 receber cuidados."
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: "seriously-wounded",
|
|
38
|
+
label: "Seriously Wounded",
|
|
39
|
+
summary: "Gravemente ferido \u2014 em risco de morrer; a\xE7\xF5es limitadas at\xE9 estabilizar."
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "shaken",
|
|
43
|
+
label: "Shaken",
|
|
44
|
+
summary: "Abalado \u2014 penalidades em testes mentais at\xE9 se recompor."
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: "stunned",
|
|
48
|
+
label: "Stunned",
|
|
49
|
+
summary: "Atordoado \u2014 perde a pr\xF3xima a\xE7\xE3o significativa."
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "unconscious",
|
|
53
|
+
label: "Unconscious",
|
|
54
|
+
summary: "Inconsciente \u2014 n\xE3o age, n\xE3o percebe; vulner\xE1vel."
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: "insane",
|
|
58
|
+
label: "Insane",
|
|
59
|
+
summary: "Insanidade tempor\xE1ria ou permanente \u2014 comportamento determinado pelo GM ou trauma."
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: "pursued",
|
|
63
|
+
label: "Pursued",
|
|
64
|
+
summary: "Sob persegui\xE7\xE3o \u2014 encontros aleat\xF3rios mais frequentes at\xE9 despistar."
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "connected",
|
|
68
|
+
label: "Connected",
|
|
69
|
+
summary: "Em contato com o sobrenatural/anomalia \u2014 risco de Stability/Sanity loss em cenas adjacentes."
|
|
70
|
+
}
|
|
71
|
+
];
|
|
72
|
+
var TRACKER_FIELDS = [
|
|
73
|
+
{
|
|
74
|
+
key: "stability",
|
|
75
|
+
label: "Estab",
|
|
76
|
+
kind: "integer",
|
|
77
|
+
min: -12,
|
|
78
|
+
max: 20,
|
|
79
|
+
default: 8,
|
|
80
|
+
description: "Estabilidade emocional \u2014 perda em encontros mentalmente abalando."
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
key: "sanity",
|
|
84
|
+
label: "Sanid",
|
|
85
|
+
kind: "integer",
|
|
86
|
+
min: 0,
|
|
87
|
+
max: 15,
|
|
88
|
+
default: 10,
|
|
89
|
+
description: "Sanidade de longo prazo \u2014 esgotar pode ser permanente."
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
key: "athletics",
|
|
93
|
+
label: "Atlet",
|
|
94
|
+
kind: "integer",
|
|
95
|
+
min: 0,
|
|
96
|
+
max: 20,
|
|
97
|
+
default: 8,
|
|
98
|
+
description: "Pool da per\xEDcia geral Athletics (gasto em testes f\xEDsicos/movimento)."
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
key: "sense-trouble",
|
|
102
|
+
label: "STro",
|
|
103
|
+
kind: "integer",
|
|
104
|
+
min: 0,
|
|
105
|
+
max: 20,
|
|
106
|
+
default: 6,
|
|
107
|
+
description: "Pool da per\xEDcia Sense Trouble (gasto em testes de percep\xE7\xE3o/iniciativa)."
|
|
108
|
+
}
|
|
109
|
+
];
|
|
110
|
+
function rollGeneralTest({ spend = 0, difficulty = 4 }) {
|
|
111
|
+
const d6 = roll(6)[0];
|
|
112
|
+
const spent = Math.max(0, Math.trunc(spend));
|
|
113
|
+
const total = d6 + spent;
|
|
114
|
+
const notes = [];
|
|
115
|
+
notes.push(total >= difficulty ? "sucesso" : "falha");
|
|
116
|
+
notes.push(`DC ${difficulty}`);
|
|
117
|
+
if (spent > 0) notes.push(`gastou ${spent} do pool`);
|
|
118
|
+
if (d6 === 6) notes.push("6 natural");
|
|
119
|
+
return {
|
|
120
|
+
rolls: [d6],
|
|
121
|
+
modifier: spent,
|
|
122
|
+
total,
|
|
123
|
+
notation: spent === 0 ? "1d6" : `1d6+${spent}`,
|
|
124
|
+
notes
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function rollStabilityTest({ spend = 0, difficulty = 4 }) {
|
|
128
|
+
const r = rollGeneralTest({ spend, difficulty });
|
|
129
|
+
return {
|
|
130
|
+
...r,
|
|
131
|
+
notes: ["teste de Estabilidade", ...r.notes ?? []]
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function rollDamage({ modifier = 0 }) {
|
|
135
|
+
const d6 = roll(6)[0];
|
|
136
|
+
const total = Math.max(0, d6 + modifier);
|
|
137
|
+
const modStr = modifier === 0 ? "" : modifier > 0 ? `+${modifier}` : `${modifier}`;
|
|
138
|
+
return {
|
|
139
|
+
rolls: [d6],
|
|
140
|
+
modifier,
|
|
141
|
+
total,
|
|
142
|
+
notation: `1d6${modStr}`
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
var RULES = {
|
|
146
|
+
roll(kind, params) {
|
|
147
|
+
switch (kind) {
|
|
148
|
+
case "check":
|
|
149
|
+
case "general":
|
|
150
|
+
return rollGeneralTest(params);
|
|
151
|
+
case "stability":
|
|
152
|
+
case "sanity":
|
|
153
|
+
return rollStabilityTest(params);
|
|
154
|
+
case "damage":
|
|
155
|
+
return rollDamage(params);
|
|
156
|
+
default:
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
var gumshoe = {
|
|
162
|
+
id: "gumshoe",
|
|
163
|
+
name: "GUMSHOE",
|
|
164
|
+
ruleVersion: "SRD (CC-BY 3.0)",
|
|
165
|
+
attribution: "Based on the GUMSHOE System by Robin D. Laws, published by Pelgrane Press under the Creative Commons Attribution 3.0 Unported License (https://creativecommons.org/licenses/by/3.0/).",
|
|
166
|
+
dicePresets: DICE_PRESETS,
|
|
167
|
+
conditions: CONDITIONS,
|
|
168
|
+
trackerFields: TRACKER_FIELDS,
|
|
169
|
+
rules: RULES
|
|
170
|
+
};
|
|
171
|
+
export {
|
|
172
|
+
gumshoe,
|
|
173
|
+
investigativeSpend,
|
|
174
|
+
resetRoller,
|
|
175
|
+
setRoller
|
|
176
|
+
};
|
|
177
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * GUMSHOE — system genérico de investigação (Robin D. Laws / Pelgrane Press).\n *\n * Implementado a partir do GUMSHOE SRD (CC-BY 3.0 Unported, Pelgrane Press).\n * https://site.pelgranepress.com/index.php/the-gumshoe-system-reference-document/\n *\n * Este pacote cobre a MECÂNICA GENÉRICA. Produtos específicos como\n * Trail of Cthulhu, Night's Black Agents, Ashen Stars, Esoterrorists,\n * Mutant City Blues, Fear Itself são Product Identity da Pelgrane Press\n * e NÃO são incluídos aqui.\n */\n\nimport type {\n ConditionDef,\n DicePreset,\n RollResult,\n System,\n SystemRules,\n TrackerField,\n} from '@lippelt/srd-core'\n\n// ============================================================================\n// Random helper\n// ============================================================================\n\ntype Roller = (sides: number) => number\n\nlet roller: Roller = (sides: number) => Math.floor(Math.random() * sides) + 1\n\nexport function setRoller(fn: Roller): void {\n roller = fn\n}\n\nexport function resetRoller(): void {\n roller = (sides: number) => Math.floor(Math.random() * sides) + 1\n}\n\nfunction roll(sides: number, count = 1): number[] {\n const out: number[] = []\n for (let i = 0; i < count; i++) out.push(roller(sides))\n return out\n}\n\n// ============================================================================\n// Investigative spend — não é um \"roll\", é gasto direto. Mantido aqui pra\n// documentar a outra metade do GUMSHOE: investigative abilities NÃO usam\n// dados. Achar pistas básicas é automático; gastar pontos compra cluês extras.\n// ============================================================================\n\n/**\n * Representa um \"investigative spend\": gasto direto de pontos de uma\n * perícia de investigação para ganhar informação adicional. Não rola.\n */\nexport interface InvestigativeSpend {\n ability: string\n amount: number\n /** Custo deduzido do pool da perícia. */\n cost: number\n}\n\n/**\n * Resolve um gasto de investigação. O custo é simplesmente o amount —\n * a UI subtrai do pool da perícia no tracker, se houver. Sucesso é\n * automático: GUMSHOE garante que pistas básicas estão sempre disponíveis.\n */\nexport function investigativeSpend(ability: string, amount: number): InvestigativeSpend {\n const cost = Math.max(0, Math.trunc(amount))\n return { ability: String(ability).slice(0, 40), amount: cost, cost }\n}\n\n// ============================================================================\n// Presets de dados — General Ability tests usam 1d6 + spend vs DC (default 4).\n// ============================================================================\n\nconst DICE_PRESETS: DicePreset[] = [\n { id: 'd6', label: 'd6', notation: '1d6', category: 'check', description: 'Teste de perícia geral GUMSHOE: 1d6 + pontos gastos vs Dificuldade (padrão 4).' },\n { id: 'd6+1', label: 'd6+1', notation: '1d6+1', category: 'check', description: 'Teste com 1 ponto gasto do pool.' },\n { id: 'd6+2', label: 'd6+2', notation: '1d6+2', category: 'check', description: 'Teste com 2 pontos gastos.' },\n { id: 'd6+3', label: 'd6+3', notation: '1d6+3', category: 'check', description: 'Teste com 3 pontos gastos.' },\n { id: 'd6+4', label: 'd6+4', notation: '1d6+4', category: 'check', description: 'Teste com 4 pontos gastos.' },\n { id: 'damage-d6-2', label: 'Dano d6−2', notation: '1d6-2', category: 'damage', description: 'Soco/chute desarmado típico.' },\n { id: 'damage-d6-1', label: 'Dano d6−1', notation: '1d6-1', category: 'damage', description: 'Faca pequena.' },\n { id: 'damage-d6', label: 'Dano d6', notation: '1d6', category: 'damage', description: 'Pistola leve/faca grande.' },\n { id: 'damage-d6+1', label: 'Dano d6+1', notation: '1d6+1', category: 'damage', description: 'Pistola pesada/arma de cano longo.' },\n { id: 'damage-d6+2', label: 'Dano d6+2', notation: '1d6+2', category: 'damage', description: 'Espingarda à queima-roupa.' },\n]\n\n// ============================================================================\n// Conditions — termos genéricos cobertos pelo SRD GUMSHOE\n// ============================================================================\n\nconst CONDITIONS: ConditionDef[] = [\n {\n id: 'hurt',\n label: 'Hurt',\n summary: 'Ferido — penalidades em testes envolvendo esforço físico até receber cuidados.',\n },\n {\n id: 'seriously-wounded',\n label: 'Seriously Wounded',\n summary: 'Gravemente ferido — em risco de morrer; ações limitadas até estabilizar.',\n },\n {\n id: 'shaken',\n label: 'Shaken',\n summary: 'Abalado — penalidades em testes mentais até se recompor.',\n },\n {\n id: 'stunned',\n label: 'Stunned',\n summary: 'Atordoado — perde a próxima ação significativa.',\n },\n {\n id: 'unconscious',\n label: 'Unconscious',\n summary: 'Inconsciente — não age, não percebe; vulnerável.',\n },\n {\n id: 'insane',\n label: 'Insane',\n summary: 'Insanidade temporária ou permanente — comportamento determinado pelo GM ou trauma.',\n },\n {\n id: 'pursued',\n label: 'Pursued',\n summary: 'Sob perseguição — encontros aleatórios mais frequentes até despistar.',\n },\n {\n id: 'connected',\n label: 'Connected',\n summary: 'Em contato com o sobrenatural/anomalia — risco de Stability/Sanity loss em cenas adjacentes.',\n },\n]\n\n// ============================================================================\n// Tracker fields — pools comuns do GUMSHOE\n// ============================================================================\n\nconst TRACKER_FIELDS: TrackerField[] = [\n {\n key: 'stability',\n label: 'Estab',\n kind: 'integer',\n min: -12,\n max: 20,\n default: 8,\n description: 'Estabilidade emocional — perda em encontros mentalmente abalando.',\n },\n {\n key: 'sanity',\n label: 'Sanid',\n kind: 'integer',\n min: 0,\n max: 15,\n default: 10,\n description: 'Sanidade de longo prazo — esgotar pode ser permanente.',\n },\n {\n key: 'athletics',\n label: 'Atlet',\n kind: 'integer',\n min: 0,\n max: 20,\n default: 8,\n description: 'Pool da perícia geral Athletics (gasto em testes físicos/movimento).',\n },\n {\n key: 'sense-trouble',\n label: 'STro',\n kind: 'integer',\n min: 0,\n max: 20,\n default: 6,\n description: 'Pool da perícia Sense Trouble (gasto em testes de percepção/iniciativa).',\n },\n]\n\n// ============================================================================\n// Rules — General test, Stability test, damage\n// ============================================================================\n\ninterface GeneralTestParams {\n /** Pontos gastos do pool (somam ao d6). */\n spend?: number\n /** Dificuldade alvo. Padrão GUMSHOE: 4. */\n difficulty?: number\n}\n\n/**\n * Teste de perícia geral GUMSHOE: 1d6 + pontos gastos vs Dificuldade.\n * Padrão Difficulty 4. 6 natural sempre passa; 1 natural raramente é\n * tratado como falha automática (deixamos a critério do narrador).\n */\nfunction rollGeneralTest({ spend = 0, difficulty = 4 }: GeneralTestParams): RollResult {\n const d6 = roll(6)[0]!\n const spent = Math.max(0, Math.trunc(spend))\n const total = d6 + spent\n const notes: string[] = []\n notes.push(total >= difficulty ? 'sucesso' : 'falha')\n notes.push(`DC ${difficulty}`)\n if (spent > 0) notes.push(`gastou ${spent} do pool`)\n if (d6 === 6) notes.push('6 natural')\n return {\n rolls: [d6],\n modifier: spent,\n total,\n notation: spent === 0 ? '1d6' : `1d6+${spent}`,\n notes,\n }\n}\n\n/**\n * Stability test — variação semântica do General test (estabilidade emocional).\n * Mesma mecânica, mas notas mencionam \"stability\".\n */\nfunction rollStabilityTest({ spend = 0, difficulty = 4 }: GeneralTestParams): RollResult {\n const r = rollGeneralTest({ spend, difficulty })\n return {\n ...r,\n notes: ['teste de Estabilidade', ...(r.notes ?? [])],\n }\n}\n\ninterface DamageParams {\n /** Modificador da arma (-2 a +2 típico em GUMSHOE). */\n modifier?: number\n}\n\n/** Damage roll GUMSHOE: 1d6 + modificador da arma (não há armor flat). */\nfunction rollDamage({ modifier = 0 }: DamageParams): RollResult {\n const d6 = roll(6)[0]!\n const total = Math.max(0, d6 + modifier)\n const modStr = modifier === 0 ? '' : modifier > 0 ? `+${modifier}` : `${modifier}`\n return {\n rolls: [d6],\n modifier,\n total,\n notation: `1d6${modStr}`,\n }\n}\n\nconst RULES: SystemRules = {\n roll(kind, params) {\n switch (kind) {\n case 'check':\n case 'general':\n return rollGeneralTest(params as unknown as GeneralTestParams)\n case 'stability':\n case 'sanity':\n return rollStabilityTest(params as unknown as GeneralTestParams)\n case 'damage':\n return rollDamage(params as unknown as DamageParams)\n default:\n return null\n }\n },\n}\n\n// ============================================================================\n// Bundle\n// ============================================================================\n\nexport const gumshoe: System = {\n id: 'gumshoe',\n name: 'GUMSHOE',\n ruleVersion: 'SRD (CC-BY 3.0)',\n attribution:\n 'Based on the GUMSHOE System by Robin D. Laws, published by Pelgrane Press under the Creative Commons Attribution 3.0 Unported License (https://creativecommons.org/licenses/by/3.0/).',\n dicePresets: DICE_PRESETS,\n conditions: CONDITIONS,\n trackerFields: TRACKER_FIELDS,\n rules: RULES,\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lippelt/srd-gumshoe",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "GUMSHOE system module for @lippelt/srd-core — investigative & general ability mechanics, CC-BY 3.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsup",
|
|
26
|
+
"dev": "tsup --watch",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"lint": "eslint .",
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"test:watch": "vitest"
|
|
31
|
+
},
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/flippelt/gmcr-srd-systems.git",
|
|
36
|
+
"directory": "packages/gumshoe"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@lippelt/srd-core": "^0.1.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@lippelt/srd-core": "*"
|
|
43
|
+
}
|
|
44
|
+
}
|