From fa71f3b9850fcc78355cd4e976f723fec7433bb9 Mon Sep 17 00:00:00 2001 From: Cal Corum Date: Tue, 16 Dec 2025 22:13:18 -0600 Subject: [PATCH] Implement Active Effects automation (Phase 11) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Schema & Documentation: - Extended EFFECT_KEYS with 24 new mappings: senses (6), movement capabilities (5), skill training (12), focus tracking - Created docs/ACTIVE_EFFECTS_REFERENCE.md with comprehensive guide for effect keys, modes, JSON format, and formula support Ancestry Automation: - Goblin: Darksight (darkvision), Nimble (+5 speed) - Orc: Darksight (darkvision), Hulking (+2 item slots) - Halfling: Nimble (+5 speed) - Draken: Scale (+1 armor) - Dwarf already had automation from earlier work Class Automation: - Wizard: Manifold Mind I/II (+1 focus.maxConcurrent each) - Fighter Valor already automated (proof of concept) - Gunslinger Deadeye deferred (dynamic, not static bonus) Added Phase 11 to PROJECT_ROADMAP.json with 18 tasks (10 complete, 8 deferred for conditional flags/UI/state tracking). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- PROJECT_ROADMAP.json | 188 ++++++++++++++++- docs/ACTIVE_EFFECTS_REFERENCE.md | 273 +++++++++++++++++++++++++ module/helpers/effects.mjs | 32 +++ packs/_source/ancestries/draken.json | 9 +- packs/_source/ancestries/goblin.json | 9 +- packs/_source/ancestries/halfling.json | 9 +- packs/_source/ancestries/orc.json | 9 +- packs/_source/classes/wizard.json | 8 +- 8 files changed, 521 insertions(+), 16 deletions(-) create mode 100644 docs/ACTIVE_EFFECTS_REFERENCE.md diff --git a/PROJECT_ROADMAP.json b/PROJECT_ROADMAP.json index 1a1da7f..fb9e82f 100644 --- a/PROJECT_ROADMAP.json +++ b/PROJECT_ROADMAP.json @@ -1070,11 +1070,195 @@ "dependencies": ["10.1", "10.2"] } ] + }, + { + "id": "phase-11", + "name": "Active Effects Automation", + "description": "Automate mechanical effects from ancestries, perks, and class features via Active Effects changes arrays", + "tasks": [ + { + "id": "11.1", + "name": "Extend EFFECT_KEYS mapping", + "description": "Add missing keys to module/helpers/effects.mjs: senses (6), movement capabilities (5), skill training (12), focus tracking", + "completed": true, + "tested": false, + "priority": "critical", + "dependencies": ["1.15"] + }, + { + "id": "11.2", + "name": "Create Active Effects reference documentation", + "description": "Create docs/ACTIVE_EFFECTS_REFERENCE.md documenting all available effect keys, modes, JSON format, and formula support", + "completed": true, + "tested": false, + "priority": "high", + "dependencies": ["11.1"] + }, + { + "id": "11.3", + "name": "Automate Dwarf ancestry traits", + "description": "Add changes arrays: Darksight (system.senses.darkvision=true), Tough (system.resources.hp.bonus=@level)", + "completed": true, + "tested": false, + "priority": "high", + "dependencies": ["11.1"], + "notes": "Sturdy trait deferred - requires conditional Favor flag system" + }, + { + "id": "11.4", + "name": "Automate Goblin ancestry traits", + "description": "Add changes arrays: Darksight (system.senses.darkvision=true), Nimble (system.speed.bonus=5)", + "completed": true, + "tested": false, + "priority": "high", + "dependencies": ["11.1"], + "notes": "Scavenger trait deferred - requires conditional Favor flag system" + }, + { + "id": "11.5", + "name": "Automate Orc ancestry traits", + "description": "Add changes arrays: Darksight (system.senses.darkvision=true), Hulking (system.itemSlots.bonus=2)", + "completed": true, + "tested": false, + "priority": "high", + "dependencies": ["11.1"], + "notes": "Beefy trait deferred - requires conditional Favor flag system" + }, + { + "id": "11.6", + "name": "Automate Halfling ancestry traits", + "description": "Add changes array: Nimble (system.speed.bonus=5)", + "completed": true, + "tested": false, + "priority": "high", + "dependencies": ["11.1"], + "notes": "Squat (movement rule) and Tricksy (rest bonus) deferred" + }, + { + "id": "11.7", + "name": "Automate Draken ancestry traits", + "description": "Add changes array: Scale (system.armor=+1)", + "completed": true, + "tested": false, + "priority": "high", + "dependencies": ["11.1"], + "notes": "Breath Attack (complex ability) and Draconic Resilience (damage type choice) deferred" + }, + { + "id": "11.8", + "name": "Automate Tough perk", + "description": "Verify changes array: system.resources.hp.bonus=@level (stackable)", + "completed": true, + "tested": false, + "priority": "high", + "dependencies": ["11.1"], + "notes": "Already had correct implementation from earlier work" + }, + { + "id": "11.9", + "name": "Automate Fighter class features", + "description": "Valor I/II/III crit reductions for melee and ranged attacks", + "completed": true, + "tested": false, + "priority": "high", + "dependencies": ["11.1"], + "notes": "Fighter is the proof of concept. Valor reduces melee+ranged crit thresholds by -1/-2/-3." + }, + { + "id": "11.10", + "name": "Automate Wizard class features", + "description": "Manifold Mind I/II: system.focus.maxConcurrent += 1 each (cumulative to 2, then 3)", + "completed": true, + "tested": false, + "priority": "high", + "dependencies": ["11.1"] + }, + { + "id": "11.11", + "name": "Implement Favor/Hinder flag system for traits", + "description": "Create flag-based system for conditional Favor/Hinder: Elven Eyes (Favor on sight-based Detect), Beefy (Favor on Grapple/Shove), Scavenger (Favor on Sickened saves), Sturdy (Favor on Fear/Sickened/Shove)", + "completed": false, + "tested": false, + "priority": "medium", + "dependencies": ["11.3", "11.4", "11.5"], + "notes": "Deferred - requires extending existing Favor/Hinder Active Effects flag system to handle conditional triggers" + }, + { + "id": "11.12", + "name": "Implement skill selection UI for ancestry traits", + "description": "Create dialog for traits that grant skill training choice: Elf Ascendancy (1 skill), Human Knack (1 skill + 1 perk)", + "completed": false, + "tested": false, + "priority": "medium", + "dependencies": ["11.3"], + "notes": "Deferred - requires UI similar to class level-up dialog" + }, + { + "id": "11.13", + "name": "Implement spell selection UI for ancestry traits", + "description": "Create dialog for traits that grant spells: Elf Naturally Attuned (1 spell of choice)", + "completed": false, + "tested": false, + "priority": "medium", + "dependencies": ["11.12"], + "notes": "Deferred - requires spell compendium browser integration" + }, + { + "id": "11.14", + "name": "Implement damage type selection for Draken", + "description": "Create dialog at ancestry add for Breath Attack damage type choice (fire/cold/shock/acid), applies to Draconic Resilience resistance", + "completed": false, + "tested": false, + "priority": "medium", + "dependencies": ["11.7"], + "notes": "Deferred - requires damage resistance system" + }, + { + "id": "11.15", + "name": "Implement rest bonus hooks", + "description": "Hook into rest system for: Halfling Tricksy (+1 Luck on rest)", + "completed": false, + "tested": false, + "priority": "low", + "dependencies": ["11.6"], + "notes": "Deferred - requires rest system implementation" + }, + { + "id": "11.16", + "name": "Implement Sharpshooter action tracking", + "description": "Track 'skip Move' action to enable crit reduction for Sharpshooter perk", + "completed": false, + "tested": false, + "priority": "low", + "dependencies": ["11.8"], + "notes": "Deferred - requires action economy tracking system" + }, + { + "id": "11.17", + "name": "Implement Situational Awareness automation", + "description": "Automate: Favor on surprise checks, flanking doesn't Hinder saves", + "completed": false, + "tested": false, + "priority": "low", + "dependencies": ["11.11"], + "notes": "Deferred - requires conditional Favor/Hinder flag system and flanking tracking" + }, + { + "id": "11.18", + "name": "Implement Gunslinger Deadeye tracking", + "description": "Track consecutive ranged hits to dynamically reduce crit threshold (resets each turn)", + "completed": false, + "tested": false, + "priority": "low", + "dependencies": ["11.1"], + "notes": "Deferred - requires combat turn state tracking, not a simple static bonus" + } + ] } ], "summary": { - "total_tasks": 98, - "phases": 11, + "total_tasks": 116, + "phases": 12, "critical_path": [ "0.1 -> 1.1 -> 2.1 -> 2.2 -> 3.1 -> 3.2 -> 7.1 -> 9.2", "0.1 -> 1.6 -> 1.9 -> 2.8 -> 7.4 -> 9.4" diff --git a/docs/ACTIVE_EFFECTS_REFERENCE.md b/docs/ACTIVE_EFFECTS_REFERENCE.md new file mode 100644 index 0000000..7f28243 --- /dev/null +++ b/docs/ACTIVE_EFFECTS_REFERENCE.md @@ -0,0 +1,273 @@ +# Active Effects Reference + +This document describes how to use Active Effects to automate mechanical bonuses from ancestries, perks, and class features in the Vagabond RPG Foundry VTT system. + +## Overview + +Active Effects are Foundry's mechanism for items (classes, perks, ancestries) to modify actor data. When an item with a `changes` array is added to an actor, the system automatically creates Active Effects that modify the actor's stats, resources, senses, etc. + +## Effect Modes + +| Mode | Constant | Value | Description | +| --------- | ------------------------ | ----- | ----------------------------------- | +| CUSTOM | `EFFECT_MODES.CUSTOM` | 0 | Custom logic (not commonly used) | +| MULTIPLY | `EFFECT_MODES.MULTIPLY` | 1 | Multiply the base value | +| ADD | `EFFECT_MODES.ADD` | 2 | Add to the base value (most common) | +| DOWNGRADE | `EFFECT_MODES.DOWNGRADE` | 3 | Use lower of base and effect value | +| UPGRADE | `EFFECT_MODES.UPGRADE` | 4 | Use higher of base and effect value | +| OVERRIDE | `EFFECT_MODES.OVERRIDE` | 5 | Replace the base value entirely | + +### When to Use Each Mode + +- **ADD (2)**: Numeric bonuses like +HP, +Speed, +Armor, crit threshold reductions +- **OVERRIDE (5)**: Boolean toggles like senses (darkvision), movement capabilities (fly), skill training + +## Available Effect Keys + +### Stats + +| Shorthand Key | Full Path | Type | Typical Mode | +| ---------------- | ------------------------------ | ------ | ------------ | +| `stat.might` | `system.stats.might.value` | Number | ADD | +| `stat.dexterity` | `system.stats.dexterity.value` | Number | ADD | +| `stat.awareness` | `system.stats.awareness.value` | Number | ADD | +| `stat.reason` | `system.stats.reason.value` | Number | ADD | +| `stat.presence` | `system.stats.presence.value` | Number | ADD | +| `stat.luck` | `system.stats.luck.value` | Number | ADD | + +### Resources + +| Shorthand Key | Full Path | Type | Typical Mode | +| ----------------- | ---------------------------------- | ------ | ------------ | +| `hp.bonus` | `system.resources.hp.bonus` | Number | ADD | +| `mana.bonus` | `system.resources.mana.bonus` | Number | ADD | +| `mana.castingMax` | `system.resources.mana.castingMax` | Number | ADD | +| `luck.max` | `system.resources.luck.max` | Number | ADD | +| `studiedDice.max` | `system.resources.studiedDice.max` | Number | ADD | + +### Combat Stats + +| Shorthand Key | Full Path | Type | Typical Mode | +| ----------------- | ------------------------ | ------ | ------------ | +| `armor` | `system.armor` | Number | ADD | +| `itemSlots.bonus` | `system.itemSlots.bonus` | Number | ADD | +| `speed.bonus` | `system.speed.bonus` | Number | ADD | + +### Save Bonuses + +| Shorthand Key | Full Path | Type | Typical Mode | +| ------------- | --------------------------- | ------ | ------------ | +| `save.reflex` | `system.saves.reflex.bonus` | Number | ADD | +| `save.endure` | `system.saves.endure.bonus` | Number | ADD | +| `save.will` | `system.saves.will.bonus` | Number | ADD | + +### Skill Crit Thresholds + +| Shorthand Key | Full Path | Type | Typical Mode | +| ------------------ | ----------------------------------------- | ------ | ------------ | +| `crit.arcana` | `system.skills.arcana.critThreshold` | Number | ADD | +| `crit.brawl` | `system.skills.brawl.critThreshold` | Number | ADD | +| `crit.craft` | `system.skills.craft.critThreshold` | Number | ADD | +| `crit.detect` | `system.skills.detect.critThreshold` | Number | ADD | +| `crit.finesse` | `system.skills.finesse.critThreshold` | Number | ADD | +| `crit.influence` | `system.skills.influence.critThreshold` | Number | ADD | +| `crit.leadership` | `system.skills.leadership.critThreshold` | Number | ADD | +| `crit.medicine` | `system.skills.medicine.critThreshold` | Number | ADD | +| `crit.mysticism` | `system.skills.mysticism.critThreshold` | Number | ADD | +| `crit.performance` | `system.skills.performance.critThreshold` | Number | ADD | +| `crit.sneak` | `system.skills.sneak.critThreshold` | Number | ADD | +| `crit.survival` | `system.skills.survival.critThreshold` | Number | ADD | + +### Attack Crit Thresholds + +| Shorthand Key | Full Path | Type | Typical Mode | +| --------------------- | -------------------------------------- | ------ | ------------ | +| `crit.attack.melee` | `system.attacks.melee.critThreshold` | Number | ADD | +| `crit.attack.brawl` | `system.attacks.brawl.critThreshold` | Number | ADD | +| `crit.attack.ranged` | `system.attacks.ranged.critThreshold` | Number | ADD | +| `crit.attack.finesse` | `system.attacks.finesse.critThreshold` | Number | ADD | + +### Senses (Boolean) + +| Shorthand Key | Full Path | Type | Typical Mode | +| -------------------- | ---------------------------- | ------- | ------------ | +| `sense.darkvision` | `system.senses.darkvision` | Boolean | OVERRIDE | +| `sense.blindsight` | `system.senses.blindsight` | Boolean | OVERRIDE | +| `sense.allsight` | `system.senses.allsight` | Boolean | OVERRIDE | +| `sense.echolocation` | `system.senses.echolocation` | Boolean | OVERRIDE | +| `sense.seismicsense` | `system.senses.seismicsense` | Boolean | OVERRIDE | +| `sense.telepathy` | `system.senses.telepathy` | Boolean | OVERRIDE | + +### Movement Capabilities (Boolean) + +| Shorthand Key | Full Path | Type | Typical Mode | +| ---------------- | ----------------------- | ------- | ------------ | +| `movement.fly` | `system.movement.fly` | Boolean | OVERRIDE | +| `movement.swim` | `system.movement.swim` | Boolean | OVERRIDE | +| `movement.climb` | `system.movement.climb` | Boolean | OVERRIDE | +| `movement.cling` | `system.movement.cling` | Boolean | OVERRIDE | +| `movement.phase` | `system.movement.phase` | Boolean | OVERRIDE | + +### Skill Training (Boolean) + +| Shorthand Key | Full Path | Type | Typical Mode | +| --------------------------- | ----------------------------------- | ------- | ------------ | +| `skill.arcana.trained` | `system.skills.arcana.trained` | Boolean | OVERRIDE | +| `skill.brawl.trained` | `system.skills.brawl.trained` | Boolean | OVERRIDE | +| `skill.craft.trained` | `system.skills.craft.trained` | Boolean | OVERRIDE | +| `skill.detect.trained` | `system.skills.detect.trained` | Boolean | OVERRIDE | +| `skill.finesse.trained` | `system.skills.finesse.trained` | Boolean | OVERRIDE | +| `skill.influence.trained` | `system.skills.influence.trained` | Boolean | OVERRIDE | +| `skill.leadership.trained` | `system.skills.leadership.trained` | Boolean | OVERRIDE | +| `skill.medicine.trained` | `system.skills.medicine.trained` | Boolean | OVERRIDE | +| `skill.mysticism.trained` | `system.skills.mysticism.trained` | Boolean | OVERRIDE | +| `skill.performance.trained` | `system.skills.performance.trained` | Boolean | OVERRIDE | +| `skill.sneak.trained` | `system.skills.sneak.trained` | Boolean | OVERRIDE | +| `skill.survival.trained` | `system.skills.survival.trained` | Boolean | OVERRIDE | + +### Focus Tracking + +| Shorthand Key | Full Path | Type | Typical Mode | +| --------------------- | ---------------------------- | ------ | ------------ | +| `focus.maxConcurrent` | `system.focus.maxConcurrent` | Number | ADD | + +## JSON Format + +### Ancestry Trait Example + +```json +{ + "name": "Darksight", + "description": "

You can see in darkness as if it were dim light.

", + "changes": [ + { + "key": "system.senses.darkvision", + "mode": 5, + "value": "true" + } + ] +} +``` + +### Perk Example + +```json +{ + "system": { + "changes": [ + { + "key": "system.resources.hp.bonus", + "mode": 2, + "value": "@level" + } + ] + } +} +``` + +### Class Feature Example + +```json +{ + "name": "Valor I", + "level": 1, + "description": "

The roll required for you to Crit on Attack Checks is reduced by 1.

", + "passive": true, + "changes": [ + { + "key": "system.attacks.melee.critThreshold", + "mode": 2, + "value": "-1", + "priority": 10 + }, + { + "key": "system.attacks.ranged.critThreshold", + "mode": 2, + "value": "-1", + "priority": 10 + } + ] +} +``` + +## Formula Support + +Values can use Roll Data formulas for dynamic calculations: + +| Formula | Description | +| ------------------------ | -------------------------- | +| `@level` | Character's current level | +| `@stats.might.value` | Character's Might stat | +| `@stats.dexterity.value` | Character's Dexterity stat | +| `@stats.awareness.value` | Character's Awareness stat | +| `@stats.reason.value` | Character's Reason stat | +| `@stats.presence.value` | Character's Presence stat | +| `@stats.luck.value` | Character's Luck stat | + +### Formula Examples + +```json +// HP bonus equal to level (Dwarf Tough, Tough Perk) +{ "key": "system.resources.hp.bonus", "mode": 2, "value": "@level" } + +// HP bonus equal to Might stat +{ "key": "system.resources.hp.bonus", "mode": 2, "value": "@stats.might.value" } +``` + +## Implementation Details + +### Where Changes Are Applied + +1. **Ancestry Traits**: `VagabondItem.applyAncestryTraits()` in `module/documents/item.mjs` +2. **Perk Effects**: `VagabondItem.applyPerkEffects()` in `module/documents/item.mjs` +3. **Class Features**: `VagabondItem.applyClassFeatures()` in `module/documents/item.mjs` + +### Key Mapping + +The system supports both full paths (`system.senses.darkvision`) and shorthand keys (`sense.darkvision`). Shorthand keys are mapped to full paths via `EFFECT_KEYS` in `module/helpers/effects.mjs`. + +### Priority + +Effects with higher priority values are applied later (and thus can override earlier effects). Default priority is `null`. Use explicit priority (e.g., `10`) when order matters. + +## Adding New Automatable Effects + +1. Add the key mapping to `EFFECT_KEYS` in `module/helpers/effects.mjs` +2. Ensure the target path exists in the actor data model (`module/data/actor/character.mjs`) +3. Add the `changes` array to the relevant compendium JSON file +4. Test by adding the item to a character and verifying the effect applies + +## Current Automated Effects + +### Ancestries + +| Ancestry | Trait | Effect | +| -------- | --------- | ------------------------------------- | +| Dwarf | Darksight | `system.senses.darkvision = true` | +| Dwarf | Tough | `system.resources.hp.bonus += @level` | +| Goblin | Darksight | `system.senses.darkvision = true` | +| Goblin | Nimble | `system.speed.bonus += 5` | +| Orc | Darksight | `system.senses.darkvision = true` | +| Orc | Hulking | `system.itemSlots.bonus += 2` | +| Halfling | Nimble | `system.speed.bonus += 5` | +| Draken | Scale | `system.armor += 1` | + +### Perks + +| Perk | Effect | +| ----- | ------------------------------------------------- | +| Tough | `system.resources.hp.bonus += @level` (stackable) | + +### Class Features + +| Class | Feature | Effect | +| ------- | ------------------ | -------------------------------------------------------------------------------------------------- | +| Fighter | Valor I/II/III | `system.attacks.melee.critThreshold -= 1`, `system.attacks.ranged.critThreshold -= 1` (cumulative) | +| Wizard | Manifold Mind I/II | `system.focus.maxConcurrent += 1` (cumulative, base 1 → 2 → 3) | + +### Not Automated (Complex Mechanics) + +| Class | Feature | Reason | +| ---------- | ------- | ------------------------------------------------------------------ | +| Gunslinger | Deadeye | Dynamic crit reduction based on consecutive hits, resets each turn | +| Magus | (none) | No simple numeric bonuses; features are spell-block related | diff --git a/module/helpers/effects.mjs b/module/helpers/effects.mjs index adba2c2..e9486c9 100644 --- a/module/helpers/effects.mjs +++ b/module/helpers/effects.mjs @@ -78,6 +78,38 @@ export const EFFECT_KEYS = { "crit.attack.brawl": "system.attacks.brawl.critThreshold", "crit.attack.ranged": "system.attacks.ranged.critThreshold", "crit.attack.finesse": "system.attacks.finesse.critThreshold", + + // Senses (boolean, use OVERRIDE mode=5) + "sense.darkvision": "system.senses.darkvision", + "sense.blindsight": "system.senses.blindsight", + "sense.allsight": "system.senses.allsight", + "sense.echolocation": "system.senses.echolocation", + "sense.seismicsense": "system.senses.seismicsense", + "sense.telepathy": "system.senses.telepathy", + + // Movement capabilities (boolean, use OVERRIDE mode=5) + "movement.fly": "system.movement.fly", + "movement.swim": "system.movement.swim", + "movement.climb": "system.movement.climb", + "movement.cling": "system.movement.cling", + "movement.phase": "system.movement.phase", + + // Skill training (boolean, use OVERRIDE mode=5) + "skill.arcana.trained": "system.skills.arcana.trained", + "skill.brawl.trained": "system.skills.brawl.trained", + "skill.craft.trained": "system.skills.craft.trained", + "skill.detect.trained": "system.skills.detect.trained", + "skill.finesse.trained": "system.skills.finesse.trained", + "skill.influence.trained": "system.skills.influence.trained", + "skill.leadership.trained": "system.skills.leadership.trained", + "skill.medicine.trained": "system.skills.medicine.trained", + "skill.mysticism.trained": "system.skills.mysticism.trained", + "skill.performance.trained": "system.skills.performance.trained", + "skill.sneak.trained": "system.skills.sneak.trained", + "skill.survival.trained": "system.skills.survival.trained", + + // Focus tracking + "focus.maxConcurrent": "system.focus.maxConcurrent", }; /** diff --git a/packs/_source/ancestries/draken.json b/packs/_source/ancestries/draken.json index d5c7502..6d14e9c 100755 --- a/packs/_source/ancestries/draken.json +++ b/packs/_source/ancestries/draken.json @@ -11,15 +11,18 @@ "traits": [ { "name": "Breath Attack", - "description": "

As an Action, you can breathe elemental energy in a 15-foot cone, dealing 2d6! damage of your chosen type (fire, cold, shock, or acid, chosen at character creation). Targets may make a Reflex save to take half damage.

" + "description": "

As an Action, you can breathe elemental energy in a 15-foot cone, dealing 2d6! damage of your chosen type (fire, cold, shock, or acid, chosen at character creation). Targets may make a Reflex save to take half damage.

", + "changes": [] }, { "name": "Scale", - "description": "

Your natural scales grant you +1 Armor.

" + "description": "

Your natural scales grant you +1 Armor.

", + "changes": [{ "key": "system.armor", "mode": 2, "value": "1" }] }, { "name": "Draconic Resilience", - "description": "

You take half damage from one damage type of your choice (matching your breath weapon).

" + "description": "

You take half damage from one damage type of your choice (matching your breath weapon).

", + "changes": [] } ] }, diff --git a/packs/_source/ancestries/goblin.json b/packs/_source/ancestries/goblin.json index 20c81a2..4ad1344 100755 --- a/packs/_source/ancestries/goblin.json +++ b/packs/_source/ancestries/goblin.json @@ -11,15 +11,18 @@ "traits": [ { "name": "Darksight", - "description": "

You can see in darkness as if it were dim light.

" + "description": "

You can see in darkness as if it were dim light.

", + "changes": [{ "key": "system.senses.darkvision", "mode": 5, "value": "true" }] }, { "name": "Nimble", - "description": "

Your base Speed is increased by 5.

" + "description": "

Your base Speed is increased by 5.

", + "changes": [{ "key": "system.speed.bonus", "mode": 2, "value": "5" }] }, { "name": "Scavenger", - "description": "

You gain Favor on saves against the Sickened condition.

" + "description": "

You gain Favor on saves against the Sickened condition.

", + "changes": [] } ] }, diff --git a/packs/_source/ancestries/halfling.json b/packs/_source/ancestries/halfling.json index 34bdc80..57b6a69 100755 --- a/packs/_source/ancestries/halfling.json +++ b/packs/_source/ancestries/halfling.json @@ -11,15 +11,18 @@ "traits": [ { "name": "Nimble", - "description": "

Your base Speed is increased by 5.

" + "description": "

Your base Speed is increased by 5.

", + "changes": [{ "key": "system.speed.bonus", "mode": 2, "value": "5" }] }, { "name": "Squat", - "description": "

You can move through spaces occupied by larger creatures.

" + "description": "

You can move through spaces occupied by larger creatures.

", + "changes": [] }, { "name": "Tricksy", - "description": "

When you take a Rest, you regain +1 additional Luck.

" + "description": "

When you take a Rest, you regain +1 additional Luck.

", + "changes": [] } ] }, diff --git a/packs/_source/ancestries/orc.json b/packs/_source/ancestries/orc.json index f360704..ea4e699 100755 --- a/packs/_source/ancestries/orc.json +++ b/packs/_source/ancestries/orc.json @@ -11,15 +11,18 @@ "traits": [ { "name": "Darksight", - "description": "

You can see in darkness as if it were dim light.

" + "description": "

You can see in darkness as if it were dim light.

", + "changes": [{ "key": "system.senses.darkvision", "mode": 5, "value": "true" }] }, { "name": "Beefy", - "description": "

You gain Favor on Grapple and Shove attempts.

" + "description": "

You gain Favor on Grapple and Shove attempts.

", + "changes": [] }, { "name": "Hulking", - "description": "

You have +2 additional Item Slots.

" + "description": "

You have +2 additional Item Slots.

", + "changes": [{ "key": "system.itemSlots.bonus", "mode": 2, "value": "2" }] } ] }, diff --git a/packs/_source/classes/wizard.json b/packs/_source/classes/wizard.json index 859378b..61548f6 100755 --- a/packs/_source/classes/wizard.json +++ b/packs/_source/classes/wizard.json @@ -74,7 +74,9 @@ "level": 4, "description": "

You can Focus on up to two Spells at the same time.

", "passive": true, - "changes": [] + "changes": [ + { "key": "system.focus.maxConcurrent", "mode": 2, "value": "1", "priority": 10 } + ] }, { "name": "Extracurricular", @@ -88,7 +90,9 @@ "level": 8, "description": "

You can now Focus on up to three Spells at the same time.

", "passive": true, - "changes": [] + "changes": [ + { "key": "system.focus.maxConcurrent", "mode": 2, "value": "1", "priority": 10 } + ] }, { "name": "Archwizard",