@lippelt/srd-dnd5e-2024 0.1.1 → 1.0.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/CHANGELOG.md +24 -0
- package/dist/index.cjs +24 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +24 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Todas as mudanças notáveis deste pacote são documentadas aqui.
|
|
4
|
+
|
|
5
|
+
O formato segue [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/)
|
|
6
|
+
e o projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR/).
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## [1.0.0] — 2026-07-13
|
|
10
|
+
|
|
11
|
+
### Mudou
|
|
12
|
+
- **Marco de estabilidade 1.0.0.** O contrato público do pacote é
|
|
13
|
+
promovido a estável — sem mudanças de API em relação à série 0.1.x.
|
|
14
|
+
A partir daqui, quebras de compatibilidade seguem SemVer (major).
|
|
15
|
+
- `peerDependencies`: `@lippelt/srd-core` de `^0.1.0` → `^1.0.0`.
|
|
16
|
+
|
|
17
|
+
## [0.1.2] — 2026-06-06
|
|
18
|
+
- Release de manutenção (sincronização de versão).
|
|
19
|
+
|
|
20
|
+
## [0.1.1] — 2026-06-05
|
|
21
|
+
- Docs: README em PT-BR com termos oficiais.
|
|
22
|
+
|
|
23
|
+
## [0.1.0] — 2026-06-04
|
|
24
|
+
- Primeira publicação no npm.
|
package/dist/index.cjs
CHANGED
|
@@ -215,6 +215,26 @@ var RULES = {
|
|
|
215
215
|
return applyDndDamage(incoming, target);
|
|
216
216
|
}
|
|
217
217
|
};
|
|
218
|
+
var DND5E_2024_SKILLS = [
|
|
219
|
+
"acrobatics",
|
|
220
|
+
"animal-handling",
|
|
221
|
+
"arcana",
|
|
222
|
+
"athletics",
|
|
223
|
+
"deception",
|
|
224
|
+
"history",
|
|
225
|
+
"insight",
|
|
226
|
+
"intimidation",
|
|
227
|
+
"investigation",
|
|
228
|
+
"medicine",
|
|
229
|
+
"nature",
|
|
230
|
+
"perception",
|
|
231
|
+
"performance",
|
|
232
|
+
"persuasion",
|
|
233
|
+
"religion",
|
|
234
|
+
"sleight-of-hand",
|
|
235
|
+
"stealth",
|
|
236
|
+
"survival"
|
|
237
|
+
];
|
|
218
238
|
var dnd5e2024 = {
|
|
219
239
|
id: "dnd5e-2024",
|
|
220
240
|
name: "Dungeons & Dragons 5e (2024)",
|
|
@@ -223,7 +243,10 @@ var dnd5e2024 = {
|
|
|
223
243
|
dicePresets: DICE_PRESETS,
|
|
224
244
|
conditions: CONDITIONS,
|
|
225
245
|
trackerFields: TRACKER_FIELDS,
|
|
226
|
-
rules: RULES
|
|
246
|
+
rules: RULES,
|
|
247
|
+
npc: {
|
|
248
|
+
skills: DND5E_2024_SKILLS
|
|
249
|
+
}
|
|
227
250
|
};
|
|
228
251
|
// Annotate the CommonJS export names for ESM import in node:
|
|
229
252
|
0 && (module.exports = {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Dungeons & Dragons 5th Edition (2024 / \"One D&D\").\n *\n * Conteúdo de regras deriva do System Reference Document 5.2, publicado\n * pela Wizards of the Coast LLC sob a Creative Commons Attribution 4.0\n * International License:\n * https://creativecommons.org/licenses/by/4.0/legalcode\n *\n * Mantém compatibilidade mecânica com a edição 2014 — o que mudou:\n * - Exhaustion: agora uma escala 1..10 com −2 cumulativo em d20 tests\n * (era 6 níveis discretos)\n * - Algumas condições com wording refinado\n * - Math de combate (advantage, attack vs AC, saves, crítico) é igual\n *\n * Esta implementação é original (referência conceitual: foundryvtt/dnd5e,\n * MIT). Para spells e features de classe, use o SRD 5.2 oficial.\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 — injetável pra testes determinísticos.\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// Presets de dados (idênticos aos 2014)\n// ============================================================================\n\nconst DICE_PRESETS: DicePreset[] = [\n { id: 'd20', label: 'd20', notation: '1d20', category: 'check' },\n { id: 'd20-adv', label: 'd20 (adv.)', notation: 'advantage', category: 'check', description: 'Rola 2d20 e pega o maior.' },\n { id: 'd20-dis', label: 'd20 (desv.)', notation: 'disadvantage', category: 'check', description: 'Rola 2d20 e pega o menor.' },\n { id: 'd4', label: 'd4', notation: '1d4', category: 'damage' },\n { id: 'd6', label: 'd6', notation: '1d6', category: 'damage' },\n { id: 'd8', label: 'd8', notation: '1d8', category: 'damage' },\n { id: 'd10', label: 'd10', notation: '1d10', category: 'damage' },\n { id: 'd12', label: 'd12', notation: '1d12', category: 'damage' },\n { id: 'd100', label: 'd100', notation: '1d100', category: 'special' },\n]\n\n// ============================================================================\n// Condições — SRD 5.2 (CC-BY 4.0)\n//\n// Mudança principal vs 5.1: Exhaustion é uma escala única 1..10, cada nível\n// dá −2 acumulativo em d20 tests; nível 10 = morte.\n// ============================================================================\n\nconst CONDITIONS: ConditionDef[] = [\n { id: 'blinded', label: 'Blinded', summary: 'Cego: falha em testes que exigem visão; atacantes têm vantagem; o cego tem desvantagem.' },\n { id: 'charmed', label: 'Charmed', summary: 'Enfeitiçado: não pode atacar o encantador nem usar habilidades nocivas contra ele.' },\n { id: 'deafened', label: 'Deafened', summary: 'Surdo: falha em testes que dependem de audição.' },\n { id: 'exhaustion', label: 'Exhaustion (level)', summary: 'Exaustão (1..10): −2 acumulativo em todos os testes de d20 por nível; nível 10 = morte.' },\n { id: 'frightened', label: 'Frightened', summary: 'Amedrontado: desvantagem se a fonte do medo estiver à vista; não pode se mover para perto dela.' },\n { id: 'grappled', label: 'Grappled', summary: 'Agarrado: velocidade 0; termina se o agarrador ficar incapacitado ou afastado.' },\n { id: 'incapacitated', label: 'Incapacitated', summary: 'Incapacitado: não pode tomar ações, reações nem mover-se.' },\n { id: 'invisible', label: 'Invisible', summary: 'Invisível: vantagem em ataques; atacantes têm desvantagem.' },\n { id: 'paralyzed', label: 'Paralyzed', summary: 'Paralisado: incapacitado, não pode mover/falar; ataques a até 1,5m crítico automático.' },\n { id: 'petrified', label: 'Petrified', summary: 'Petrificado: incapacitado, transformado em pedra; resistência a todo dano; imune a venenos e doenças.' },\n { id: 'poisoned', label: 'Poisoned', summary: 'Envenenado: desvantagem em ataques e testes de habilidade.' },\n { id: 'prone', label: 'Prone', summary: 'Caído: desvantagem em ataques; corpo-a-corpo contra o alvo têm vantagem; à distância têm desvantagem.' },\n { id: 'restrained', label: 'Restrained', summary: 'Contido: velocidade 0; desvantagem em ataques e em Dex saves; atacantes têm vantagem.' },\n { id: 'stunned', label: 'Stunned', summary: 'Atordoado: incapacitado; falha em Str/Dex saves; atacantes têm vantagem.' },\n { id: 'unconscious', label: 'Unconscious', summary: 'Inconsciente: incapacitado, caído; ataques a até 1,5m crítico automático.' },\n]\n\n// ============================================================================\n// Tracker fields — mesmas do 2014 (AC, death saves)\n// ============================================================================\n\nconst TRACKER_FIELDS: TrackerField[] = [\n {\n key: 'ac',\n label: 'CA',\n kind: 'integer',\n min: 1,\n max: 30,\n default: 10,\n description: 'Classe de Armadura — DC para ser atingido por ataques.',\n },\n {\n key: 'exhaustion',\n label: 'Exh',\n kind: 'integer',\n min: 0,\n max: 10,\n default: 0,\n description: 'Nível de Exhaustion (0..10). Cada ponto dá −2 cumulativo em d20 tests; 10 = morte.',\n },\n {\n key: 'deathSuccesses',\n label: 'M✓',\n kind: 'integer',\n min: 0,\n max: 3,\n default: 0,\n description: 'Sucessos em testes de resistência à morte (3 = estabilizado).',\n },\n {\n key: 'deathFailures',\n label: 'M✗',\n kind: 'integer',\n min: 0,\n max: 3,\n default: 0,\n description: 'Falhas em testes de resistência à morte (3 = morte).',\n },\n]\n\n// ============================================================================\n// Regras automatizadas\n// ============================================================================\n\nexport function abilityMod(score: number): number {\n return Math.floor((score - 10) / 2)\n}\n\nexport function spellSaveDC(proficiency: number, casterMod: number): number {\n return 8 + proficiency + casterMod\n}\n\nexport function spellAttackBonus(proficiency: number, casterMod: number): number {\n return proficiency + casterMod\n}\n\n/** Modificador de exaustão por nível (2024): −2 por nível. */\nexport function exhaustionPenalty(level: number): number {\n const clamped = Math.max(0, Math.min(10, Math.trunc(level)))\n return clamped === 0 ? 0 : -2 * clamped\n}\n\ninterface D20Params {\n modifier?: number\n advantage?: boolean\n disadvantage?: boolean\n /** Nível de exaustão (0..10). Aplica −2 por nível em todos os testes. */\n exhaustion?: number\n}\n\nfunction rollD20({\n modifier = 0,\n advantage = false,\n disadvantage = false,\n exhaustion = 0,\n}: D20Params): RollResult {\n const cancelled = advantage && disadvantage\n const useAdv = advantage && !cancelled\n const useDis = disadvantage && !cancelled\n const count = useAdv || useDis ? 2 : 1\n const dice = roll(20, count)\n const picked = useAdv ? Math.max(...dice) : useDis ? Math.min(...dice) : dice[0]!\n const exhPenalty = exhaustionPenalty(exhaustion)\n const effectiveMod = modifier + exhPenalty\n const total = picked + effectiveMod\n const notes: string[] = []\n if (cancelled) notes.push('vantagem/desvantagem se cancelaram')\n else if (useAdv) notes.push('vantagem')\n else if (useDis) notes.push('desvantagem')\n if (exhPenalty !== 0) notes.push(`exaustão ${exhaustion} (${exhPenalty})`)\n if (picked === 20) notes.push('crítico natural')\n if (picked === 1) notes.push('falha crítica')\n const modStr =\n effectiveMod === 0 ? '' : effectiveMod > 0 ? `+${effectiveMod}` : `${effectiveMod}`\n const dStr = count === 2 ? `2d20${useAdv ? 'kh1' : 'kl1'}` : '1d20'\n return { rolls: dice, modifier: effectiveMod, total, notation: `${dStr}${modStr}`, notes }\n}\n\ninterface AttackParams {\n modifier?: number\n targetAC?: number\n advantage?: boolean\n disadvantage?: boolean\n exhaustion?: number\n}\n\nfunction rollAttack(params: AttackParams): RollResult {\n const result = rollD20(params)\n const adv = params.advantage && !params.disadvantage\n const d20 =\n result.rolls.length === 2\n ? adv\n ? result.rolls[0]! >= result.rolls[1]!\n ? result.rolls[0]!\n : result.rolls[1]!\n : result.rolls[0]! <= result.rolls[1]!\n ? result.rolls[0]!\n : result.rolls[1]!\n : result.rolls[0]!\n const notes = [...(result.notes ?? [])]\n if (params.targetAC !== undefined) {\n const natural20 = d20 === 20\n const natural1 = d20 === 1\n const hit = natural20 || (!natural1 && result.total >= params.targetAC)\n notes.push(\n hit\n ? natural20\n ? 'acerto crítico'\n : 'acertou'\n : natural1\n ? 'erro crítico'\n : 'errou',\n )\n }\n return { ...result, notes }\n}\n\ninterface SaveParams {\n modifier?: number\n dc: number\n advantage?: boolean\n disadvantage?: boolean\n exhaustion?: number\n}\n\nfunction rollSave(params: SaveParams): RollResult {\n const result = rollD20(params)\n const notes = [...(result.notes ?? [])]\n notes.push(result.total >= params.dc ? 'sucesso' : 'falha')\n return { ...result, notes: notes.concat([`DC ${params.dc}`]) }\n}\n\ninterface DamageParams {\n count: number\n sides: number\n modifier?: number\n critical?: boolean\n}\n\nfunction rollDamage({ count, sides, modifier = 0, critical = false }: DamageParams): RollResult {\n const totalDice = critical ? count * 2 : count\n const dice = roll(sides, totalDice)\n const sum = dice.reduce((a, b) => a + b, 0)\n const total = Math.max(0, sum + modifier)\n const modStr = modifier === 0 ? '' : modifier > 0 ? `+${modifier}` : `${modifier}`\n return {\n rolls: dice,\n modifier,\n total,\n notation: `${totalDice}d${sides}${modStr}${critical ? ' (crit)' : ''}`,\n notes: critical ? ['dano crítico — dados dobrados'] : [],\n }\n}\n\ninterface DamageTarget {\n resistance?: string[]\n vulnerability?: string[]\n immunity?: string[]\n}\n\ninterface ApplyDamageInput {\n type?: string\n target?: DamageTarget\n}\n\nfunction applyDndDamage(\n incoming: number,\n ctx: ApplyDamageInput,\n): { final: number; notes: string[] } {\n const t = ctx.target\n const type = ctx.type\n if (!type || !t) return { final: Math.max(0, incoming), notes: [] }\n if (t.immunity?.includes(type)) return { final: 0, notes: [`imune a ${type}`] }\n if (t.resistance?.includes(type)) {\n return { final: Math.floor(incoming / 2), notes: [`resistência a ${type} (metade)`] }\n }\n if (t.vulnerability?.includes(type)) {\n return { final: incoming * 2, notes: [`vulnerabilidade a ${type} (dobro)`] }\n }\n return { final: Math.max(0, incoming), notes: [] }\n}\n\n// ============================================================================\n// Bundle\n// ============================================================================\n\nconst RULES: SystemRules = {\n roll(kind, params) {\n switch (kind) {\n case 'd20':\n case 'check':\n case 'ability':\n return rollD20(params as unknown as D20Params)\n case 'attack':\n return rollAttack(params as unknown as AttackParams)\n case 'save':\n return rollSave(params as unknown as SaveParams)\n case 'damage':\n return rollDamage(params as unknown as DamageParams)\n default:\n return null\n }\n },\n applyDamage(incoming, target) {\n return applyDndDamage(incoming, target as ApplyDamageInput)\n },\n}\n\nexport const dnd5e2024: System = {\n id: 'dnd5e-2024',\n name: 'Dungeons & Dragons 5e (2024)',\n ruleVersion: 'SRD 5.2',\n attribution:\n 'Contains material from the System Reference Document 5.2 by Wizards of the Coast LLC, licensed under CC-BY 4.0.',\n dicePresets: DICE_PRESETS,\n conditions: CONDITIONS,\n trackerFields: TRACKER_FIELDS,\n rules: RULES,\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Dungeons & Dragons 5th Edition (2024 / \"One D&D\").\n *\n * Conteúdo de regras deriva do System Reference Document 5.2, publicado\n * pela Wizards of the Coast LLC sob a Creative Commons Attribution 4.0\n * International License:\n * https://creativecommons.org/licenses/by/4.0/legalcode\n *\n * Mantém compatibilidade mecânica com a edição 2014 — o que mudou:\n * - Exhaustion: agora uma escala 1..10 com −2 cumulativo em d20 tests\n * (era 6 níveis discretos)\n * - Algumas condições com wording refinado\n * - Math de combate (advantage, attack vs AC, saves, crítico) é igual\n *\n * Esta implementação é original (referência conceitual: foundryvtt/dnd5e,\n * MIT). Para spells e features de classe, use o SRD 5.2 oficial.\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 — injetável pra testes determinísticos.\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// Presets de dados (idênticos aos 2014)\n// ============================================================================\n\nconst DICE_PRESETS: DicePreset[] = [\n { id: 'd20', label: 'd20', notation: '1d20', category: 'check' },\n { id: 'd20-adv', label: 'd20 (adv.)', notation: 'advantage', category: 'check', description: 'Rola 2d20 e pega o maior.' },\n { id: 'd20-dis', label: 'd20 (desv.)', notation: 'disadvantage', category: 'check', description: 'Rola 2d20 e pega o menor.' },\n { id: 'd4', label: 'd4', notation: '1d4', category: 'damage' },\n { id: 'd6', label: 'd6', notation: '1d6', category: 'damage' },\n { id: 'd8', label: 'd8', notation: '1d8', category: 'damage' },\n { id: 'd10', label: 'd10', notation: '1d10', category: 'damage' },\n { id: 'd12', label: 'd12', notation: '1d12', category: 'damage' },\n { id: 'd100', label: 'd100', notation: '1d100', category: 'special' },\n]\n\n// ============================================================================\n// Condições — SRD 5.2 (CC-BY 4.0)\n//\n// Mudança principal vs 5.1: Exhaustion é uma escala única 1..10, cada nível\n// dá −2 acumulativo em d20 tests; nível 10 = morte.\n// ============================================================================\n\nconst CONDITIONS: ConditionDef[] = [\n { id: 'blinded', label: 'Blinded', summary: 'Cego: falha em testes que exigem visão; atacantes têm vantagem; o cego tem desvantagem.' },\n { id: 'charmed', label: 'Charmed', summary: 'Enfeitiçado: não pode atacar o encantador nem usar habilidades nocivas contra ele.' },\n { id: 'deafened', label: 'Deafened', summary: 'Surdo: falha em testes que dependem de audição.' },\n { id: 'exhaustion', label: 'Exhaustion (level)', summary: 'Exaustão (1..10): −2 acumulativo em todos os testes de d20 por nível; nível 10 = morte.' },\n { id: 'frightened', label: 'Frightened', summary: 'Amedrontado: desvantagem se a fonte do medo estiver à vista; não pode se mover para perto dela.' },\n { id: 'grappled', label: 'Grappled', summary: 'Agarrado: velocidade 0; termina se o agarrador ficar incapacitado ou afastado.' },\n { id: 'incapacitated', label: 'Incapacitated', summary: 'Incapacitado: não pode tomar ações, reações nem mover-se.' },\n { id: 'invisible', label: 'Invisible', summary: 'Invisível: vantagem em ataques; atacantes têm desvantagem.' },\n { id: 'paralyzed', label: 'Paralyzed', summary: 'Paralisado: incapacitado, não pode mover/falar; ataques a até 1,5m crítico automático.' },\n { id: 'petrified', label: 'Petrified', summary: 'Petrificado: incapacitado, transformado em pedra; resistência a todo dano; imune a venenos e doenças.' },\n { id: 'poisoned', label: 'Poisoned', summary: 'Envenenado: desvantagem em ataques e testes de habilidade.' },\n { id: 'prone', label: 'Prone', summary: 'Caído: desvantagem em ataques; corpo-a-corpo contra o alvo têm vantagem; à distância têm desvantagem.' },\n { id: 'restrained', label: 'Restrained', summary: 'Contido: velocidade 0; desvantagem em ataques e em Dex saves; atacantes têm vantagem.' },\n { id: 'stunned', label: 'Stunned', summary: 'Atordoado: incapacitado; falha em Str/Dex saves; atacantes têm vantagem.' },\n { id: 'unconscious', label: 'Unconscious', summary: 'Inconsciente: incapacitado, caído; ataques a até 1,5m crítico automático.' },\n]\n\n// ============================================================================\n// Tracker fields — mesmas do 2014 (AC, death saves)\n// ============================================================================\n\nconst TRACKER_FIELDS: TrackerField[] = [\n {\n key: 'ac',\n label: 'CA',\n kind: 'integer',\n min: 1,\n max: 30,\n default: 10,\n description: 'Classe de Armadura — DC para ser atingido por ataques.',\n },\n {\n key: 'exhaustion',\n label: 'Exh',\n kind: 'integer',\n min: 0,\n max: 10,\n default: 0,\n description: 'Nível de Exhaustion (0..10). Cada ponto dá −2 cumulativo em d20 tests; 10 = morte.',\n },\n {\n key: 'deathSuccesses',\n label: 'M✓',\n kind: 'integer',\n min: 0,\n max: 3,\n default: 0,\n description: 'Sucessos em testes de resistência à morte (3 = estabilizado).',\n },\n {\n key: 'deathFailures',\n label: 'M✗',\n kind: 'integer',\n min: 0,\n max: 3,\n default: 0,\n description: 'Falhas em testes de resistência à morte (3 = morte).',\n },\n]\n\n// ============================================================================\n// Regras automatizadas\n// ============================================================================\n\nexport function abilityMod(score: number): number {\n return Math.floor((score - 10) / 2)\n}\n\nexport function spellSaveDC(proficiency: number, casterMod: number): number {\n return 8 + proficiency + casterMod\n}\n\nexport function spellAttackBonus(proficiency: number, casterMod: number): number {\n return proficiency + casterMod\n}\n\n/** Modificador de exaustão por nível (2024): −2 por nível. */\nexport function exhaustionPenalty(level: number): number {\n const clamped = Math.max(0, Math.min(10, Math.trunc(level)))\n return clamped === 0 ? 0 : -2 * clamped\n}\n\ninterface D20Params {\n modifier?: number\n advantage?: boolean\n disadvantage?: boolean\n /** Nível de exaustão (0..10). Aplica −2 por nível em todos os testes. */\n exhaustion?: number\n}\n\nfunction rollD20({\n modifier = 0,\n advantage = false,\n disadvantage = false,\n exhaustion = 0,\n}: D20Params): RollResult {\n const cancelled = advantage && disadvantage\n const useAdv = advantage && !cancelled\n const useDis = disadvantage && !cancelled\n const count = useAdv || useDis ? 2 : 1\n const dice = roll(20, count)\n const picked = useAdv ? Math.max(...dice) : useDis ? Math.min(...dice) : dice[0]!\n const exhPenalty = exhaustionPenalty(exhaustion)\n const effectiveMod = modifier + exhPenalty\n const total = picked + effectiveMod\n const notes: string[] = []\n if (cancelled) notes.push('vantagem/desvantagem se cancelaram')\n else if (useAdv) notes.push('vantagem')\n else if (useDis) notes.push('desvantagem')\n if (exhPenalty !== 0) notes.push(`exaustão ${exhaustion} (${exhPenalty})`)\n if (picked === 20) notes.push('crítico natural')\n if (picked === 1) notes.push('falha crítica')\n const modStr =\n effectiveMod === 0 ? '' : effectiveMod > 0 ? `+${effectiveMod}` : `${effectiveMod}`\n const dStr = count === 2 ? `2d20${useAdv ? 'kh1' : 'kl1'}` : '1d20'\n return { rolls: dice, modifier: effectiveMod, total, notation: `${dStr}${modStr}`, notes }\n}\n\ninterface AttackParams {\n modifier?: number\n targetAC?: number\n advantage?: boolean\n disadvantage?: boolean\n exhaustion?: number\n}\n\nfunction rollAttack(params: AttackParams): RollResult {\n const result = rollD20(params)\n const adv = params.advantage && !params.disadvantage\n const d20 =\n result.rolls.length === 2\n ? adv\n ? result.rolls[0]! >= result.rolls[1]!\n ? result.rolls[0]!\n : result.rolls[1]!\n : result.rolls[0]! <= result.rolls[1]!\n ? result.rolls[0]!\n : result.rolls[1]!\n : result.rolls[0]!\n const notes = [...(result.notes ?? [])]\n if (params.targetAC !== undefined) {\n const natural20 = d20 === 20\n const natural1 = d20 === 1\n const hit = natural20 || (!natural1 && result.total >= params.targetAC)\n notes.push(\n hit\n ? natural20\n ? 'acerto crítico'\n : 'acertou'\n : natural1\n ? 'erro crítico'\n : 'errou',\n )\n }\n return { ...result, notes }\n}\n\ninterface SaveParams {\n modifier?: number\n dc: number\n advantage?: boolean\n disadvantage?: boolean\n exhaustion?: number\n}\n\nfunction rollSave(params: SaveParams): RollResult {\n const result = rollD20(params)\n const notes = [...(result.notes ?? [])]\n notes.push(result.total >= params.dc ? 'sucesso' : 'falha')\n return { ...result, notes: notes.concat([`DC ${params.dc}`]) }\n}\n\ninterface DamageParams {\n count: number\n sides: number\n modifier?: number\n critical?: boolean\n}\n\nfunction rollDamage({ count, sides, modifier = 0, critical = false }: DamageParams): RollResult {\n const totalDice = critical ? count * 2 : count\n const dice = roll(sides, totalDice)\n const sum = dice.reduce((a, b) => a + b, 0)\n const total = Math.max(0, sum + modifier)\n const modStr = modifier === 0 ? '' : modifier > 0 ? `+${modifier}` : `${modifier}`\n return {\n rolls: dice,\n modifier,\n total,\n notation: `${totalDice}d${sides}${modStr}${critical ? ' (crit)' : ''}`,\n notes: critical ? ['dano crítico — dados dobrados'] : [],\n }\n}\n\ninterface DamageTarget {\n resistance?: string[]\n vulnerability?: string[]\n immunity?: string[]\n}\n\ninterface ApplyDamageInput {\n type?: string\n target?: DamageTarget\n}\n\nfunction applyDndDamage(\n incoming: number,\n ctx: ApplyDamageInput,\n): { final: number; notes: string[] } {\n const t = ctx.target\n const type = ctx.type\n if (!type || !t) return { final: Math.max(0, incoming), notes: [] }\n if (t.immunity?.includes(type)) return { final: 0, notes: [`imune a ${type}`] }\n if (t.resistance?.includes(type)) {\n return { final: Math.floor(incoming / 2), notes: [`resistência a ${type} (metade)`] }\n }\n if (t.vulnerability?.includes(type)) {\n return { final: incoming * 2, notes: [`vulnerabilidade a ${type} (dobro)`] }\n }\n return { final: Math.max(0, incoming), notes: [] }\n}\n\n// ============================================================================\n// Bundle\n// ============================================================================\n\nconst RULES: SystemRules = {\n roll(kind, params) {\n switch (kind) {\n case 'd20':\n case 'check':\n case 'ability':\n return rollD20(params as unknown as D20Params)\n case 'attack':\n return rollAttack(params as unknown as AttackParams)\n case 'save':\n return rollSave(params as unknown as SaveParams)\n case 'damage':\n return rollDamage(params as unknown as DamageParams)\n default:\n return null\n }\n },\n applyDamage(incoming, target) {\n return applyDndDamage(incoming, target as ApplyDamageInput)\n },\n}\n\n/**\n * Hooks pra `@lippelt/srd-npcgen`. 5e 2024 mantém a mesma matemática\n * (proficiency + ability mod, cantrip scaling 1/5/11/17). A lista de skills\n * é idêntica à 2014 — o SRD 5.2 não acrescentou nem removeu skills.\n */\nconst DND5E_2024_SKILLS = [\n 'acrobatics',\n 'animal-handling',\n 'arcana',\n 'athletics',\n 'deception',\n 'history',\n 'insight',\n 'intimidation',\n 'investigation',\n 'medicine',\n 'nature',\n 'perception',\n 'performance',\n 'persuasion',\n 'religion',\n 'sleight-of-hand',\n 'stealth',\n 'survival',\n] as const\n\nexport const dnd5e2024: System = {\n id: 'dnd5e-2024',\n name: 'Dungeons & Dragons 5e (2024)',\n ruleVersion: 'SRD 5.2',\n attribution:\n 'Contains material from the System Reference Document 5.2 by Wizards of the Coast LLC, licensed under CC-BY 4.0.',\n dicePresets: DICE_PRESETS,\n conditions: CONDITIONS,\n trackerFields: TRACKER_FIELDS,\n rules: RULES,\n npc: {\n skills: DND5E_2024_SKILLS,\n },\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCA,IAAI,SAAiB,CAAC,UAAkB,KAAK,MAAM,KAAK,OAAO,IAAI,KAAK,IAAI;AAErE,SAAS,UAAU,IAAkB;AAC1C,WAAS;AACX;AAEO,SAAS,cAAoB;AAClC,WAAS,CAAC,UAAkB,KAAK,MAAM,KAAK,OAAO,IAAI,KAAK,IAAI;AAClE;AAEA,SAAS,KAAK,OAAe,QAAQ,GAAa;AAChD,QAAM,MAAgB,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,OAAO,IAAK,KAAI,KAAK,OAAO,KAAK,CAAC;AACtD,SAAO;AACT;AAMA,IAAM,eAA6B;AAAA,EACjC,EAAE,IAAI,OAAO,OAAO,OAAO,UAAU,QAAQ,UAAU,QAAQ;AAAA,EAC/D,EAAE,IAAI,WAAW,OAAO,cAAc,UAAU,aAAa,UAAU,SAAS,aAAa,4BAA4B;AAAA,EACzH,EAAE,IAAI,WAAW,OAAO,eAAe,UAAU,gBAAgB,UAAU,SAAS,aAAa,4BAA4B;AAAA,EAC7H,EAAE,IAAI,MAAM,OAAO,MAAM,UAAU,OAAO,UAAU,SAAS;AAAA,EAC7D,EAAE,IAAI,MAAM,OAAO,MAAM,UAAU,OAAO,UAAU,SAAS;AAAA,EAC7D,EAAE,IAAI,MAAM,OAAO,MAAM,UAAU,OAAO,UAAU,SAAS;AAAA,EAC7D,EAAE,IAAI,OAAO,OAAO,OAAO,UAAU,QAAQ,UAAU,SAAS;AAAA,EAChE,EAAE,IAAI,OAAO,OAAO,OAAO,UAAU,QAAQ,UAAU,SAAS;AAAA,EAChE,EAAE,IAAI,QAAQ,OAAO,QAAQ,UAAU,SAAS,UAAU,UAAU;AACtE;AASA,IAAM,aAA6B;AAAA,EACjC,EAAE,IAAI,WAAW,OAAO,WAAW,SAAS,gGAA0F;AAAA,EACtI,EAAE,IAAI,WAAW,OAAO,WAAW,SAAS,2FAAqF;AAAA,EACjI,EAAE,IAAI,YAAY,OAAO,YAAY,SAAS,wDAAkD;AAAA,EAChG,EAAE,IAAI,cAAc,OAAO,sBAAsB,SAAS,wGAA0F;AAAA,EACpJ,EAAE,IAAI,cAAc,OAAO,cAAc,SAAS,wGAAkG;AAAA,EACpJ,EAAE,IAAI,YAAY,OAAO,YAAY,SAAS,iFAAiF;AAAA,EAC/H,EAAE,IAAI,iBAAiB,OAAO,iBAAiB,SAAS,2EAA4D;AAAA,EACpH,EAAE,IAAI,aAAa,OAAO,aAAa,SAAS,mEAA6D;AAAA,EAC7G,EAAE,IAAI,aAAa,OAAO,aAAa,SAAS,qGAAyF;AAAA,EACzI,EAAE,IAAI,aAAa,OAAO,aAAa,SAAS,8GAAwG;AAAA,EACxJ,EAAE,IAAI,YAAY,OAAO,YAAY,SAAS,6DAA6D;AAAA,EAC3G,EAAE,IAAI,SAAS,OAAO,SAAS,SAAS,uHAAwG;AAAA,EAChJ,EAAE,IAAI,cAAc,OAAO,cAAc,SAAS,2FAAwF;AAAA,EAC1I,EAAE,IAAI,WAAW,OAAO,WAAW,SAAS,8EAA2E;AAAA,EACvH,EAAE,IAAI,eAAe,OAAO,eAAe,SAAS,wFAA4E;AAClI;AAMA,IAAM,iBAAiC;AAAA,EACrC;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN,KAAK;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN,KAAK;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN,KAAK;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,MAAM;AAAA,IACN,KAAK;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AACF;AAMO,SAAS,WAAW,OAAuB;AAChD,SAAO,KAAK,OAAO,QAAQ,MAAM,CAAC;AACpC;AAEO,SAAS,YAAY,aAAqB,WAA2B;AAC1E,SAAO,IAAI,cAAc;AAC3B;AAEO,SAAS,iBAAiB,aAAqB,WAA2B;AAC/E,SAAO,cAAc;AACvB;AAGO,SAAS,kBAAkB,OAAuB;AACvD,QAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,MAAM,KAAK,CAAC,CAAC;AAC3D,SAAO,YAAY,IAAI,IAAI,KAAK;AAClC;AAUA,SAAS,QAAQ;AAAA,EACf,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,aAAa;AACf,GAA0B;AACxB,QAAM,YAAY,aAAa;AAC/B,QAAM,SAAS,aAAa,CAAC;AAC7B,QAAM,SAAS,gBAAgB,CAAC;AAChC,QAAM,QAAQ,UAAU,SAAS,IAAI;AACrC,QAAM,OAAO,KAAK,IAAI,KAAK;AAC3B,QAAM,SAAS,SAAS,KAAK,IAAI,GAAG,IAAI,IAAI,SAAS,KAAK,IAAI,GAAG,IAAI,IAAI,KAAK,CAAC;AAC/E,QAAM,aAAa,kBAAkB,UAAU;AAC/C,QAAM,eAAe,WAAW;AAChC,QAAM,QAAQ,SAAS;AACvB,QAAM,QAAkB,CAAC;AACzB,MAAI,UAAW,OAAM,KAAK,oCAAoC;AAAA,WACrD,OAAQ,OAAM,KAAK,UAAU;AAAA,WAC7B,OAAQ,OAAM,KAAK,aAAa;AACzC,MAAI,eAAe,EAAG,OAAM,KAAK,eAAY,UAAU,KAAK,UAAU,GAAG;AACzE,MAAI,WAAW,GAAI,OAAM,KAAK,oBAAiB;AAC/C,MAAI,WAAW,EAAG,OAAM,KAAK,kBAAe;AAC5C,QAAM,SACJ,iBAAiB,IAAI,KAAK,eAAe,IAAI,IAAI,YAAY,KAAK,GAAG,YAAY;AACnF,QAAM,OAAO,UAAU,IAAI,OAAO,SAAS,QAAQ,KAAK,KAAK;AAC7D,SAAO,EAAE,OAAO,MAAM,UAAU,cAAc,OAAO,UAAU,GAAG,IAAI,GAAG,MAAM,IAAI,MAAM;AAC3F;AAUA,SAAS,WAAW,QAAkC;AACpD,QAAM,SAAS,QAAQ,MAAM;AAC7B,QAAM,MAAM,OAAO,aAAa,CAAC,OAAO;AACxC,QAAM,MACJ,OAAO,MAAM,WAAW,IACpB,MACE,OAAO,MAAM,CAAC,KAAM,OAAO,MAAM,CAAC,IAChC,OAAO,MAAM,CAAC,IACd,OAAO,MAAM,CAAC,IAChB,OAAO,MAAM,CAAC,KAAM,OAAO,MAAM,CAAC,IAChC,OAAO,MAAM,CAAC,IACd,OAAO,MAAM,CAAC,IAClB,OAAO,MAAM,CAAC;AACpB,QAAM,QAAQ,CAAC,GAAI,OAAO,SAAS,CAAC,CAAE;AACtC,MAAI,OAAO,aAAa,QAAW;AACjC,UAAM,YAAY,QAAQ;AAC1B,UAAM,WAAW,QAAQ;AACzB,UAAM,MAAM,aAAc,CAAC,YAAY,OAAO,SAAS,OAAO;AAC9D,UAAM;AAAA,MACJ,MACI,YACE,sBACA,YACF,WACE,oBACA;AAAA,IACR;AAAA,EACF;AACA,SAAO,EAAE,GAAG,QAAQ,MAAM;AAC5B;AAUA,SAAS,SAAS,QAAgC;AAChD,QAAM,SAAS,QAAQ,MAAM;AAC7B,QAAM,QAAQ,CAAC,GAAI,OAAO,SAAS,CAAC,CAAE;AACtC,QAAM,KAAK,OAAO,SAAS,OAAO,KAAK,YAAY,OAAO;AAC1D,SAAO,EAAE,GAAG,QAAQ,OAAO,MAAM,OAAO,CAAC,MAAM,OAAO,EAAE,EAAE,CAAC,EAAE;AAC/D;AASA,SAAS,WAAW,EAAE,OAAO,OAAO,WAAW,GAAG,WAAW,MAAM,GAA6B;AAC9F,QAAM,YAAY,WAAW,QAAQ,IAAI;AACzC,QAAM,OAAO,KAAK,OAAO,SAAS;AAClC,QAAM,MAAM,KAAK,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AAC1C,QAAM,QAAQ,KAAK,IAAI,GAAG,MAAM,QAAQ;AACxC,QAAM,SAAS,aAAa,IAAI,KAAK,WAAW,IAAI,IAAI,QAAQ,KAAK,GAAG,QAAQ;AAChF,SAAO;AAAA,IACL,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,UAAU,GAAG,SAAS,IAAI,KAAK,GAAG,MAAM,GAAG,WAAW,YAAY,EAAE;AAAA,IACpE,OAAO,WAAW,CAAC,uCAA+B,IAAI,CAAC;AAAA,EACzD;AACF;AAaA,SAAS,eACP,UACA,KACoC;AACpC,QAAM,IAAI,IAAI;AACd,QAAM,OAAO,IAAI;AACjB,MAAI,CAAC,QAAQ,CAAC,EAAG,QAAO,EAAE,OAAO,KAAK,IAAI,GAAG,QAAQ,GAAG,OAAO,CAAC,EAAE;AAClE,MAAI,EAAE,UAAU,SAAS,IAAI,EAAG,QAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,EAAE;AAC9E,MAAI,EAAE,YAAY,SAAS,IAAI,GAAG;AAChC,WAAO,EAAE,OAAO,KAAK,MAAM,WAAW,CAAC,GAAG,OAAO,CAAC,oBAAiB,IAAI,WAAW,EAAE;AAAA,EACtF;AACA,MAAI,EAAE,eAAe,SAAS,IAAI,GAAG;AACnC,WAAO,EAAE,OAAO,WAAW,GAAG,OAAO,CAAC,qBAAqB,IAAI,UAAU,EAAE;AAAA,EAC7E;AACA,SAAO,EAAE,OAAO,KAAK,IAAI,GAAG,QAAQ,GAAG,OAAO,CAAC,EAAE;AACnD;AAMA,IAAM,QAAqB;AAAA,EACzB,KAAK,MAAM,QAAQ;AACjB,YAAQ,MAAM;AAAA,MACZ,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO,QAAQ,MAA8B;AAAA,MAC/C,KAAK;AACH,eAAO,WAAW,MAAiC;AAAA,MACrD,KAAK;AACH,eAAO,SAAS,MAA+B;AAAA,MACjD,KAAK;AACH,eAAO,WAAW,MAAiC;AAAA,MACrD;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAAA,EACA,YAAY,UAAU,QAAQ;AAC5B,WAAO,eAAe,UAAU,MAA0B;AAAA,EAC5D;AACF;AAOA,IAAM,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,YAAoB;AAAA,EAC/B,IAAI;AAAA,EACJ,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aACE;AAAA,EACF,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,OAAO;AAAA,EACP,KAAK;AAAA,IACH,QAAQ;AAAA,EACV;AACF;","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -185,6 +185,26 @@ var RULES = {
|
|
|
185
185
|
return applyDndDamage(incoming, target);
|
|
186
186
|
}
|
|
187
187
|
};
|
|
188
|
+
var DND5E_2024_SKILLS = [
|
|
189
|
+
"acrobatics",
|
|
190
|
+
"animal-handling",
|
|
191
|
+
"arcana",
|
|
192
|
+
"athletics",
|
|
193
|
+
"deception",
|
|
194
|
+
"history",
|
|
195
|
+
"insight",
|
|
196
|
+
"intimidation",
|
|
197
|
+
"investigation",
|
|
198
|
+
"medicine",
|
|
199
|
+
"nature",
|
|
200
|
+
"perception",
|
|
201
|
+
"performance",
|
|
202
|
+
"persuasion",
|
|
203
|
+
"religion",
|
|
204
|
+
"sleight-of-hand",
|
|
205
|
+
"stealth",
|
|
206
|
+
"survival"
|
|
207
|
+
];
|
|
188
208
|
var dnd5e2024 = {
|
|
189
209
|
id: "dnd5e-2024",
|
|
190
210
|
name: "Dungeons & Dragons 5e (2024)",
|
|
@@ -193,7 +213,10 @@ var dnd5e2024 = {
|
|
|
193
213
|
dicePresets: DICE_PRESETS,
|
|
194
214
|
conditions: CONDITIONS,
|
|
195
215
|
trackerFields: TRACKER_FIELDS,
|
|
196
|
-
rules: RULES
|
|
216
|
+
rules: RULES,
|
|
217
|
+
npc: {
|
|
218
|
+
skills: DND5E_2024_SKILLS
|
|
219
|
+
}
|
|
197
220
|
};
|
|
198
221
|
export {
|
|
199
222
|
abilityMod,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Dungeons & Dragons 5th Edition (2024 / \"One D&D\").\n *\n * Conteúdo de regras deriva do System Reference Document 5.2, publicado\n * pela Wizards of the Coast LLC sob a Creative Commons Attribution 4.0\n * International License:\n * https://creativecommons.org/licenses/by/4.0/legalcode\n *\n * Mantém compatibilidade mecânica com a edição 2014 — o que mudou:\n * - Exhaustion: agora uma escala 1..10 com −2 cumulativo em d20 tests\n * (era 6 níveis discretos)\n * - Algumas condições com wording refinado\n * - Math de combate (advantage, attack vs AC, saves, crítico) é igual\n *\n * Esta implementação é original (referência conceitual: foundryvtt/dnd5e,\n * MIT). Para spells e features de classe, use o SRD 5.2 oficial.\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 — injetável pra testes determinísticos.\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// Presets de dados (idênticos aos 2014)\n// ============================================================================\n\nconst DICE_PRESETS: DicePreset[] = [\n { id: 'd20', label: 'd20', notation: '1d20', category: 'check' },\n { id: 'd20-adv', label: 'd20 (adv.)', notation: 'advantage', category: 'check', description: 'Rola 2d20 e pega o maior.' },\n { id: 'd20-dis', label: 'd20 (desv.)', notation: 'disadvantage', category: 'check', description: 'Rola 2d20 e pega o menor.' },\n { id: 'd4', label: 'd4', notation: '1d4', category: 'damage' },\n { id: 'd6', label: 'd6', notation: '1d6', category: 'damage' },\n { id: 'd8', label: 'd8', notation: '1d8', category: 'damage' },\n { id: 'd10', label: 'd10', notation: '1d10', category: 'damage' },\n { id: 'd12', label: 'd12', notation: '1d12', category: 'damage' },\n { id: 'd100', label: 'd100', notation: '1d100', category: 'special' },\n]\n\n// ============================================================================\n// Condições — SRD 5.2 (CC-BY 4.0)\n//\n// Mudança principal vs 5.1: Exhaustion é uma escala única 1..10, cada nível\n// dá −2 acumulativo em d20 tests; nível 10 = morte.\n// ============================================================================\n\nconst CONDITIONS: ConditionDef[] = [\n { id: 'blinded', label: 'Blinded', summary: 'Cego: falha em testes que exigem visão; atacantes têm vantagem; o cego tem desvantagem.' },\n { id: 'charmed', label: 'Charmed', summary: 'Enfeitiçado: não pode atacar o encantador nem usar habilidades nocivas contra ele.' },\n { id: 'deafened', label: 'Deafened', summary: 'Surdo: falha em testes que dependem de audição.' },\n { id: 'exhaustion', label: 'Exhaustion (level)', summary: 'Exaustão (1..10): −2 acumulativo em todos os testes de d20 por nível; nível 10 = morte.' },\n { id: 'frightened', label: 'Frightened', summary: 'Amedrontado: desvantagem se a fonte do medo estiver à vista; não pode se mover para perto dela.' },\n { id: 'grappled', label: 'Grappled', summary: 'Agarrado: velocidade 0; termina se o agarrador ficar incapacitado ou afastado.' },\n { id: 'incapacitated', label: 'Incapacitated', summary: 'Incapacitado: não pode tomar ações, reações nem mover-se.' },\n { id: 'invisible', label: 'Invisible', summary: 'Invisível: vantagem em ataques; atacantes têm desvantagem.' },\n { id: 'paralyzed', label: 'Paralyzed', summary: 'Paralisado: incapacitado, não pode mover/falar; ataques a até 1,5m crítico automático.' },\n { id: 'petrified', label: 'Petrified', summary: 'Petrificado: incapacitado, transformado em pedra; resistência a todo dano; imune a venenos e doenças.' },\n { id: 'poisoned', label: 'Poisoned', summary: 'Envenenado: desvantagem em ataques e testes de habilidade.' },\n { id: 'prone', label: 'Prone', summary: 'Caído: desvantagem em ataques; corpo-a-corpo contra o alvo têm vantagem; à distância têm desvantagem.' },\n { id: 'restrained', label: 'Restrained', summary: 'Contido: velocidade 0; desvantagem em ataques e em Dex saves; atacantes têm vantagem.' },\n { id: 'stunned', label: 'Stunned', summary: 'Atordoado: incapacitado; falha em Str/Dex saves; atacantes têm vantagem.' },\n { id: 'unconscious', label: 'Unconscious', summary: 'Inconsciente: incapacitado, caído; ataques a até 1,5m crítico automático.' },\n]\n\n// ============================================================================\n// Tracker fields — mesmas do 2014 (AC, death saves)\n// ============================================================================\n\nconst TRACKER_FIELDS: TrackerField[] = [\n {\n key: 'ac',\n label: 'CA',\n kind: 'integer',\n min: 1,\n max: 30,\n default: 10,\n description: 'Classe de Armadura — DC para ser atingido por ataques.',\n },\n {\n key: 'exhaustion',\n label: 'Exh',\n kind: 'integer',\n min: 0,\n max: 10,\n default: 0,\n description: 'Nível de Exhaustion (0..10). Cada ponto dá −2 cumulativo em d20 tests; 10 = morte.',\n },\n {\n key: 'deathSuccesses',\n label: 'M✓',\n kind: 'integer',\n min: 0,\n max: 3,\n default: 0,\n description: 'Sucessos em testes de resistência à morte (3 = estabilizado).',\n },\n {\n key: 'deathFailures',\n label: 'M✗',\n kind: 'integer',\n min: 0,\n max: 3,\n default: 0,\n description: 'Falhas em testes de resistência à morte (3 = morte).',\n },\n]\n\n// ============================================================================\n// Regras automatizadas\n// ============================================================================\n\nexport function abilityMod(score: number): number {\n return Math.floor((score - 10) / 2)\n}\n\nexport function spellSaveDC(proficiency: number, casterMod: number): number {\n return 8 + proficiency + casterMod\n}\n\nexport function spellAttackBonus(proficiency: number, casterMod: number): number {\n return proficiency + casterMod\n}\n\n/** Modificador de exaustão por nível (2024): −2 por nível. */\nexport function exhaustionPenalty(level: number): number {\n const clamped = Math.max(0, Math.min(10, Math.trunc(level)))\n return clamped === 0 ? 0 : -2 * clamped\n}\n\ninterface D20Params {\n modifier?: number\n advantage?: boolean\n disadvantage?: boolean\n /** Nível de exaustão (0..10). Aplica −2 por nível em todos os testes. */\n exhaustion?: number\n}\n\nfunction rollD20({\n modifier = 0,\n advantage = false,\n disadvantage = false,\n exhaustion = 0,\n}: D20Params): RollResult {\n const cancelled = advantage && disadvantage\n const useAdv = advantage && !cancelled\n const useDis = disadvantage && !cancelled\n const count = useAdv || useDis ? 2 : 1\n const dice = roll(20, count)\n const picked = useAdv ? Math.max(...dice) : useDis ? Math.min(...dice) : dice[0]!\n const exhPenalty = exhaustionPenalty(exhaustion)\n const effectiveMod = modifier + exhPenalty\n const total = picked + effectiveMod\n const notes: string[] = []\n if (cancelled) notes.push('vantagem/desvantagem se cancelaram')\n else if (useAdv) notes.push('vantagem')\n else if (useDis) notes.push('desvantagem')\n if (exhPenalty !== 0) notes.push(`exaustão ${exhaustion} (${exhPenalty})`)\n if (picked === 20) notes.push('crítico natural')\n if (picked === 1) notes.push('falha crítica')\n const modStr =\n effectiveMod === 0 ? '' : effectiveMod > 0 ? `+${effectiveMod}` : `${effectiveMod}`\n const dStr = count === 2 ? `2d20${useAdv ? 'kh1' : 'kl1'}` : '1d20'\n return { rolls: dice, modifier: effectiveMod, total, notation: `${dStr}${modStr}`, notes }\n}\n\ninterface AttackParams {\n modifier?: number\n targetAC?: number\n advantage?: boolean\n disadvantage?: boolean\n exhaustion?: number\n}\n\nfunction rollAttack(params: AttackParams): RollResult {\n const result = rollD20(params)\n const adv = params.advantage && !params.disadvantage\n const d20 =\n result.rolls.length === 2\n ? adv\n ? result.rolls[0]! >= result.rolls[1]!\n ? result.rolls[0]!\n : result.rolls[1]!\n : result.rolls[0]! <= result.rolls[1]!\n ? result.rolls[0]!\n : result.rolls[1]!\n : result.rolls[0]!\n const notes = [...(result.notes ?? [])]\n if (params.targetAC !== undefined) {\n const natural20 = d20 === 20\n const natural1 = d20 === 1\n const hit = natural20 || (!natural1 && result.total >= params.targetAC)\n notes.push(\n hit\n ? natural20\n ? 'acerto crítico'\n : 'acertou'\n : natural1\n ? 'erro crítico'\n : 'errou',\n )\n }\n return { ...result, notes }\n}\n\ninterface SaveParams {\n modifier?: number\n dc: number\n advantage?: boolean\n disadvantage?: boolean\n exhaustion?: number\n}\n\nfunction rollSave(params: SaveParams): RollResult {\n const result = rollD20(params)\n const notes = [...(result.notes ?? [])]\n notes.push(result.total >= params.dc ? 'sucesso' : 'falha')\n return { ...result, notes: notes.concat([`DC ${params.dc}`]) }\n}\n\ninterface DamageParams {\n count: number\n sides: number\n modifier?: number\n critical?: boolean\n}\n\nfunction rollDamage({ count, sides, modifier = 0, critical = false }: DamageParams): RollResult {\n const totalDice = critical ? count * 2 : count\n const dice = roll(sides, totalDice)\n const sum = dice.reduce((a, b) => a + b, 0)\n const total = Math.max(0, sum + modifier)\n const modStr = modifier === 0 ? '' : modifier > 0 ? `+${modifier}` : `${modifier}`\n return {\n rolls: dice,\n modifier,\n total,\n notation: `${totalDice}d${sides}${modStr}${critical ? ' (crit)' : ''}`,\n notes: critical ? ['dano crítico — dados dobrados'] : [],\n }\n}\n\ninterface DamageTarget {\n resistance?: string[]\n vulnerability?: string[]\n immunity?: string[]\n}\n\ninterface ApplyDamageInput {\n type?: string\n target?: DamageTarget\n}\n\nfunction applyDndDamage(\n incoming: number,\n ctx: ApplyDamageInput,\n): { final: number; notes: string[] } {\n const t = ctx.target\n const type = ctx.type\n if (!type || !t) return { final: Math.max(0, incoming), notes: [] }\n if (t.immunity?.includes(type)) return { final: 0, notes: [`imune a ${type}`] }\n if (t.resistance?.includes(type)) {\n return { final: Math.floor(incoming / 2), notes: [`resistência a ${type} (metade)`] }\n }\n if (t.vulnerability?.includes(type)) {\n return { final: incoming * 2, notes: [`vulnerabilidade a ${type} (dobro)`] }\n }\n return { final: Math.max(0, incoming), notes: [] }\n}\n\n// ============================================================================\n// Bundle\n// ============================================================================\n\nconst RULES: SystemRules = {\n roll(kind, params) {\n switch (kind) {\n case 'd20':\n case 'check':\n case 'ability':\n return rollD20(params as unknown as D20Params)\n case 'attack':\n return rollAttack(params as unknown as AttackParams)\n case 'save':\n return rollSave(params as unknown as SaveParams)\n case 'damage':\n return rollDamage(params as unknown as DamageParams)\n default:\n return null\n }\n },\n applyDamage(incoming, target) {\n return applyDndDamage(incoming, target as ApplyDamageInput)\n },\n}\n\nexport const dnd5e2024: System = {\n id: 'dnd5e-2024',\n name: 'Dungeons & Dragons 5e (2024)',\n ruleVersion: 'SRD 5.2',\n attribution:\n 'Contains material from the System Reference Document 5.2 by Wizards of the Coast LLC, licensed under CC-BY 4.0.',\n dicePresets: DICE_PRESETS,\n conditions: CONDITIONS,\n trackerFields: TRACKER_FIELDS,\n rules: RULES,\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Dungeons & Dragons 5th Edition (2024 / \"One D&D\").\n *\n * Conteúdo de regras deriva do System Reference Document 5.2, publicado\n * pela Wizards of the Coast LLC sob a Creative Commons Attribution 4.0\n * International License:\n * https://creativecommons.org/licenses/by/4.0/legalcode\n *\n * Mantém compatibilidade mecânica com a edição 2014 — o que mudou:\n * - Exhaustion: agora uma escala 1..10 com −2 cumulativo em d20 tests\n * (era 6 níveis discretos)\n * - Algumas condições com wording refinado\n * - Math de combate (advantage, attack vs AC, saves, crítico) é igual\n *\n * Esta implementação é original (referência conceitual: foundryvtt/dnd5e,\n * MIT). Para spells e features de classe, use o SRD 5.2 oficial.\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 — injetável pra testes determinísticos.\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// Presets de dados (idênticos aos 2014)\n// ============================================================================\n\nconst DICE_PRESETS: DicePreset[] = [\n { id: 'd20', label: 'd20', notation: '1d20', category: 'check' },\n { id: 'd20-adv', label: 'd20 (adv.)', notation: 'advantage', category: 'check', description: 'Rola 2d20 e pega o maior.' },\n { id: 'd20-dis', label: 'd20 (desv.)', notation: 'disadvantage', category: 'check', description: 'Rola 2d20 e pega o menor.' },\n { id: 'd4', label: 'd4', notation: '1d4', category: 'damage' },\n { id: 'd6', label: 'd6', notation: '1d6', category: 'damage' },\n { id: 'd8', label: 'd8', notation: '1d8', category: 'damage' },\n { id: 'd10', label: 'd10', notation: '1d10', category: 'damage' },\n { id: 'd12', label: 'd12', notation: '1d12', category: 'damage' },\n { id: 'd100', label: 'd100', notation: '1d100', category: 'special' },\n]\n\n// ============================================================================\n// Condições — SRD 5.2 (CC-BY 4.0)\n//\n// Mudança principal vs 5.1: Exhaustion é uma escala única 1..10, cada nível\n// dá −2 acumulativo em d20 tests; nível 10 = morte.\n// ============================================================================\n\nconst CONDITIONS: ConditionDef[] = [\n { id: 'blinded', label: 'Blinded', summary: 'Cego: falha em testes que exigem visão; atacantes têm vantagem; o cego tem desvantagem.' },\n { id: 'charmed', label: 'Charmed', summary: 'Enfeitiçado: não pode atacar o encantador nem usar habilidades nocivas contra ele.' },\n { id: 'deafened', label: 'Deafened', summary: 'Surdo: falha em testes que dependem de audição.' },\n { id: 'exhaustion', label: 'Exhaustion (level)', summary: 'Exaustão (1..10): −2 acumulativo em todos os testes de d20 por nível; nível 10 = morte.' },\n { id: 'frightened', label: 'Frightened', summary: 'Amedrontado: desvantagem se a fonte do medo estiver à vista; não pode se mover para perto dela.' },\n { id: 'grappled', label: 'Grappled', summary: 'Agarrado: velocidade 0; termina se o agarrador ficar incapacitado ou afastado.' },\n { id: 'incapacitated', label: 'Incapacitated', summary: 'Incapacitado: não pode tomar ações, reações nem mover-se.' },\n { id: 'invisible', label: 'Invisible', summary: 'Invisível: vantagem em ataques; atacantes têm desvantagem.' },\n { id: 'paralyzed', label: 'Paralyzed', summary: 'Paralisado: incapacitado, não pode mover/falar; ataques a até 1,5m crítico automático.' },\n { id: 'petrified', label: 'Petrified', summary: 'Petrificado: incapacitado, transformado em pedra; resistência a todo dano; imune a venenos e doenças.' },\n { id: 'poisoned', label: 'Poisoned', summary: 'Envenenado: desvantagem em ataques e testes de habilidade.' },\n { id: 'prone', label: 'Prone', summary: 'Caído: desvantagem em ataques; corpo-a-corpo contra o alvo têm vantagem; à distância têm desvantagem.' },\n { id: 'restrained', label: 'Restrained', summary: 'Contido: velocidade 0; desvantagem em ataques e em Dex saves; atacantes têm vantagem.' },\n { id: 'stunned', label: 'Stunned', summary: 'Atordoado: incapacitado; falha em Str/Dex saves; atacantes têm vantagem.' },\n { id: 'unconscious', label: 'Unconscious', summary: 'Inconsciente: incapacitado, caído; ataques a até 1,5m crítico automático.' },\n]\n\n// ============================================================================\n// Tracker fields — mesmas do 2014 (AC, death saves)\n// ============================================================================\n\nconst TRACKER_FIELDS: TrackerField[] = [\n {\n key: 'ac',\n label: 'CA',\n kind: 'integer',\n min: 1,\n max: 30,\n default: 10,\n description: 'Classe de Armadura — DC para ser atingido por ataques.',\n },\n {\n key: 'exhaustion',\n label: 'Exh',\n kind: 'integer',\n min: 0,\n max: 10,\n default: 0,\n description: 'Nível de Exhaustion (0..10). Cada ponto dá −2 cumulativo em d20 tests; 10 = morte.',\n },\n {\n key: 'deathSuccesses',\n label: 'M✓',\n kind: 'integer',\n min: 0,\n max: 3,\n default: 0,\n description: 'Sucessos em testes de resistência à morte (3 = estabilizado).',\n },\n {\n key: 'deathFailures',\n label: 'M✗',\n kind: 'integer',\n min: 0,\n max: 3,\n default: 0,\n description: 'Falhas em testes de resistência à morte (3 = morte).',\n },\n]\n\n// ============================================================================\n// Regras automatizadas\n// ============================================================================\n\nexport function abilityMod(score: number): number {\n return Math.floor((score - 10) / 2)\n}\n\nexport function spellSaveDC(proficiency: number, casterMod: number): number {\n return 8 + proficiency + casterMod\n}\n\nexport function spellAttackBonus(proficiency: number, casterMod: number): number {\n return proficiency + casterMod\n}\n\n/** Modificador de exaustão por nível (2024): −2 por nível. */\nexport function exhaustionPenalty(level: number): number {\n const clamped = Math.max(0, Math.min(10, Math.trunc(level)))\n return clamped === 0 ? 0 : -2 * clamped\n}\n\ninterface D20Params {\n modifier?: number\n advantage?: boolean\n disadvantage?: boolean\n /** Nível de exaustão (0..10). Aplica −2 por nível em todos os testes. */\n exhaustion?: number\n}\n\nfunction rollD20({\n modifier = 0,\n advantage = false,\n disadvantage = false,\n exhaustion = 0,\n}: D20Params): RollResult {\n const cancelled = advantage && disadvantage\n const useAdv = advantage && !cancelled\n const useDis = disadvantage && !cancelled\n const count = useAdv || useDis ? 2 : 1\n const dice = roll(20, count)\n const picked = useAdv ? Math.max(...dice) : useDis ? Math.min(...dice) : dice[0]!\n const exhPenalty = exhaustionPenalty(exhaustion)\n const effectiveMod = modifier + exhPenalty\n const total = picked + effectiveMod\n const notes: string[] = []\n if (cancelled) notes.push('vantagem/desvantagem se cancelaram')\n else if (useAdv) notes.push('vantagem')\n else if (useDis) notes.push('desvantagem')\n if (exhPenalty !== 0) notes.push(`exaustão ${exhaustion} (${exhPenalty})`)\n if (picked === 20) notes.push('crítico natural')\n if (picked === 1) notes.push('falha crítica')\n const modStr =\n effectiveMod === 0 ? '' : effectiveMod > 0 ? `+${effectiveMod}` : `${effectiveMod}`\n const dStr = count === 2 ? `2d20${useAdv ? 'kh1' : 'kl1'}` : '1d20'\n return { rolls: dice, modifier: effectiveMod, total, notation: `${dStr}${modStr}`, notes }\n}\n\ninterface AttackParams {\n modifier?: number\n targetAC?: number\n advantage?: boolean\n disadvantage?: boolean\n exhaustion?: number\n}\n\nfunction rollAttack(params: AttackParams): RollResult {\n const result = rollD20(params)\n const adv = params.advantage && !params.disadvantage\n const d20 =\n result.rolls.length === 2\n ? adv\n ? result.rolls[0]! >= result.rolls[1]!\n ? result.rolls[0]!\n : result.rolls[1]!\n : result.rolls[0]! <= result.rolls[1]!\n ? result.rolls[0]!\n : result.rolls[1]!\n : result.rolls[0]!\n const notes = [...(result.notes ?? [])]\n if (params.targetAC !== undefined) {\n const natural20 = d20 === 20\n const natural1 = d20 === 1\n const hit = natural20 || (!natural1 && result.total >= params.targetAC)\n notes.push(\n hit\n ? natural20\n ? 'acerto crítico'\n : 'acertou'\n : natural1\n ? 'erro crítico'\n : 'errou',\n )\n }\n return { ...result, notes }\n}\n\ninterface SaveParams {\n modifier?: number\n dc: number\n advantage?: boolean\n disadvantage?: boolean\n exhaustion?: number\n}\n\nfunction rollSave(params: SaveParams): RollResult {\n const result = rollD20(params)\n const notes = [...(result.notes ?? [])]\n notes.push(result.total >= params.dc ? 'sucesso' : 'falha')\n return { ...result, notes: notes.concat([`DC ${params.dc}`]) }\n}\n\ninterface DamageParams {\n count: number\n sides: number\n modifier?: number\n critical?: boolean\n}\n\nfunction rollDamage({ count, sides, modifier = 0, critical = false }: DamageParams): RollResult {\n const totalDice = critical ? count * 2 : count\n const dice = roll(sides, totalDice)\n const sum = dice.reduce((a, b) => a + b, 0)\n const total = Math.max(0, sum + modifier)\n const modStr = modifier === 0 ? '' : modifier > 0 ? `+${modifier}` : `${modifier}`\n return {\n rolls: dice,\n modifier,\n total,\n notation: `${totalDice}d${sides}${modStr}${critical ? ' (crit)' : ''}`,\n notes: critical ? ['dano crítico — dados dobrados'] : [],\n }\n}\n\ninterface DamageTarget {\n resistance?: string[]\n vulnerability?: string[]\n immunity?: string[]\n}\n\ninterface ApplyDamageInput {\n type?: string\n target?: DamageTarget\n}\n\nfunction applyDndDamage(\n incoming: number,\n ctx: ApplyDamageInput,\n): { final: number; notes: string[] } {\n const t = ctx.target\n const type = ctx.type\n if (!type || !t) return { final: Math.max(0, incoming), notes: [] }\n if (t.immunity?.includes(type)) return { final: 0, notes: [`imune a ${type}`] }\n if (t.resistance?.includes(type)) {\n return { final: Math.floor(incoming / 2), notes: [`resistência a ${type} (metade)`] }\n }\n if (t.vulnerability?.includes(type)) {\n return { final: incoming * 2, notes: [`vulnerabilidade a ${type} (dobro)`] }\n }\n return { final: Math.max(0, incoming), notes: [] }\n}\n\n// ============================================================================\n// Bundle\n// ============================================================================\n\nconst RULES: SystemRules = {\n roll(kind, params) {\n switch (kind) {\n case 'd20':\n case 'check':\n case 'ability':\n return rollD20(params as unknown as D20Params)\n case 'attack':\n return rollAttack(params as unknown as AttackParams)\n case 'save':\n return rollSave(params as unknown as SaveParams)\n case 'damage':\n return rollDamage(params as unknown as DamageParams)\n default:\n return null\n }\n },\n applyDamage(incoming, target) {\n return applyDndDamage(incoming, target as ApplyDamageInput)\n },\n}\n\n/**\n * Hooks pra `@lippelt/srd-npcgen`. 5e 2024 mantém a mesma matemática\n * (proficiency + ability mod, cantrip scaling 1/5/11/17). A lista de skills\n * é idêntica à 2014 — o SRD 5.2 não acrescentou nem removeu skills.\n */\nconst DND5E_2024_SKILLS = [\n 'acrobatics',\n 'animal-handling',\n 'arcana',\n 'athletics',\n 'deception',\n 'history',\n 'insight',\n 'intimidation',\n 'investigation',\n 'medicine',\n 'nature',\n 'perception',\n 'performance',\n 'persuasion',\n 'religion',\n 'sleight-of-hand',\n 'stealth',\n 'survival',\n] as const\n\nexport const dnd5e2024: System = {\n id: 'dnd5e-2024',\n name: 'Dungeons & Dragons 5e (2024)',\n ruleVersion: 'SRD 5.2',\n attribution:\n 'Contains material from the System Reference Document 5.2 by Wizards of the Coast LLC, licensed under CC-BY 4.0.',\n dicePresets: DICE_PRESETS,\n conditions: CONDITIONS,\n trackerFields: TRACKER_FIELDS,\n rules: RULES,\n npc: {\n skills: DND5E_2024_SKILLS,\n },\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lippelt/srd-dnd5e-2024",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "D&D 5e (2024) system module for @lippelt/srd-core — SRD 5.2, CC-BY 4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
"files": [
|
|
17
17
|
"dist",
|
|
18
18
|
"README.md",
|
|
19
|
-
"LICENSE"
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"CHANGELOG.md"
|
|
20
21
|
],
|
|
21
22
|
"publishConfig": {
|
|
22
23
|
"access": "public"
|
|
@@ -36,7 +37,7 @@
|
|
|
36
37
|
"directory": "packages/dnd5e-2024"
|
|
37
38
|
},
|
|
38
39
|
"peerDependencies": {
|
|
39
|
-
"@lippelt/srd-core": "^
|
|
40
|
+
"@lippelt/srd-core": "^1.0.0"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"@lippelt/srd-core": "*"
|