diff --git a/lang/en.json b/lang/en.json index 2ee02386..99daf69b 100755 --- a/lang/en.json +++ b/lang/en.json @@ -130,7 +130,8 @@ "RangeDependance": { "hint": "Settings for an optional distance at which this effect should activate", "title": "Range Dependant" - } + }, + "immuneStatusText": "Immunity: {status}" }, "ACTORS": { "Adversary": { @@ -396,7 +397,8 @@ "stressReduction": "Reduce By Stress", "title": "Damage Reduction", "unncessaryStress": "You don't need to expend stress", - "usedMarks": "Used Marks" + "usedMarks": "Used Marks", + "reduceSeverity": "Severity Reduced By {nr}" }, "DeathMove": { "selectMove": "Select Move", @@ -1034,7 +1036,8 @@ }, "ItemResourceType": { "simple": "Simple", - "diceValue": "Dice Value" + "diceValue": "Dice Value", + "die": "Die" }, "Range": { "self": { @@ -2530,7 +2533,8 @@ "abilityCheckTitle": "{ability} Check" }, "effectSummary": { - "title": "Effects Applied" + "title": "Effects Applied", + "immunityTo": "Immunity: {immunities}" }, "featureTitle": "Class Feature", "groupRoll": { @@ -2728,7 +2732,8 @@ "rightClickExtand": "Right-Click to extand", "companionPartnerLevelBlock": "The companion needs an assigned partner to level up.", "configureAttribution": "Configure Attribution", - "deleteItem": "Delete Item" + "deleteItem": "Delete Item", + "immune": "Immune" } } } diff --git a/module/applications/dialogs/damageReductionDialog.mjs b/module/applications/dialogs/damageReductionDialog.mjs index b64149c0..cd0a5cf7 100644 --- a/module/applications/dialogs/damageReductionDialog.mjs +++ b/module/applications/dialogs/damageReductionDialog.mjs @@ -10,6 +10,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap this.reject = reject; this.actor = actor; this.damage = damage; + this.damageType = damageType; this.rulesDefault = game.settings.get( CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation @@ -57,6 +58,11 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap null ); + this.reduceSeverity = this.damageType.reduce((value, curr) => { + return Math.max(this.actor.system.rules.damageReduction.reduceSeverity[curr], value); + }, 0); + this.actor.system.rules.damageReduction.reduceSeverity[this.damageType]; + this.thresholdImmunities = Object.keys(actor.system.rules.damageReduction.thresholdImmunities).reduce( (acc, key) => { if (actor.system.rules.damageReduction.thresholdImmunities[key]) @@ -111,7 +117,9 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap CONFIG.DH.GENERAL.ruleChoice.onWithToggle.id, CONFIG.DH.GENERAL.ruleChoice.offWithToggle.id ].includes(this.rulesDefault); - context.thresholdImmunities = this.thresholdImmunities; + context.reduceSeverity = this.reduceSeverity; + context.thresholdImmunities = + Object.keys(this.thresholdImmunities).length > 0 ? this.thresholdImmunities : null; const { selectedArmorMarks, selectedStressMarks, stressReductions, currentMarks, currentDamage } = this.getDamageInfo(); @@ -173,6 +181,9 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap this.damage - armorMarkReduction - selectedStressMarks.length - stressReductions.length, 0 ); + if (this.reduceSeverity) { + currentDamage = Math.max(currentDamage - this.reduceSeverity, 0); + } if (this.thresholdImmunities[currentDamage]) currentDamage = 0; diff --git a/module/applications/hud/tokenHUD.mjs b/module/applications/hud/tokenHUD.mjs index a5fd719f..8898ff0b 100644 --- a/module/applications/hud/tokenHUD.mjs +++ b/module/applications/hud/tokenHUD.mjs @@ -33,7 +33,10 @@ export default class DHTokenHUD extends foundry.applications.hud.TokenHUD { : context.canToggleCombat; context.systemStatusEffects = Object.keys(context.statusEffects).reduce((acc, key) => { const effect = context.statusEffects[key]; - if (effect.systemEffect) acc[key] = effect; + if (effect.systemEffect) { + const disabled = !effect.isActive && this.actor.system.rules.conditionImmunities[key]; + acc[key] = { ...effect, disabled }; + } return acc; }, {}); diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 01eb2105..c4962b18 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -30,6 +30,7 @@ export default class CharacterSheet extends DHBaseActorSheet { toggleEquipItem: CharacterSheet.#toggleEquipItem, toggleResourceDice: CharacterSheet.#toggleResourceDice, handleResourceDice: CharacterSheet.#handleResourceDice, + advanceResourceDie: CharacterSheet.#advanceResourceDie, cancelBeastform: CharacterSheet.#cancelBeastform, useDowntime: this.useDowntime }, @@ -147,6 +148,10 @@ export default class CharacterSheet extends DHBaseActorSheet { htmlElement.querySelectorAll('.armor-marks-input').forEach(element => { element.addEventListener('change', this.updateArmorMarks.bind(this)); }); + + htmlElement.querySelectorAll('.item-resource.die').forEach(element => { + element.addEventListener('contextmenu', this.lowerResourceDie.bind(this)); + }); } /** @inheritdoc */ @@ -857,6 +862,27 @@ export default class CharacterSheet extends DHBaseActorSheet { }); } + /** */ + static #advanceResourceDie(_, target) { + this.updateResourceDie(target, true); + } + + lowerResourceDie(event) { + event.preventDefault(); + event.stopPropagation(); + this.updateResourceDie(event.target, false); + } + + async updateResourceDie(target, advance) { + const item = await getDocFromElement(target); + if (!item) return; + + const advancedValue = item.system.resource.value + (advance ? 1 : -1); + await item.update({ + 'system.resource.value': Math.min(advancedValue, Number(item.system.resource.dieFaces.split('d')[1])) + }); + } + /** * */ diff --git a/module/canvas/placeables/token.mjs b/module/canvas/placeables/token.mjs index 09b3b192..367e7682 100644 --- a/module/canvas/placeables/token.mjs +++ b/module/canvas/placeables/token.mjs @@ -24,7 +24,7 @@ export default class DhTokenPlaceable extends foundry.canvas.placeables.Token { acc.push({ name: game.i18n.localize(statusData.name), statuses: [status], - img: statusData.icon, + img: statusData.icon ?? statusData.img, tint: effect.tint }); } diff --git a/module/config/itemConfig.mjs b/module/config/itemConfig.mjs index 544d6b2d..0dd7c587 100644 --- a/module/config/itemConfig.mjs +++ b/module/config/itemConfig.mjs @@ -1519,6 +1519,10 @@ export const itemResourceTypes = { diceValue: { id: 'diceValue', label: 'DAGGERHEART.CONFIG.ItemResourceType.diceValue' + }, + die: { + id: 'die', + label: 'DAGGERHEART.CONFIG.ItemResourceType.die' } }; diff --git a/module/data/actor/adversary.mjs b/module/data/actor/adversary.mjs index 0e74e0c8..5e25202c 100644 --- a/module/data/actor/adversary.mjs +++ b/module/data/actor/adversary.mjs @@ -57,6 +57,13 @@ export default class DhpAdversary extends BaseDataActor { hitPoints: resourceField(0, 0, 'DAGGERHEART.GENERAL.HitPoints.plural', true), stress: resourceField(0, 0, 'DAGGERHEART.GENERAL.stress', true) }), + rules: new fields.SchemaField({ + conditionImmunities: new fields.SchemaField({ + hidden: new fields.BooleanField({ initial: false }), + restrained: new fields.BooleanField({ initial: false }), + vulnerable: new fields.BooleanField({ initial: false }) + }) + }), attack: new ActionField({ initial: { name: 'Attack', diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 645a50da..638da365 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -250,6 +250,10 @@ export default class DhCharacter extends BaseDataActor { thresholdImmunities: new fields.SchemaField({ minor: new fields.BooleanField({ initial: false }) }), + reduceSeverity: new fields.SchemaField({ + magical: new fields.NumberField({ initial: 0, min: 0 }), + physical: new fields.NumberField({ initial: 0, min: 0 }) + }), disabledArmor: new fields.BooleanField({ intial: false }) }), attack: new fields.SchemaField({ @@ -279,6 +283,11 @@ export default class DhCharacter extends BaseDataActor { }) }) }), + conditionImmunities: new fields.SchemaField({ + hidden: new fields.BooleanField({ initial: false }), + restrained: new fields.BooleanField({ initial: false }), + vulnerable: new fields.BooleanField({ initial: false }) + }), runeWard: new fields.BooleanField({ initial: false }), burden: new fields.SchemaField({ ignore: new fields.BooleanField() diff --git a/module/data/actor/companion.mjs b/module/data/actor/companion.mjs index 48572460..a66cd028 100644 --- a/module/data/actor/companion.mjs +++ b/module/data/actor/companion.mjs @@ -51,6 +51,13 @@ export default class DhCompanion extends BaseDataActor { } } ), + rules: new fields.SchemaField({ + conditionImmunities: new fields.SchemaField({ + hidden: new fields.BooleanField({ initial: false }), + restrained: new fields.BooleanField({ initial: false }), + vulnerable: new fields.BooleanField({ initial: false }) + }) + }), attack: new ActionField({ initial: { name: 'Attack', diff --git a/module/data/fields/action/effectsField.mjs b/module/data/fields/action/effectsField.mjs index 528a8658..d9658736 100644 --- a/module/data/fields/action/effectsField.mjs +++ b/module/data/fields/action/effectsField.mjs @@ -47,6 +47,7 @@ export default class EffectsField extends fields.ArrayField { static async applyEffects(targets) { if (!this.effects?.length || !targets?.length) return; + const conditions = CONFIG.DH.GENERAL.conditions(); let effects = this.effects; const messageTargets = []; targets.forEach(async baseToken => { @@ -56,7 +57,20 @@ export default class EffectsField extends fields.ArrayField { const token = canvas.tokens.get(baseToken.id) ?? foundry.utils.fromUuidSync(baseToken.actorId).prototypeToken; if (!token) return; - messageTargets.push(token.document ?? token); + + const messageToken = token.document ?? token; + const conditionImmunities = messageToken.actor.system.rules.conditionImmunities ?? {}; + messageTargets.push({ + token: messageToken, + conditionImmunities: Object.values(conditionImmunities).some(x => x) + ? game.i18n.format('DAGGERHEART.UI.Chat.effectSummary.immunityTo', { + immunities: Object.keys(conditionImmunities) + .filter(x => conditionImmunities[x]) + .map(x => game.i18n.localize(conditions[x].name)) + .join(', ') + }) + : null + }); effects.forEach(async e => { const effect = this.item.effects.get(e._id); diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index b2896513..1724ec13 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -57,6 +57,27 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect { update.img = 'icons/magic/life/heart-cross-blue.webp'; } + const immuneStatuses = + data.statuses?.filter( + status => + this.parent.system.rules?.conditionImmunities && + this.parent.system.rules.conditionImmunities[status] + ) ?? []; + if (immuneStatuses.length > 0) { + update.statuses = data.statuses.filter(x => !immuneStatuses.includes(x)); + const conditions = CONFIG.DH.GENERAL.conditions(); + const scrollingTexts = immuneStatuses.map(status => ({ + text: game.i18n.format('DAGGERHEART.ACTIVEEFFECT.immuneStatusText', { + status: game.i18n.localize(conditions[status].name) + }) + })); + if (update.statuses.length > 0) { + setTimeout(() => scrollingTexts, 500); + } else { + this.parent.queueScrollText(scrollingTexts); + } + } + if (Object.keys(update).length > 0) { await this.updateSource(update); } @@ -76,7 +97,10 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect { change.value = change.value.replaceAll(/origin\.@/gi, '@'); try { const effect = foundry.utils.fromUuidSync(change.effect.origin); - const doc = effect.parent?.parent; + const doc = + effect.parent?.parent instanceof game.system.api.documents.DhpActor + ? effect.parent + : effect.parent.parent; if (doc) parseModel = doc; } catch (_) {} } diff --git a/module/systemRegistration/handlebars.mjs b/module/systemRegistration/handlebars.mjs index 2b87dda1..32e047fd 100644 --- a/module/systemRegistration/handlebars.mjs +++ b/module/systemRegistration/handlebars.mjs @@ -12,7 +12,10 @@ export const preloadHandlebarsTemplates = async function () { 'systems/daggerheart/templates/sheets/global/partials/action-item.hbs', 'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs', 'systems/daggerheart/templates/sheets/global/partials/item-resource.hbs', - 'systems/daggerheart/templates/sheets/global/partials/resource-section.hbs', + 'systems/daggerheart/templates/sheets/global/partials/resource-section/resource-section.hbs', + 'systems/daggerheart/templates/sheets/global/partials/resource-section/simple.hbs', + 'systems/daggerheart/templates/sheets/global/partials/resource-section/dice-value.hbs', + 'systems/daggerheart/templates/sheets/global/partials/resource-section/die.hbs', 'systems/daggerheart/templates/sheets/global/partials/resource-bar.hbs', 'systems/daggerheart/templates/components/card-preview.hbs', 'systems/daggerheart/templates/levelup/parts/selectable-card-preview.hbs', diff --git a/src/packs/adversaries/adversary_Bear_71qKDLKO3CsrNkdy.json b/src/packs/adversaries/adversary_Bear_71qKDLKO3CsrNkdy.json index dc8f4013..8be83035 100644 --- a/src/packs/adversaries/adversary_Bear_71qKDLKO3CsrNkdy.json +++ b/src/packs/adversaries/adversary_Bear_71qKDLKO3CsrNkdy.json @@ -401,7 +401,7 @@ "description": "
You are Restrained until you break free with a successful Strength Roll.
", "tint": "#ffffff", "statuses": [ - "restrain" + "restrained" ], "sort": 0, "flags": {}, diff --git a/src/packs/adversaries/adversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json b/src/packs/adversaries/adversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json index 446aee22..c63ced47 100644 --- a/src/packs/adversaries/adversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json +++ b/src/packs/adversaries/adversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json @@ -239,7 +239,59 @@ }, "_id": "m6uPm4vujrUjSFPw", "img": "icons/magic/air/fog-gas-smoke-blue-gray.webp", - "effects": [], + "effects": [ + { + "name": "Levitation", + "type": "base", + "system": { + "rangeDependence": { + "enabled": false, + "type": "withinRange", + "target": "hostile", + "range": "melee" + } + }, + "_id": "k6iaQVfMZhrpwYQj", + "img": "icons/magic/air/fog-gas-smoke-blue-gray.webp", + "changes": [ + { + "key": "system.rules.conditionImmunities.restrained", + "mode": 5, + "value": "1", + "priority": null + } + ], + "disabled": false, + "duration": { + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null + }, + "description": "The Skull levitates several feet off the ground and can’t be Restrained.
", + "origin": null, + "tint": "#ffffff", + "transfer": true, + "statuses": [], + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.351", + "systemId": "daggerheart", + "systemVersion": "1.2.4", + "createdTime": 1763845938979, + "modifiedTime": 1763846023794, + "lastModifiedBy": "Q4RzhhaPfvLUzzbw" + }, + "_key": "!actors.items.effects!jDmHqGvzg5wjgmxE.m6uPm4vujrUjSFPw.k6iaQVfMZhrpwYQj" + } + ], "folder": null, "sort": 0, "ownership": { diff --git a/src/packs/adversaries/adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json b/src/packs/adversaries/adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json index 091b862c..156b1908 100644 --- a/src/packs/adversaries/adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json +++ b/src/packs/adversaries/adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json @@ -580,7 +580,7 @@ "description": "You are Restrained in smoky chains until you break free with a successful Strength or Instinct Roll. A target Restrained by this feature must spend a Hope to make an action roll.
", "tint": "#ffffff", "statuses": [ - "restrain" + "restrained" ], "sort": 0, "flags": {}, diff --git a/src/packs/adversaries/adversary_Deeproot_Defender_9x2xY9zwc3xzbXo5.json b/src/packs/adversaries/adversary_Deeproot_Defender_9x2xY9zwc3xzbXo5.json index d14eff69..5f97abe1 100644 --- a/src/packs/adversaries/adversary_Deeproot_Defender_9x2xY9zwc3xzbXo5.json +++ b/src/packs/adversaries/adversary_Deeproot_Defender_9x2xY9zwc3xzbXo5.json @@ -439,7 +439,7 @@ "description": "You are Restrained until the Defender takes Severe damage.
", "tint": "#ffffff", "statuses": [ - "restrain" + "restrained" ], "sort": 0, "flags": {}, diff --git a/src/packs/adversaries/adversary_Giant_Beastmaster_8VZIgU12cB3cvlyH.json b/src/packs/adversaries/adversary_Giant_Beastmaster_8VZIgU12cB3cvlyH.json index 5c09cd95..05bf04de 100644 --- a/src/packs/adversaries/adversary_Giant_Beastmaster_8VZIgU12cB3cvlyH.json +++ b/src/packs/adversaries/adversary_Giant_Beastmaster_8VZIgU12cB3cvlyH.json @@ -385,7 +385,7 @@ "description": "You are Restrained until you break free with a successful Finesse or Strength Roll.
", "tint": "#ffffff", "statuses": [ - "restrain" + "restrained" ], "sort": 0, "flags": {}, diff --git a/src/packs/adversaries/adversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json b/src/packs/adversaries/adversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json index f400054b..0a027340 100644 --- a/src/packs/adversaries/adversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json +++ b/src/packs/adversaries/adversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json @@ -624,7 +624,7 @@ "description": "", "tint": "#ffffff", "statuses": [ - "restrain" + "restrained" ], "sort": 0, "flags": {}, diff --git a/src/packs/adversaries/adversary_Gorgon_8mJYMpbLTb8qIOrr.json b/src/packs/adversaries/adversary_Gorgon_8mJYMpbLTb8qIOrr.json index ed8cf539..378fffd2 100644 --- a/src/packs/adversaries/adversary_Gorgon_8mJYMpbLTb8qIOrr.json +++ b/src/packs/adversaries/adversary_Gorgon_8mJYMpbLTb8qIOrr.json @@ -355,7 +355,14 @@ "range": "melee" } }, - "changes": [], + "changes": [ + { + "key": "system.rules.conditionImmunities.hidden", + "mode": 5, + "value": "1", + "priority": null + } + ], "disabled": false, "duration": { "startTime": null, @@ -366,7 +373,7 @@ "startRound": null, "startTurn": null }, - "description": "You Glow until the end of the scene and can’t become Hidden. Attack rolls made against you have advantage.
", + "description": "You Glow until the end of the scene and can’t become Hidden. Attack rolls made against you have advantage.
", "tint": "#ffffff", "statuses": [], "sort": 0, @@ -375,12 +382,12 @@ "compendiumSource": null, "duplicateSource": null, "exportSource": null, - "coreVersion": "13.346", + "coreVersion": "13.351", "systemId": "daggerheart", "systemVersion": "0.0.1", "createdTime": 1754079525282, - "modifiedTime": 1754079558712, - "lastModifiedBy": "MQSznptE5yLT7kj8" + "modifiedTime": 1763847816177, + "lastModifiedBy": "Q4RzhhaPfvLUzzbw" }, "_key": "!actors.items.effects!8mJYMpbLTb8qIOrr.NepVGKOo1lHYjA1F.bYBrgiSwHwYfQyjn" } diff --git a/src/packs/adversaries/adversary_Kraken_4nqv3ZwJGjnmic8j.json b/src/packs/adversaries/adversary_Kraken_4nqv3ZwJGjnmic8j.json index 32282950..1085e0eb 100644 --- a/src/packs/adversaries/adversary_Kraken_4nqv3ZwJGjnmic8j.json +++ b/src/packs/adversaries/adversary_Kraken_4nqv3ZwJGjnmic8j.json @@ -426,7 +426,7 @@ "description": "You are Restrained and Vulnerable until you break free with a successful Strength Roll or the Kraken takes Major or greater damage. While Restrained and Vulnerable in this way, you must mark a Stress when you make an action roll.
", "tint": "#ffffff", "statuses": [ - "restrain", + "restrained", "vulnerable" ], "sort": 0, diff --git a/src/packs/adversaries/adversary_Masked_Thief_niBpVU7yeo5ccskE.json b/src/packs/adversaries/adversary_Masked_Thief_niBpVU7yeo5ccskE.json index 7d16e606..df42ee06 100644 --- a/src/packs/adversaries/adversary_Masked_Thief_niBpVU7yeo5ccskE.json +++ b/src/packs/adversaries/adversary_Masked_Thief_niBpVU7yeo5ccskE.json @@ -432,7 +432,7 @@ "description": "You are Restrained and Vulnerable until you break free, ending both conditions, with a successful Finesse or Strength Roll (13).
[[/dr trait=finesse difficulty=13]]
[[/dr trait=strength difficulty=13]]
You are Restrained within the Gaoler until freed with a successful Strength Roll (18). While Restrained, you can only attack the Gaoler.
", "tint": "#ffffff", "statuses": [ - "restrain" + "restrained" ], "sort": 0, "flags": {}, diff --git a/src/packs/adversaries/adversary_Young_Dryad_8yUj2Mzvnifhxegm.json b/src/packs/adversaries/adversary_Young_Dryad_8yUj2Mzvnifhxegm.json index 5449bf90..12894c19 100644 --- a/src/packs/adversaries/adversary_Young_Dryad_8yUj2Mzvnifhxegm.json +++ b/src/packs/adversaries/adversary_Young_Dryad_8yUj2Mzvnifhxegm.json @@ -399,7 +399,7 @@ "description": "You are Restrained until you're freed with a successful Strength Roll. When a creature makes an action roll against the cage, they must mark a Stress.
", "tint": "#ffffff", "statuses": [ - "restrain" + "restrained" ], "sort": 0, "flags": {}, diff --git a/src/packs/classes/feature_Unstoppable_PnD2UCgzIlwX6cY3.json b/src/packs/classes/feature_Unstoppable_PnD2UCgzIlwX6cY3.json index c768b09f..2c40d0af 100644 --- a/src/packs/classes/feature_Unstoppable_PnD2UCgzIlwX6cY3.json +++ b/src/packs/classes/feature_Unstoppable_PnD2UCgzIlwX6cY3.json @@ -5,9 +5,46 @@ "_id": "PnD2UCgzIlwX6cY3", "img": "icons/magic/defensive/shield-barrier-glowing-blue.webp", "system": { - "description": "(Note: This needs to be manually implemented. Unstoppable die feature is not implemented as of this time)
Once per long rest, you can become Unstoppable. You gain an Unstoppable Die. At level 1, your Unstoppable Die is a d4. Place it on your character sheet in the space provided, starting with the 1 value facing up. After you make a damage roll that deals 1 or more Hit Points to a target, increase the Unstoppable Die value by one. When the die’s value would exceed its maximum value or when the scene ends, remove the die and drop out of Unstoppable. At level 5, your Unstoppable Die increases to a d6. While Unstoppable, you gain the following benefits:
You reduce the severity of physical damage by one threshold (Severe to Major, Major to Minor, Minor to None).
You add the current value of the Unstoppable Die to your damage roll.
You can’t be Restrained or Vulnerable.
", - "resource": null, - "actions": {}, + "description": "Tip: If your Unstoppable Die is a d4 and the 4 is currently facing up, you remove the die the next time you would increase it. However, if your Unstoppable Die has increased to a d6 and the 4 is currently facing up, you’ll turn it to 5 the next time you would increase it. In this case, you’ll remove the die after you would need to increase it higher than 6.
Once per long rest, you can become Unstoppable. You gain an Unstoppable Die. At level 1, your Unstoppable Die is a d4. Place it on your character sheet in the space provided, starting with the 1 value facing up. After you make a damage roll that deals 1 or more Hit Points to a target, increase the Unstoppable Die value by one. When the die’s value would exceed its maximum value or when the scene ends, remove the die and drop out of Unstoppable. At level 5, your Unstoppable Die increases to a d6. While Unstoppable, you gain the following benefits:
You reduce the severity of physical damage by one threshold (Severe to Major, Major to Minor, Minor to None).
You add the current value of the Unstoppable Die to your damage roll.
You can’t be Restrained or Vulnerable.
", + "resource": { + "type": "die", + "value": 0, + "max": "", + "icon": "" + }, + "actions": { + "KZiZ8m8uqH5iG96d": { + "type": "effect", + "_id": "KZiZ8m8uqH5iG96d", + "systemPath": "actions", + "description": "Tip: If your Unstoppable Die is a d4 and the 4 is currently facing up, you remove the die the next time you would increase it. However, if your Unstoppable Die has increased to a d6 and the 4 is currently facing up, you’ll turn it to 5 the next time you would increase it. In this case, you’ll remove the die after you would need to increase it higher than 6.
Once per long rest, you can become Unstoppable. You gain an Unstoppable Die. At level 1, your Unstoppable Die is a d4. Place it on your character sheet in the space provided, starting with the 1 value facing up. After you make a damage roll that deals 1 or more Hit Points to a target, increase the Unstoppable Die value by one. When the die’s value would exceed its maximum value or when the scene ends, remove the die and drop out of Unstoppable. At level 5, your Unstoppable Die increases to a d6. While Unstoppable, you gain the following benefits:
You reduce the severity of physical damage by one threshold (Severe to Major, Major to Minor, Minor to None).
You add the current value of the Unstoppable Die to your damage roll.
You can’t be Restrained or Vulnerable.
", + "chatDisplay": true, + "originItem": { + "type": "itemCollection" + }, + "actionType": "action", + "cost": [], + "uses": { + "value": null, + "max": "1", + "recovery": "longRest", + "consumeOnSuccess": false + }, + "effects": [ + { + "_id": "xzQtFSuDS48kUdAZ", + "onSave": false + } + ], + "target": { + "type": "self", + "amount": null + }, + "name": "Become Unstoppable", + "img": "icons/magic/defensive/shield-barrier-glowing-blue.webp", + "range": "" + } + }, "originItemType": null, "originId": null, "attribution": { @@ -16,7 +53,83 @@ "artist": "" } }, - "effects": [], + "effects": [ + { + "name": "Unstoppable", + "img": "icons/magic/defensive/shield-barrier-glowing-blue.webp", + "origin": "Compendium.daggerheart.classes.Item.PnD2UCgzIlwX6cY3", + "transfer": false, + "_id": "xzQtFSuDS48kUdAZ", + "type": "base", + "system": { + "rangeDependence": { + "enabled": false, + "type": "withinRange", + "target": "hostile", + "range": "melee" + } + }, + "changes": [ + { + "key": "system.bonuses.damage.physical.bonus", + "mode": 2, + "value": "ORIGIN.@item.resource.value", + "priority": null + }, + { + "key": "system.bonuses.damage.magical.bonus", + "mode": 2, + "value": "ORIGIN.@item.resource.value", + "priority": null + }, + { + "key": "system.rules.damageReduction.reduceSeverity.physical", + "mode": 2, + "value": "1", + "priority": null + }, + { + "key": "system.rules.conditionImmunities.vulnerable", + "mode": 5, + "value": "1", + "priority": null + }, + { + "key": "system.rules.conditionImmunities.restrained", + "mode": 5, + "value": "1", + "priority": null + } + ], + "disabled": false, + "duration": { + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null + }, + "description": "", + "tint": "#ffffff", + "statuses": [], + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null, + "duplicateSource": null, + "exportSource": null, + "coreVersion": "13.351", + "systemId": "daggerheart", + "systemVersion": "1.2.4", + "createdTime": 1763835871799, + "modifiedTime": 1763843691784, + "lastModifiedBy": "Q4RzhhaPfvLUzzbw" + }, + "_key": "!items.effects!PnD2UCgzIlwX6cY3.xzQtFSuDS48kUdAZ" + } + ], "sort": 0, "ownership": { "default": 0, @@ -27,12 +140,12 @@ "compendiumSource": null, "duplicateSource": null, "exportSource": null, - "coreVersion": "13.347", + "coreVersion": "13.351", "systemId": "daggerheart", - "systemVersion": "1.0.5", + "systemVersion": "1.2.4", "createdTime": 1754246498657, - "modifiedTime": 1755391250586, - "lastModifiedBy": "VZIeX2YDvX338Zvr" + "modifiedTime": 1763839481783, + "lastModifiedBy": "Q4RzhhaPfvLUzzbw" }, "_key": "!items!PnD2UCgzIlwX6cY3" } diff --git a/src/packs/domains/domainCard_Book_of_Norai_WtwSWXTRZa7QVvmo.json b/src/packs/domains/domainCard_Book_of_Norai_WtwSWXTRZa7QVvmo.json index 4db3e78f..da819526 100644 --- a/src/packs/domains/domainCard_Book_of_Norai_WtwSWXTRZa7QVvmo.json +++ b/src/packs/domains/domainCard_Book_of_Norai_WtwSWXTRZa7QVvmo.json @@ -211,7 +211,7 @@ "description": "", "tint": "#ffffff", "statuses": [ - "restrain" + "restrained" ], "sort": 0, "flags": {}, diff --git a/src/packs/domains/domainCard_Death_Grip_x0FVGE1YbfXalJiw.json b/src/packs/domains/domainCard_Death_Grip_x0FVGE1YbfXalJiw.json index 437100da..26b0a2f2 100644 --- a/src/packs/domains/domainCard_Death_Grip_x0FVGE1YbfXalJiw.json +++ b/src/packs/domains/domainCard_Death_Grip_x0FVGE1YbfXalJiw.json @@ -267,7 +267,7 @@ "description": "", "tint": "#ffffff", "statuses": [ - "restrain" + "restrained" ], "sort": 0, "flags": {}, @@ -313,7 +313,7 @@ "description": "", "tint": "#ffffff", "statuses": [ - "restrain" + "restrained" ], "sort": 0, "flags": {}, @@ -359,7 +359,7 @@ "description": "", "tint": "#ffffff", "statuses": [ - "restrain" + "restrained" ], "sort": 0, "flags": {}, diff --git a/src/packs/domains/domainCard_Force_of_Nature_LzVpMkD5I4QeaIHf.json b/src/packs/domains/domainCard_Force_of_Nature_LzVpMkD5I4QeaIHf.json index b3d55ab5..1770b72d 100644 --- a/src/packs/domains/domainCard_Force_of_Nature_LzVpMkD5I4QeaIHf.json +++ b/src/packs/domains/domainCard_Force_of_Nature_LzVpMkD5I4QeaIHf.json @@ -122,6 +122,12 @@ "mode": 2, "value": "10", "priority": null + }, + { + "key": "system.rules.conditionImmunities.restrained", + "mode": 5, + "value": "1", + "priority": null } ], "disabled": false, @@ -134,7 +140,7 @@ "startRound": null, "startTurn": null }, - "description": "Tip: If your Unstoppable Die is a d4 and the 4 is currently facing up, you remove the die the next time you would increase it. However, if your Unstoppable Die has increased to a d6 and the 4 is currently facing up, you’ll turn it to 5 the next time you would increase it. In this case, you’ll remove the die after you would need to increase it higher than 6.
When you succeed on an attack or Spellcast Roll, gain a +10 bonus to the damage roll.
When you deal enough damage to defeat a creature within Close range, you absorb them and clear an Armor Slot.
You can’t be Restrained.
Before you make an action roll, you must spend a Hope. If you can’t, you revert to your normal form.
When you succeed on an attack or Spellcast Roll, gain a +10 bonus to the damage roll.
When you deal enough damage to defeat a creature within Close range, you absorb them and clear an Armor Slot.
You can’t be Restrained.
Before you make an action roll, you must spend a Hope. If you can’t, you revert to your normal form.
Restrained lasts until you’re freed with a successful Finesse or Strength roll or by dealing at least 6 damage to the vines.
", "tint": "#ffffff", "statuses": [ - "restrain" + "restrained" ], "sort": 0, "flags": {}, diff --git a/src/packs/environments/environment_Burning_Heart_of_the_Woods_oY69NN4rYxoRE4hl.json b/src/packs/environments/environment_Burning_Heart_of_the_Woods_oY69NN4rYxoRE4hl.json index 0abe95cf..a8ed164a 100644 --- a/src/packs/environments/environment_Burning_Heart_of_the_Woods_oY69NN4rYxoRE4hl.json +++ b/src/packs/environments/environment_Burning_Heart_of_the_Woods_oY69NN4rYxoRE4hl.json @@ -313,7 +313,7 @@ "description": "Restrained and Vulnerable until you break free, clearing both conditions, with a successful Finesse or Strength Roll or by dealing 10 damage to the vines. When the target makes a roll to escape, they take 1d8+4 physical damage and lose a Hope.
What painful memories do the vines bring to the surface as they pierce flesh?