From 7d1e70f66f001488e952b8133ad2e36aab538d29 Mon Sep 17 00:00:00 2001 From: Nikhil Nagarajan Date: Sat, 20 Dec 2025 13:36:06 -0500 Subject: [PATCH 01/17] [PR] [Feature] Feature form labels + SRD Update (Adversaries & Environments) (#1429) * New labels. Time to print them somewhere. * Action buttons have icons. Pretty Iconic * Features tweaked to support only on limited actors * Duplicate ActionTypes+references are removed. * Adversary and Environment SRD entries updated. * Updated name field workflow in character actor. * Adversary name fields are improved as well. * Revert "Updated name field workflow in character actor." This reverts commit 66924c530fd4c188ef0dfcfd0b841f6c7187063d. * Revert "Adversary name fields are improved as well." This reverts commit f60e8cffda9d286f80cf1403d9137c83e1a8f95b. * Fixed prototype token in Abandoned Grove * Label change --------- Co-authored-by: WBHarry --- lang/en.json | 16 +++-- module/applications/sheets/items/feature.mjs | 7 ++ module/config/itemConfig.mjs | 64 ++----------------- module/data/action/baseAction.mjs | 1 - module/data/fields/actionField.mjs | 6 ++ module/data/item/feature.mjs | 8 ++- ...ersary_Acid_Burrower_89yAh30vaNQOALlz.json | 9 ++- ...ary_Adult_Flickerfly_G7jiltRjgvVhZewm.json | 26 ++++---- ..._Apprentice_Assassin_vNIbYQ4YSzNf0WPE.json | 6 +- ...ary_Arch_Necromancer_WPEOIGfclNJxWb87.json | 15 +++-- ...versary_Archer_Guard_JRhrrEg5UroURiAD.json | 3 +- ...sary_Archer_Squadron_0ts6CGd93lLqGZI5.json | 6 +- ...ry_Assassin_Poisoner_h5RuhzGL17dW5FBT.json | 3 +- ...adversary_Battle_Box_dgH3fW9FTYLaIDvS.json | 27 +++++--- .../adversary_Bear_71qKDLKO3CsrNkdy.json | 6 +- ...versary_Bladed_Guard_B4LZcGuBAHzyVdzy.json | 3 +- ...ersary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json | 6 +- .../adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json | 6 +- ...dversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json | 6 +- .../adversary_Conscript_99TqczuQipBmaB8i.json | 3 +- .../adversary_Construct_uOP5oT9QzXPlnf3p.json | 9 ++- .../adversary_Courtesan_ZxWaWPdzFIUPNC62.json | 3 +- .../adversary_Courtier_CBBuEXAlLKFMJdjg.json | 6 +- ...adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json | 12 ++-- .../adversary_Cult_Fang_tyBOpLfigAhI9bU3.json | 3 +- ...ersary_Cult_Initiate_zx99sOGTXicP4SSD.json | 3 +- ...ry_Deeproot_Defender_9x2xY9zwc3xzbXo5.json | 6 +- ...ary_Demon_of_Avarice_pnyjIGxxvurcWmTv.json | 3 +- ...ary_Demon_of_Despair_kE4dfhqmIQpNd44e.json | 9 ++- ...sary_Demon_of_Hubris_2VN3BftageoTTIzu.json | 9 ++- ...ry_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json | 9 ++- ...rsary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json | 9 ++- ...y_Demonic_Hound_Pack_NoRZ1PqB8N5wcIw0.json | 6 +- .../adversary_Dire_Bat_tBWHW00epmMnkawe.json | 6 +- .../adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json | 3 +- .../adversary_Dryad_wR7cFKrHvRzbzhBT.json | 9 ++- ...ersary_Electric_Eels_TLzY1nDw0Bu9Ud40.json | 3 +- ...sary_Elemental_Spark_P7h54ZePFPHpYwvB.json | 3 +- ...ersary_Elite_Soldier_bfhVWMBUh61b9J6n.json | 6 +- ...ry_Failed_Experiment_ChwwVqowFw8hJQwT.json | 3 +- ...y_Fallen_Shock_Troop_OsLG2BjaEdTZUJU9.json | 3 +- ...sary_Fallen_Sorcerer_PELRry1vqjBzSAlr.json | 12 ++-- ...rlord__Realm_Breaker_hxZ0sgoFJubh5aj6.json | 12 ++-- ..._Undefeated_Champion_RXkZTwBRi4dJ3JE5.json | 15 +++-- ...ry_Giant_Beastmaster_8VZIgU12cB3cvlyH.json | 6 +- ...ersary_Giant_Brawler_YnObCleGjPT7yqEc.json | 9 ++- ...dversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json | 9 ++- ...ary_Giant_Mosquitoes_IIWV4ysJPFPnTP7W.json | 3 +- .../adversary_Giant_Rat_4PfLnaCrOcMdb4dK.json | 3 +- ...ersary_Giant_Recruit_5s8wSvpyC5rxY5aD.json | 3 +- ...rsary_Giant_Scorpion_fmfntuJ8mHRCAktP.json | 9 ++- ...dversary_Glass_Snake_8KWVLWXFhlY2kYx0.json | 6 +- .../adversary_Gorgon_8mJYMpbLTb8qIOrr.json | 9 ++- ...ater_Earth_Elemental_dsfB3YhoL5SudvS2.json | 6 +- ...ater_Water_Elemental_xIICT6tEdnA7dKDV.json | 9 ++- ...adversary_Green_Ooze_SHXedd9zZPVfUgUa.json | 6 +- ...sary_Hallowed_Archer_kabueAo6BALApWqp.json | 3 +- ...ary_Hallowed_Soldier_VENwg7xEFcYObjmT.json | 3 +- .../adversary_Harrier_uRtghKE9mHlII4rs.json | 3 +- ...adversary_Head_Guard_mK3A5FTx6k8iPU3F.json | 9 ++- ...versary_Head_Vampire_i2UNbRvgyoSs07M6.json | 9 ++- ...dversary_High_Seraph_r1mbfSSwKWdcFdAU.json | 9 ++- ...sary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json | 6 +- .../adversary_Hydra_MI126iMOOobQ1Obn.json | 9 ++- ...y_Jagged_Knife_Hexer_MbBPIOxaxXYNApXz.json | 6 +- ...ed_Knife_Kneebreaker_CBKixLH3yhivZZuL.json | 3 +- ..._Jagged_Knife_Lackey_C0OMQqV7pN6t7ouR.json | 3 +- ...ged_Knife_Lieutenant_aTljstqteGoLpCBq.json | 12 ++-- ..._Jagged_Knife_Shadow_XF4tYTq9nPJAy2ox.json | 3 +- ..._Juvenile_Flickerfly_MYXmTx2FHcIjdfYZ.json | 6 +- ..._Knight_of_the_Realm_7ai2opemrclQe3VF.json | 6 +- .../adversary_Kraken_4nqv3ZwJGjnmic8j.json | 9 ++- ...versary_Masked_Thief_niBpVU7yeo5ccskE.json | 6 +- ...sary_Master_Assassin_dNta0cUzr96xcFhf.json | 9 ++- ...rsary_Merchant_Baron_Vy02IhGhkJLuezu4.json | 6 +- ...inor_Chaos_Elemental_sRn4bqerfARvhgSV.json | 12 ++-- ...dversary_Minor_Demon_3tqCjDwJAQ7JKqMb.json | 9 ++- ...Minor_Fire_Elemental_DscWkNVoHak6P4hh.json | 12 ++-- ...versary_Minor_Treant_G62k4oSkhkoXEs2D.json | 3 +- ...ary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json | 6 +- .../adversary_Monarch_yx0vK2yfNVZKWUUi.json | 9 ++- ...ersary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json | 9 ++- ...adversary_Oak_Treant_XK78QUfY8c8Go8Uv.json | 6 +- ...rsary_Oracle_of_Doom_befIqd5IYKg6eUz2.json | 12 ++-- ...r_Realms_Abomination_A0SeeDzwjvqOsyof.json | 6 +- ...ter_Realms_Corrupter_ms6nuOl3NFkhPj1k.json | 3 +- ..._Outer_Realms_Thrall_moJhHgKqTKPS2WYS.json | 3 +- ...atchwork_Zombie_Hulk_EQTOAOUrkIvS2z88.json | 6 +- ...ary_Perfected_Zombie_CP6iRfHdyFWniTHY.json | 6 +- ...dversary_Petty_Noble_wycLpvebWdUqRhpP.json | 6 +- ...rsary_Pirate_Captain_OROJbjsqagVh7ECV.json | 9 ++- ...versary_Pirate_Tough_mhcVkVFrzIJ18FDm.json | 3 +- .../adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json | 6 +- ...ersary_Rotted_Zombie_gP3fWTLzSFnpA8EJ.json | 3 +- ...ersary_Royal_Advisor_EtLJiTsilPPZvLUX.json | 6 +- ...ersary_Secret_Keeper_sLAccjvCWfeedbpI.json | 12 ++-- .../adversary_Sellsword_bgreCaQ6ap2DVpCr.json | 3 +- .../adversary_Shark_YmVAkdNsyuXWTtYp.json | 3 +- .../adversary_Siren_BK4jwyXSRx7IOQiO.json | 3 +- ...sary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json | 3 +- ...sary_Skeleton_Dredge_6l1a3Fazq8BoKIcc.json | 3 +- ...sary_Skeleton_Knight_Q9LaVTyXF9NF12C7.json | 6 +- ...ary_Skeleton_Warrior_10YIQl0lvCJXZLfX.json | 3 +- ...sary_Spectral_Archer_5tCkhnBByUIN5UdG.json | 3 +- ...ary_Spectral_Captain_65cSO3EQEh6ZH6Xk.json | 9 ++- ...ry_Spectral_Guardian_UFVGl1osOsJTneLf.json | 3 +- ...adversary_Spellblade_ldbWEL7uZs84vyrR.json | 9 ++- .../adversary_Spy_8zlynOhnVA59KpKT.json | 6 +- ...dversary_Stag_Knight_KGVwnLq85ywP9xvB.json | 6 +- ...dversary_Stonewraith_3aAS2Qm3R6cgaYfE.json | 9 ++- ...rsary_Sylvan_Soldier_VtFBt9XBE0WrGGxP.json | 6 +- ...Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json | 6 +- ...rsary_Tangle_Bramble_XcAGOSmtCFLT1unN.json | 6 +- ...ersary_Tiny_Red_Ooze_1fkLQXVtmILqfJ44.json | 3 +- ...rsary_Treant_Sapling_o63nS0k3wHu6EgKP.json | 3 +- .../adversary_Vampire_WWyUp6Mxl1S3KYUG.json | 6 +- ...ault_Guardian_Gaoler_JqYraOqNmmhHk4Yy.json | 3 +- ...lt_Guardian_Sentinel_FVgYb28fhxlVcGwA.json | 9 ++- ...ault_Guardian_Turret_c5hGdvY5UnSjlHws.json | 9 ++- ...Dragon__Ashen_Tyrant_pMuXGCSOQaxpi5tb.json | 9 ++- ...agon__Molten_Scourge_eArAPuB38CNR0ZIM.json | 15 +++-- ...n__Obsidian_Predator_ladm7wykhZczYzrQ.json | 9 ++- ...adversary_War_Wizard_noDdT0tsN6FXSmC8.json | 14 ++-- ...versary_Weaponmaster_ZNbQ2jg35LG4t9eH.json | 9 ++- ...dversary_Young_Dryad_8yUj2Mzvnifhxegm.json | 9 ++- ...ary_Young_Ice_Dragon_UGPiPLJsPvMTSKEF.json | 12 ++-- ...ersary_Zombie_Legion_YhJrP7rTBiRdX5Fp.json | 3 +- ...dversary_Zombie_Pack_Nf0v43rtflV56V2T.json | 3 +- ...ment_Abandoned_Grove_pGEdzdLkqYtBhxnG.json | 17 +++-- ...environment_Ambushed_uGEdNYERCTJBEjc5.json | 3 +- ...nvironment_Ambushers_uXZpebPR77YQ1oXI.json | 3 +- ...g_Heart_of_the_Woods_oY69NN4rYxoRE4hl.json | 9 ++- ...Bustling_Marketplace_HZKA7hkej7JJY503.json | 9 ++- ...ronment_Castle_Siege_1eZ32Esq7rfZOjlu.json | 9 ++- ...ironment_Chaos_Realm_2Z1mKc65LxNk2PqR.json | 12 ++-- ...ent_Cliffside_Ascent_LPpfdlNKqiZIl04w.json | 3 +- ...ironment_Cult_Ritual_QAXXiOKBDmCTauHD.json | 9 ++- ...nt_Divine_Usurpation_4DLYez7VbMCFDAuZ.json | 12 ++-- ...ment_Hallowed_Temple_dsA6j69AnaJhUyqH.json | 8 ++- ...ronment_Haunted_City_OzYbizKraK92FDiI.json | 6 +- ...nment_Imperial_Court_jr1xAoXzVwVblzxI.json | 9 ++- ...ronment_Local_Tavern_cM4X81DOyvxNIi52.json | 11 ++-- ...onment_Mountain_Pass_acMu9wJrMZZzLSTJ.json | 9 ++- ...ecromancer_s_Ossuary_h3KyRL7AshhLAmcH.json | 9 ++- ...ronment_Outpost_Town_YezryR32uo39xRxW.json | 6 +- ...nment_Pitched_Battle_EWD3ZsLoK6VMVOf7.json | 9 ++- ...ronment_Raging_River_t4cdqTfzcqP3H1vJ.json | 6 +- .../sheets-settings/action-settings/base.hbs | 1 - .../global/partials/inventory-item-V2.hbs | 15 +++++ .../sheets/global/partials/inventory-item.hbs | 15 +++++ templates/sheets/items/feature/header.hbs | 2 +- templates/sheets/items/feature/settings.hbs | 7 ++ 152 files changed, 731 insertions(+), 405 deletions(-) diff --git a/lang/en.json b/lang/en.json index 32717fcb..8a3481c8 100755 --- a/lang/en.json +++ b/lang/en.json @@ -620,11 +620,6 @@ } }, "CONFIG": { - "ActionType": { - "passive": "Passive", - "action": "Action", - "reaction": "Reaction" - }, "AdversaryTrait": { "relentless": { "name": "Relentless", @@ -1033,6 +1028,12 @@ "description": "" } }, + "FeatureForm": { + "label": "Feature Form", + "passive": "Passive", + "action": "Action", + "reaction": "Reaction" + }, "Gold": { "title": "Gold", "coins": "Coins", @@ -2094,6 +2095,7 @@ "fear": "Fear", "features": "Features", "formula": "Formula", + "general": "General", "gm": "GM", "healing": "Healing", "healingRoll": "Healing Roll", @@ -2527,8 +2529,8 @@ "enabled": { "label": "Enabled" }, "tokens": { "label": "Tokens" } }, - "massiveDamage":{ - "title":"Massive Damage", + "massiveDamage": { + "title": "Massive Damage", "enabled": { "label": "Enabled" } } } diff --git a/module/applications/sheets/items/feature.mjs b/module/applications/sheets/items/feature.mjs index 1575067b..6ff98ca7 100644 --- a/module/applications/sheets/items/feature.mjs +++ b/module/applications/sheets/items/feature.mjs @@ -31,4 +31,11 @@ export default class FeatureSheet extends DHBaseItemSheet { labelPrefix: 'DAGGERHEART.GENERAL.Tabs' } }; +//Might be wrong location but testing out if here is okay. + /**@override */ + async _prepareContext(options) { + const context = await super._prepareContext(options); + context.featureFormChoices = CONFIG.DH.ITEM.featureForm; + return context; + } } diff --git a/module/config/itemConfig.mjs b/module/config/itemConfig.mjs index a9ad1d68..02914143 100644 --- a/module/config/itemConfig.mjs +++ b/module/config/itemConfig.mjs @@ -5,7 +5,6 @@ export const armorFeatures = { actions: [ { type: 'damage', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.ArmorFeature.burning.actions.burn.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.burning.actions.burn.description', @@ -174,7 +173,6 @@ export const armorFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.actions.hope.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.actions.hope.description', @@ -188,7 +186,6 @@ export const armorFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.actions.impenetrable.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.actions.impenetrable.description', @@ -231,7 +228,6 @@ export const armorFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.ArmorFeature.painful.actions.pain.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.painful.actions.pain.description', @@ -269,7 +265,6 @@ export const armorFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.ArmorFeature.quiet.actions.quiet.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.quiet.actions.quiet.description', @@ -306,7 +301,6 @@ export const armorFeatures = { actions: [ { type: 'attack', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.ArmorFeature.resilient.actions.resilient.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.resilient.actions.resilient.description', @@ -353,7 +347,6 @@ export const armorFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.ArmorFeature.shifting.actions.shift.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.shifting.actions.shift.description', @@ -373,7 +366,6 @@ export const armorFeatures = { actions: [ { type: 'attack', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.ArmorFeature.timeslowing.actions.slowTime.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.timeslowing.actions.slowTime.description', @@ -401,7 +393,6 @@ export const armorFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.ArmorFeature.truthseeking.actions.truthseeking.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.truthseeking.actions.truthseeking.description', @@ -537,7 +528,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.actions.bounce.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.actions.bounce.description', @@ -582,7 +572,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.actions.addDamage.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.actions.addDamage.description', @@ -596,7 +585,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.burning.actions.burn.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.burning.actions.burn.description', @@ -610,7 +598,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.charged.actions.markStress.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.charged.actions.markStress.description', @@ -647,7 +634,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.actions.attack.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.actions.attack.description', @@ -688,7 +674,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.actions.extraDamage.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.actions.extraDamage.description', @@ -702,7 +687,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.actions.deflect.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.actions.deflect.description', @@ -739,7 +723,6 @@ export const weaponFeatures = { actions: [ { type: 'damage', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.actions.attack.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.actions.attack.descriptive', @@ -784,7 +767,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.actions.devastate.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.actions.devastate.description', @@ -835,7 +817,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.actions.doubleUp.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.actions.doubleUp.description', @@ -849,7 +830,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.actions.duel.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.actions.duel.description', @@ -863,7 +843,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', // Should prompt a dc 14 reaction save on adversaries - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.actions.erupt.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.actions.erupt.description', @@ -877,7 +856,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.actions.grapple.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.actions.grapple.description', @@ -897,7 +875,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.description', @@ -929,7 +906,6 @@ export const weaponFeatures = { actions: [ { type: 'healing', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.healing.actions.heal.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.healing.actions.heal.description', @@ -977,7 +953,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.actions.hook.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.actions.hook.description', @@ -991,7 +966,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.hot.actions.hot.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.hot.actions.hot.description', @@ -1005,7 +979,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.actions.invigorate.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.actions.invigorate.description', @@ -1019,7 +992,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.actions.lifesteal.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.actions.lifesteal.description', @@ -1033,7 +1005,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.actions.lockOn.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.actions.lockOn.description', @@ -1047,7 +1018,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.long.actions.long.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.long.actions.long.description', @@ -1061,7 +1031,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.actions.luck.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.actions.luck.description', @@ -1099,7 +1068,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.painful.actions.pain.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.painful.actions.pain.description', @@ -1145,7 +1113,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.parry.actions.parry.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.parry.actions.parry.description', @@ -1159,7 +1126,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.actions.persuade.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.actions.persuade.description', @@ -1196,7 +1162,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.pompous.actions.pompous.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.pompous.actions.pompous.description', @@ -1240,7 +1205,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.quick.actions.quick.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.quick.actions.quick.description', @@ -1278,7 +1242,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.actions.reload.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.actions.reload.description', @@ -1292,7 +1255,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.retractable.actions.retract.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.retractable.actions.retract.description', @@ -1306,7 +1268,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.returning.actions.return.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.returning.actions.return.description', @@ -1320,7 +1281,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.scary.actions.scare.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.scary.actions.scare.description', @@ -1376,7 +1336,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.actions.shelter.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.actions.shelter.description', @@ -1390,7 +1349,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.startling.actions.startle.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.startling.actions.startle.description', @@ -1410,7 +1368,6 @@ export const weaponFeatures = { actions: [ { type: 'effect', - actionType: 'action', chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.timebending.actions.bendTime.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.timebending.actions.bendTime.description', @@ -1458,6 +1415,12 @@ export const orderedWeaponFeatures = () => { return Object.values(all).sort((a, b) => game.i18n.localize(a.label).localeCompare(game.i18n.localize(b.label))); }; +export const featureForm = { + passive: "DAGGERHEART.CONFIG.FeatureForm.passive", + action: "DAGGERHEART.CONFIG.FeatureForm.action", + reaction: "DAGGERHEART.CONFIG.FeatureForm.reaction" +}; + export const featureTypes = { ancestry: { id: 'ancestry', @@ -1515,21 +1478,6 @@ export const featureSubTypes = { mastery: 'mastery' }; -export const actionTypes = { - passive: { - id: 'passive', - label: 'DAGGERHEART.CONFIG.ActionType.passive' - }, - action: { - id: 'action', - label: 'DAGGERHEART.CONFIG.ActionType.action' - }, - reaction: { - id: 'reaction', - label: 'DAGGERHEART.CONFIG.ActionType.reaction' - } -}; - export const itemResourceTypes = { simple: { id: 'simple', diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index ae085064..b15d6c4e 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -324,7 +324,6 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel _getTags() { const tags = [ game.i18n.localize(`DAGGERHEART.ACTIONS.TYPES.${this.type}.name`), - game.i18n.localize(`DAGGERHEART.CONFIG.ActionType.${this.actionType}`) ]; return tags; diff --git a/module/data/fields/actionField.mjs b/module/data/fields/actionField.mjs index 8661f500..2d968fe0 100644 --- a/module/data/fields/actionField.mjs +++ b/module/data/fields/actionField.mjs @@ -141,6 +141,12 @@ export function ActionMixin(Base) { return this.documentName; } + //Getter for icons + get typeIcon() { + const config = CONFIG.DH.ACTIONS.actionTypes[this.type]; + return config?.icon || 'fa-question'; // Fallback icon just in case + } + get relativeUUID() { return `.Item.${this.item.id}.Action.${this.id}`; } diff --git a/module/data/item/feature.mjs b/module/data/item/feature.mjs index 3b8fe064..cb01b1fb 100644 --- a/module/data/item/feature.mjs +++ b/module/data/item/feature.mjs @@ -30,7 +30,13 @@ export default class DHFeature extends BaseDataItem { initial: null }), multiclassOrigin: new fields.BooleanField({ initial: false }), - identifier: new fields.StringField() + identifier: new fields.StringField(), + featureForm: new fields.StringField({ + required: true, + initial: 'passive', + choices: CONFIG.DH.ITEM.featureForm, + label: 'DAGGERHEART.CONFIG.FeatureForm.label' + }) }; } } diff --git a/src/packs/adversaries/adversary_Acid_Burrower_89yAh30vaNQOALlz.json b/src/packs/adversaries/adversary_Acid_Burrower_89yAh30vaNQOALlz.json index 8060ab72..1d4cf11a 100644 --- a/src/packs/adversaries/adversary_Acid_Burrower_89yAh30vaNQOALlz.json +++ b/src/packs/adversaries/adversary_Acid_Burrower_89yAh30vaNQOALlz.json @@ -381,7 +381,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { @@ -546,7 +547,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -681,7 +683,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Adult_Flickerfly_G7jiltRjgvVhZewm.json b/src/packs/adversaries/adversary_Adult_Flickerfly_G7jiltRjgvVhZewm.json index 0e3a89c6..3d1404a7 100644 --- a/src/packs/adversaries/adversary_Adult_Flickerfly_G7jiltRjgvVhZewm.json +++ b/src/packs/adversaries/adversary_Adult_Flickerfly_G7jiltRjgvVhZewm.json @@ -263,7 +263,7 @@ "img": "icons/magic/unholy/silhouette-evil-horned-giant.webp", "effects": [], "folder": null, - "sort": 0, + "sort": 100000, "ownership": { "default": 0, "MQSznptE5yLT7kj8": 3 @@ -360,7 +360,7 @@ } ], "folder": null, - "sort": 0, + "sort": 200000, "ownership": { "default": 0, "MQSznptE5yLT7kj8": 3 @@ -461,13 +461,14 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "BuL6ndgaiJtjaM2T", "img": "icons/skills/melee/strike-slashes-orange.webp", "effects": [], "folder": null, - "sort": 0, + "sort": 300000, "ownership": { "default": 0, "MQSznptE5yLT7kj8": 3 @@ -540,13 +541,14 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "bOTsfXr9yNIGkIzK", "img": "icons/magic/light/explosion-glow-spiral-yellow.webp", "effects": [], "folder": null, - "sort": 0, + "sort": 400000, "ownership": { "default": 0, "MQSznptE5yLT7kj8": 3 @@ -701,13 +703,14 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "49cIxZRFiAM6jDva", "img": "icons/magic/air/fog-gas-smoke-purple.webp", "effects": [], "folder": null, - "sort": 0, + "sort": 500000, "ownership": { "default": 0, "MQSznptE5yLT7kj8": 3 @@ -756,13 +759,14 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "KLdLRKoJHBJlHwYe", "img": "icons/skills/movement/arrow-upward-yellow.webp", "effects": [], "folder": null, - "sort": 0, + "sort": 600000, "ownership": { "default": 0, "MQSznptE5yLT7kj8": 3 @@ -787,7 +791,7 @@ "img": "icons/skills/movement/feet-winged-boots-blue.webp", "effects": [], "folder": null, - "sort": 0, + "sort": 700000, "ownership": { "default": 0, "fBcTgyTzoARBvohY": 3 diff --git a/src/packs/adversaries/adversary_Apprentice_Assassin_vNIbYQ4YSzNf0WPE.json b/src/packs/adversaries/adversary_Apprentice_Assassin_vNIbYQ4YSzNf0WPE.json index 0fd791e0..fbf53d80 100644 --- a/src/packs/adversaries/adversary_Apprentice_Assassin_vNIbYQ4YSzNf0WPE.json +++ b/src/packs/adversaries/adversary_Apprentice_Assassin_vNIbYQ4YSzNf0WPE.json @@ -223,7 +223,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "passive" }, "_id": "2yREz60uPY80tAa4", "img": "icons/magic/symbols/runes-carved-stone-yellow.webp", @@ -278,7 +279,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "4wT7CmM1DJEPcraF", "img": "icons/creatures/abilities/tail-strike-bone-orange.webp", diff --git a/src/packs/adversaries/adversary_Arch_Necromancer_WPEOIGfclNJxWb87.json b/src/packs/adversaries/adversary_Arch_Necromancer_WPEOIGfclNJxWb87.json index cbba184b..2962b84c 100644 --- a/src/packs/adversaries/adversary_Arch_Necromancer_WPEOIGfclNJxWb87.json +++ b/src/packs/adversaries/adversary_Arch_Necromancer_WPEOIGfclNJxWb87.json @@ -289,7 +289,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "jNmMyq5QI2HNgffy", "img": "icons/magic/death/skull-weapon-staff-glow-pink.webp", @@ -467,7 +468,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "4EECsXzHFG0RoIg0", "img": "icons/magic/unholy/projectile-missile-green.webp", @@ -561,7 +563,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "XxXOrFovbCz9zFxR", "img": "icons/magic/death/undead-zombie-grave-green.webp", @@ -640,7 +643,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "k4MSykLRoW3qp7Lk", "img": "icons/magic/death/skull-horned-worn-fire-blue.webp", @@ -756,7 +760,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "FKcuCo0v2U7fVkqq", "img": "icons/magic/unholy/hand-claw-fire-green.webp", diff --git a/src/packs/adversaries/adversary_Archer_Guard_JRhrrEg5UroURiAD.json b/src/packs/adversaries/adversary_Archer_Guard_JRhrrEg5UroURiAD.json index f4520545..bfdee207 100644 --- a/src/packs/adversaries/adversary_Archer_Guard_JRhrrEg5UroURiAD.json +++ b/src/packs/adversaries/adversary_Archer_Guard_JRhrrEg5UroURiAD.json @@ -311,7 +311,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { diff --git a/src/packs/adversaries/adversary_Archer_Squadron_0ts6CGd93lLqGZI5.json b/src/packs/adversaries/adversary_Archer_Squadron_0ts6CGd93lLqGZI5.json index 00b2462a..88d63721 100644 --- a/src/packs/adversaries/adversary_Archer_Squadron_0ts6CGd93lLqGZI5.json +++ b/src/packs/adversaries/adversary_Archer_Squadron_0ts6CGd93lLqGZI5.json @@ -328,7 +328,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "Wuf5y9tJ88BwzLv2", "img": "icons/skills/ranged/arrows-flying-triple-brown.webp", @@ -425,7 +426,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "ayGHTtyjSuIR4BrV", "img": "icons/skills/ranged/arrows-flying-salvo-blue.webp", diff --git a/src/packs/adversaries/adversary_Assassin_Poisoner_h5RuhzGL17dW5FBT.json b/src/packs/adversaries/adversary_Assassin_Poisoner_h5RuhzGL17dW5FBT.json index e887b4ba..b962fe78 100644 --- a/src/packs/adversaries/adversary_Assassin_Poisoner_h5RuhzGL17dW5FBT.json +++ b/src/packs/adversaries/adversary_Assassin_Poisoner_h5RuhzGL17dW5FBT.json @@ -419,7 +419,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "lAmiK8wVxjyHwKlp", "img": "icons/magic/air/fog-gas-smoke-green.webp", diff --git a/src/packs/adversaries/adversary_Battle_Box_dgH3fW9FTYLaIDvS.json b/src/packs/adversaries/adversary_Battle_Box_dgH3fW9FTYLaIDvS.json index 49982ae2..b172b646 100644 --- a/src/packs/adversaries/adversary_Battle_Box_dgH3fW9FTYLaIDvS.json +++ b/src/packs/adversaries/adversary_Battle_Box_dgH3fW9FTYLaIDvS.json @@ -342,7 +342,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "ZqfLMjVkbUwDw4p6", "img": "icons/commodities/tech/transmission.webp", @@ -441,7 +442,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "lqyN4CQop53BzarW", "img": "icons/magic/light/beam-rays-blue.webp", @@ -540,7 +542,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "IHQoqt39T772FVMs", "img": "icons/magic/fire/explosion-embers-orange.webp", @@ -644,7 +647,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "XtnByqUr9AuYU9Ip", "img": "icons/skills/movement/arrow-upward-yellow.webp", @@ -781,7 +785,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "3bPURmuwQs06fThQ", "img": "icons/magic/lightning/bolt-strike-embers-teal.webp", @@ -858,7 +863,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "ijIaKjroxq3xZd9Z", "img": "icons/magic/sonic/explosion-impact-shock-wave.webp", @@ -996,7 +1002,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "JCue4ko61bjhedXv", "img": "icons/creatures/invertebrates/wasp-swarm-tan.webp", @@ -1096,7 +1103,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "ITzpRJr2jWK0Ksmp", "img": "icons/creatures/magical/construct-golem-stone-blue.webp", @@ -1195,7 +1203,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "YvfzPyJbbv2ia6Yp", "img": "icons/magic/sonic/explosion-shock-wave-teal.webp", diff --git a/src/packs/adversaries/adversary_Bear_71qKDLKO3CsrNkdy.json b/src/packs/adversaries/adversary_Bear_71qKDLKO3CsrNkdy.json index e902ac32..f804c06e 100644 --- a/src/packs/adversaries/adversary_Bear_71qKDLKO3CsrNkdy.json +++ b/src/packs/adversaries/adversary_Bear_71qKDLKO3CsrNkdy.json @@ -350,7 +350,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { @@ -485,7 +486,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Bladed_Guard_B4LZcGuBAHzyVdzy.json b/src/packs/adversaries/adversary_Bladed_Guard_B4LZcGuBAHzyVdzy.json index 24194f3d..ecc547f8 100644 --- a/src/packs/adversaries/adversary_Bladed_Guard_B4LZcGuBAHzyVdzy.json +++ b/src/packs/adversaries/adversary_Bladed_Guard_B4LZcGuBAHzyVdzy.json @@ -358,7 +358,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { diff --git a/src/packs/adversaries/adversary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json b/src/packs/adversaries/adversary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json index cf6583e4..96e00139 100644 --- a/src/packs/adversaries/adversary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json +++ b/src/packs/adversaries/adversary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json @@ -342,7 +342,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -433,7 +434,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [ { diff --git a/src/packs/adversaries/adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json b/src/packs/adversaries/adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json index fd73ee36..91ba0045 100644 --- a/src/packs/adversaries/adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json +++ b/src/packs/adversaries/adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json @@ -467,7 +467,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -548,7 +549,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json b/src/packs/adversaries/adversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json index a9686bf0..cf2be503 100644 --- a/src/packs/adversaries/adversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json +++ b/src/packs/adversaries/adversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json @@ -443,7 +443,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "Zn25zBr96y1hrmnr", "img": "icons/magic/lightning/bolt-strike-purple.webp", @@ -540,7 +541,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "urXRi4bdBfvl8U6K", "img": "icons/magic/control/sihouette-hold-beam-green.webp", diff --git a/src/packs/adversaries/adversary_Conscript_99TqczuQipBmaB8i.json b/src/packs/adversaries/adversary_Conscript_99TqczuQipBmaB8i.json index bf302c3f..d79aed6c 100644 --- a/src/packs/adversaries/adversary_Conscript_99TqczuQipBmaB8i.json +++ b/src/packs/adversaries/adversary_Conscript_99TqczuQipBmaB8i.json @@ -272,7 +272,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "MWfKUGzT1YBmLvpn", "img": "icons/creatures/abilities/tail-strike-bone-orange.webp", diff --git a/src/packs/adversaries/adversary_Construct_uOP5oT9QzXPlnf3p.json b/src/packs/adversaries/adversary_Construct_uOP5oT9QzXPlnf3p.json index b8d8cfa0..964b1354 100644 --- a/src/packs/adversaries/adversary_Construct_uOP5oT9QzXPlnf3p.json +++ b/src/packs/adversaries/adversary_Construct_uOP5oT9QzXPlnf3p.json @@ -393,7 +393,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -449,7 +450,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [ { @@ -593,7 +595,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Courtesan_ZxWaWPdzFIUPNC62.json b/src/packs/adversaries/adversary_Courtesan_ZxWaWPdzFIUPNC62.json index f6b94677..571d8cf1 100644 --- a/src/packs/adversaries/adversary_Courtesan_ZxWaWPdzFIUPNC62.json +++ b/src/packs/adversaries/adversary_Courtesan_ZxWaWPdzFIUPNC62.json @@ -300,7 +300,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "rSMUPC5GhR982ifg", "img": "icons/magic/perception/eye-slit-orange.webp", diff --git a/src/packs/adversaries/adversary_Courtier_CBBuEXAlLKFMJdjg.json b/src/packs/adversaries/adversary_Courtier_CBBuEXAlLKFMJdjg.json index 28222226..c22a8130 100644 --- a/src/packs/adversaries/adversary_Courtier_CBBuEXAlLKFMJdjg.json +++ b/src/packs/adversaries/adversary_Courtier_CBBuEXAlLKFMJdjg.json @@ -318,7 +318,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { @@ -413,7 +414,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json b/src/packs/adversaries/adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json index 7c90a78b..8e4f477e 100644 --- a/src/packs/adversaries/adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json +++ b/src/packs/adversaries/adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json @@ -341,7 +341,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "kCffzM8rX8NEr9d2", "img": "icons/magic/unholy/beam-ringed-impact-purple.webp", @@ -401,7 +402,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "IHWDn097sRgjlZXO", "img": "icons/magic/unholy/orb-contained-pink.webp", @@ -511,7 +513,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "JpSrduK3vjd9h098", "img": "icons/magic/air/fog-gas-smoke-dense-pink.webp", @@ -643,7 +646,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "x6FbcrfOscb3er6P", "img": "icons/magic/unholy/silhouette-robe-evil-glow.webp", diff --git a/src/packs/adversaries/adversary_Cult_Fang_tyBOpLfigAhI9bU3.json b/src/packs/adversaries/adversary_Cult_Fang_tyBOpLfigAhI9bU3.json index 76a338d2..5b167356 100644 --- a/src/packs/adversaries/adversary_Cult_Fang_tyBOpLfigAhI9bU3.json +++ b/src/packs/adversaries/adversary_Cult_Fang_tyBOpLfigAhI9bU3.json @@ -364,7 +364,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "ohASSruBxcvuItIK", "img": "icons/magic/unholy/barrier-fire-pink.webp", diff --git a/src/packs/adversaries/adversary_Cult_Initiate_zx99sOGTXicP4SSD.json b/src/packs/adversaries/adversary_Cult_Initiate_zx99sOGTXicP4SSD.json index f748df8b..0aa5c326 100644 --- a/src/packs/adversaries/adversary_Cult_Initiate_zx99sOGTXicP4SSD.json +++ b/src/packs/adversaries/adversary_Cult_Initiate_zx99sOGTXicP4SSD.json @@ -272,7 +272,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "WP6xQtYzouPEFr82", "img": "icons/creatures/abilities/tail-strike-bone-orange.webp", diff --git a/src/packs/adversaries/adversary_Deeproot_Defender_9x2xY9zwc3xzbXo5.json b/src/packs/adversaries/adversary_Deeproot_Defender_9x2xY9zwc3xzbXo5.json index eea41180..19d0fd4d 100644 --- a/src/packs/adversaries/adversary_Deeproot_Defender_9x2xY9zwc3xzbXo5.json +++ b/src/packs/adversaries/adversary_Deeproot_Defender_9x2xY9zwc3xzbXo5.json @@ -285,7 +285,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -388,7 +389,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { diff --git a/src/packs/adversaries/adversary_Demon_of_Avarice_pnyjIGxxvurcWmTv.json b/src/packs/adversaries/adversary_Demon_of_Avarice_pnyjIGxxvurcWmTv.json index 3c76628d..fa925b38 100644 --- a/src/packs/adversaries/adversary_Demon_of_Avarice_pnyjIGxxvurcWmTv.json +++ b/src/packs/adversaries/adversary_Demon_of_Avarice_pnyjIGxxvurcWmTv.json @@ -329,7 +329,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "BKgv2D1IdI813R8k", "img": "icons/skills/movement/arrows-up-trio-red.webp", diff --git a/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json b/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json index 3ae3639d..cc792029 100644 --- a/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json +++ b/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json @@ -290,7 +290,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "FC8PIf4BVkhmoJX8", "img": "icons/magic/death/skull-flames-white-blue.webp", @@ -412,7 +413,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "dlMdfUjy2GaqgeOJ", "img": "icons/creatures/unholy/demon-fire-horned-mask.webp", @@ -507,7 +509,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "7qjx1c4C1fUfvXnu", "img": "icons/skills/melee/strike-weapons-orange.webp", diff --git a/src/packs/adversaries/adversary_Demon_of_Hubris_2VN3BftageoTTIzu.json b/src/packs/adversaries/adversary_Demon_of_Hubris_2VN3BftageoTTIzu.json index b425ec66..04f6a778 100644 --- a/src/packs/adversaries/adversary_Demon_of_Hubris_2VN3BftageoTTIzu.json +++ b/src/packs/adversaries/adversary_Demon_of_Hubris_2VN3BftageoTTIzu.json @@ -454,7 +454,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "Y3W44ifKIcoYpONN", "img": "icons/skills/melee/spear-tips-quintuple-orange.webp", @@ -509,7 +510,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "6BKWOTuxQWJd5RP5", "img": "icons/creatures/unholy/demon-fire-horned-winged-roar.webp", @@ -587,7 +589,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "FLp1dPSJz1ezY0gD", "img": "icons/magic/control/fear-fright-shadow-monster-red.webp", diff --git a/src/packs/adversaries/adversary_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json b/src/packs/adversaries/adversary_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json index 7ea12036..e79eef29 100644 --- a/src/packs/adversaries/adversary_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json +++ b/src/packs/adversaries/adversary_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json @@ -256,7 +256,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "KVyhgMJSSHTwRISA", "img": "icons/magic/control/fear-fright-monster-grin-purple-blue.webp", @@ -311,7 +312,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "pSAupMWw1eYqm84z", "img": "icons/magic/perception/eye-ringed-glow-angry-small-teal.webp", @@ -383,7 +385,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "589tCxFc8KZ3rdzP", "img": "icons/magic/perception/hand-eye-black.webp", diff --git a/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json b/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json index 72ec986d..cfe301f5 100644 --- a/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json +++ b/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json @@ -286,7 +286,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "a33PW8UkziliowlR", "img": "icons/skills/melee/maneuver-greatsword-yellow.webp", @@ -393,7 +394,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "DjGydqLXT4rDa7Av", "img": "icons/skills/melee/blood-slash-foam-red.webp", @@ -482,7 +484,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "2F75BO0xEU8Zlj7T", "img": "icons/creatures/unholy/demon-fire-horned-clawed.webp", diff --git a/src/packs/adversaries/adversary_Demonic_Hound_Pack_NoRZ1PqB8N5wcIw0.json b/src/packs/adversaries/adversary_Demonic_Hound_Pack_NoRZ1PqB8N5wcIw0.json index b7ac7cb5..d407949e 100644 --- a/src/packs/adversaries/adversary_Demonic_Hound_Pack_NoRZ1PqB8N5wcIw0.json +++ b/src/packs/adversaries/adversary_Demonic_Hound_Pack_NoRZ1PqB8N5wcIw0.json @@ -308,7 +308,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "WEbHwamS5ZBphiKq", "img": "icons/creatures/unholy/demons-horned-glowing-pink.webp", @@ -403,7 +404,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "3mOBJE5c3cP2cGP1", "img": "icons/skills/melee/strike-weapons-orange.webp", diff --git a/src/packs/adversaries/adversary_Dire_Bat_tBWHW00epmMnkawe.json b/src/packs/adversaries/adversary_Dire_Bat_tBWHW00epmMnkawe.json index 38bba1d3..9c367879 100644 --- a/src/packs/adversaries/adversary_Dire_Bat_tBWHW00epmMnkawe.json +++ b/src/packs/adversaries/adversary_Dire_Bat_tBWHW00epmMnkawe.json @@ -350,7 +350,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "o69lipskvBwGVhe4", "img": "icons/magic/sonic/projectile-sound-rings-wave.webp", @@ -456,7 +457,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "BQPGgbNzKbNkGDJb", "img": "icons/skills/melee/strike-slashes-red.webp", diff --git a/src/packs/adversaries/adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json b/src/packs/adversaries/adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json index a900aa7b..f40c2310 100644 --- a/src/packs/adversaries/adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json +++ b/src/packs/adversaries/adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json @@ -417,7 +417,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { diff --git a/src/packs/adversaries/adversary_Dryad_wR7cFKrHvRzbzhBT.json b/src/packs/adversaries/adversary_Dryad_wR7cFKrHvRzbzhBT.json index 845e447a..0bd8939e 100644 --- a/src/packs/adversaries/adversary_Dryad_wR7cFKrHvRzbzhBT.json +++ b/src/packs/adversaries/adversary_Dryad_wR7cFKrHvRzbzhBT.json @@ -337,7 +337,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "i9HbArl09dX2BvzY", "img": "icons/magic/nature/root-vines-grow-brown.webp", @@ -392,7 +393,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "yKWQLL3qsEZlQjyb", "img": "icons/magic/nature/tree-animated-stump-mushrooms-teal.webp", @@ -517,7 +519,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "z4JbqiHuxrWy6Cpu", "img": "icons/magic/nature/vines-thorned-curled-glow-teal-purple.webp", diff --git a/src/packs/adversaries/adversary_Electric_Eels_TLzY1nDw0Bu9Ud40.json b/src/packs/adversaries/adversary_Electric_Eels_TLzY1nDw0Bu9Ud40.json index 6d25a124..0354d820 100644 --- a/src/packs/adversaries/adversary_Electric_Eels_TLzY1nDw0Bu9Ud40.json +++ b/src/packs/adversaries/adversary_Electric_Eels_TLzY1nDw0Bu9Ud40.json @@ -330,7 +330,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "u5NL1eUJeAkIEpgt", "img": "icons/magic/lightning/bolt-strike-sparks-teal.webp", diff --git a/src/packs/adversaries/adversary_Elemental_Spark_P7h54ZePFPHpYwvB.json b/src/packs/adversaries/adversary_Elemental_Spark_P7h54ZePFPHpYwvB.json index a774d40e..9713e7ba 100644 --- a/src/packs/adversaries/adversary_Elemental_Spark_P7h54ZePFPHpYwvB.json +++ b/src/packs/adversaries/adversary_Elemental_Spark_P7h54ZePFPHpYwvB.json @@ -272,7 +272,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "13OraSLq2YjpZqbm", "img": "icons/creatures/abilities/tail-strike-bone-orange.webp", diff --git a/src/packs/adversaries/adversary_Elite_Soldier_bfhVWMBUh61b9J6n.json b/src/packs/adversaries/adversary_Elite_Soldier_bfhVWMBUh61b9J6n.json index 5baabdec..18dc586b 100644 --- a/src/packs/adversaries/adversary_Elite_Soldier_bfhVWMBUh61b9J6n.json +++ b/src/packs/adversaries/adversary_Elite_Soldier_bfhVWMBUh61b9J6n.json @@ -336,7 +336,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "ojiIZHBd0sMLxSUE", "img": "icons/skills/melee/hand-grip-sword-orange.webp", @@ -391,7 +392,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "zcfyEY29yWqJtZbl", "img": "icons/magic/defensive/shield-barrier-blue.webp", diff --git a/src/packs/adversaries/adversary_Failed_Experiment_ChwwVqowFw8hJQwT.json b/src/packs/adversaries/adversary_Failed_Experiment_ChwwVqowFw8hJQwT.json index 7d439a1b..7e97c5b1 100644 --- a/src/packs/adversaries/adversary_Failed_Experiment_ChwwVqowFw8hJQwT.json +++ b/src/packs/adversaries/adversary_Failed_Experiment_ChwwVqowFw8hJQwT.json @@ -354,7 +354,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "g0h3Zo6xqgfSlyxi", "img": "icons/skills/melee/strike-slashes-red.webp", diff --git a/src/packs/adversaries/adversary_Fallen_Shock_Troop_OsLG2BjaEdTZUJU9.json b/src/packs/adversaries/adversary_Fallen_Shock_Troop_OsLG2BjaEdTZUJU9.json index df039d82..b8b054c8 100644 --- a/src/packs/adversaries/adversary_Fallen_Shock_Troop_OsLG2BjaEdTZUJU9.json +++ b/src/packs/adversaries/adversary_Fallen_Shock_Troop_OsLG2BjaEdTZUJU9.json @@ -350,7 +350,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "gC4whvt2r9Tfso9Y", "img": "icons/creatures/abilities/tail-strike-bone-orange.webp", diff --git a/src/packs/adversaries/adversary_Fallen_Sorcerer_PELRry1vqjBzSAlr.json b/src/packs/adversaries/adversary_Fallen_Sorcerer_PELRry1vqjBzSAlr.json index 48dbefcc..8b690bfd 100644 --- a/src/packs/adversaries/adversary_Fallen_Sorcerer_PELRry1vqjBzSAlr.json +++ b/src/packs/adversaries/adversary_Fallen_Sorcerer_PELRry1vqjBzSAlr.json @@ -311,7 +311,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "s15sNyb3JYMzBLIU", "img": "icons/magic/fire/projectile-beams-salvo-red.webp", @@ -364,7 +365,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "ecp9o8t1dQFXGsse", "img": "icons/magic/death/skull-energy-light-white.webp", @@ -429,7 +431,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "C74czwNeWF5vS1DZ", "img": "icons/magic/symbols/ring-circle-smoke-blue.webp", @@ -549,7 +552,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "gwSgBhkcekCGvXxz", "img": "icons/magic/unholy/strike-hand-glow-pink.webp", diff --git a/src/packs/adversaries/adversary_Fallen_Warlord__Realm_Breaker_hxZ0sgoFJubh5aj6.json b/src/packs/adversaries/adversary_Fallen_Warlord__Realm_Breaker_hxZ0sgoFJubh5aj6.json index c432cae2..8d75dd9e 100644 --- a/src/packs/adversaries/adversary_Fallen_Warlord__Realm_Breaker_hxZ0sgoFJubh5aj6.json +++ b/src/packs/adversaries/adversary_Fallen_Warlord__Realm_Breaker_hxZ0sgoFJubh5aj6.json @@ -476,7 +476,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "PVLjJaQLH3LK3svk", "img": "icons/skills/melee/blood-slash-foam-red.webp", @@ -612,7 +613,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "48tIwFQr64IQ5LaY", "img": "icons/magic/control/fear-fright-monster-grin-red-orange.webp", @@ -690,7 +692,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "v74W0MUqVi9vPUEw", "img": "icons/magic/death/skull-energy-light-purple.webp", @@ -715,7 +718,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "RscRTl8U8u6WcwAB", "img": "icons/magic/unholy/silhouette-evil-horned-giant.webp", diff --git a/src/packs/adversaries/adversary_Fallen_Warlord__Undefeated_Champion_RXkZTwBRi4dJ3JE5.json b/src/packs/adversaries/adversary_Fallen_Warlord__Undefeated_Champion_RXkZTwBRi4dJ3JE5.json index ab5d5c41..061abed8 100644 --- a/src/packs/adversaries/adversary_Fallen_Warlord__Undefeated_Champion_RXkZTwBRi4dJ3JE5.json +++ b/src/packs/adversaries/adversary_Fallen_Warlord__Undefeated_Champion_RXkZTwBRi4dJ3JE5.json @@ -470,7 +470,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "t8yOkGWmPgQ6EbIr", "img": "icons/skills/melee/sword-stuck-glowing-pink.webp", @@ -525,7 +526,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "AP7W9ruUCdTHO69S", "img": "icons/magic/death/undead-skeleton-worn-blue.webp", @@ -615,7 +617,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "55P7ZijSbQeVHCw4", "img": "icons/magic/unholy/barrier-fire-pink.webp", @@ -749,7 +752,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "ReWtcLE5akrSauI1", "img": "icons/skills/melee/strike-weapons-orange.webp", @@ -827,7 +831,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "tQRotPLi3eokgUdM", "img": "icons/magic/death/skull-energy-light-purple.webp", diff --git a/src/packs/adversaries/adversary_Giant_Beastmaster_8VZIgU12cB3cvlyH.json b/src/packs/adversaries/adversary_Giant_Beastmaster_8VZIgU12cB3cvlyH.json index 7eb4f6fc..e82d30d8 100644 --- a/src/packs/adversaries/adversary_Giant_Beastmaster_8VZIgU12cB3cvlyH.json +++ b/src/packs/adversaries/adversary_Giant_Beastmaster_8VZIgU12cB3cvlyH.json @@ -332,7 +332,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "6ZrDjgnWufJohkp1", "img": "icons/skills/ranged/arrow-flying-broadhead-metal.webp", @@ -420,7 +421,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "w1oHm0NoEavQgUzl", "img": "icons/creatures/mammals/ox-bull-horned-glowing-orange.webp", diff --git a/src/packs/adversaries/adversary_Giant_Brawler_YnObCleGjPT7yqEc.json b/src/packs/adversaries/adversary_Giant_Brawler_YnObCleGjPT7yqEc.json index bce45f4c..a51abc03 100644 --- a/src/packs/adversaries/adversary_Giant_Brawler_YnObCleGjPT7yqEc.json +++ b/src/packs/adversaries/adversary_Giant_Brawler_YnObCleGjPT7yqEc.json @@ -311,7 +311,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "ro8AtBdgklyyuydK", "img": "icons/skills/melee/shield-damaged-broken-orange.webp", @@ -410,7 +411,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "kKBbEAffbHxmHo15", "img": "icons/skills/melee/strike-flail-spiked-pink.webp", @@ -505,7 +507,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "B0EniYxyLvjJSqYb", "img": "icons/skills/melee/strike-weapons-orange.webp", diff --git a/src/packs/adversaries/adversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json b/src/packs/adversaries/adversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json index 7606d09f..dc21e5aa 100644 --- a/src/packs/adversaries/adversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json +++ b/src/packs/adversaries/adversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json @@ -410,7 +410,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "MabIQE1Kjn60j08J", "img": "icons/skills/melee/strike-slashes-orange.webp", @@ -553,7 +554,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "NEOQ0E9AGSSIDm4v", "img": "icons/skills/movement/arrow-upward-yellow.webp", @@ -671,7 +673,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "jY0ynjYvbS6E3NgJ", "img": "icons/skills/movement/arrow-down-pink.webp", diff --git a/src/packs/adversaries/adversary_Giant_Mosquitoes_IIWV4ysJPFPnTP7W.json b/src/packs/adversaries/adversary_Giant_Mosquitoes_IIWV4ysJPFPnTP7W.json index 7b21aca5..0db2613f 100644 --- a/src/packs/adversaries/adversary_Giant_Mosquitoes_IIWV4ysJPFPnTP7W.json +++ b/src/packs/adversaries/adversary_Giant_Mosquitoes_IIWV4ysJPFPnTP7W.json @@ -359,7 +359,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Giant_Rat_4PfLnaCrOcMdb4dK.json b/src/packs/adversaries/adversary_Giant_Rat_4PfLnaCrOcMdb4dK.json index afeb44ad..7da2eabd 100644 --- a/src/packs/adversaries/adversary_Giant_Rat_4PfLnaCrOcMdb4dK.json +++ b/src/packs/adversaries/adversary_Giant_Rat_4PfLnaCrOcMdb4dK.json @@ -306,7 +306,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Giant_Recruit_5s8wSvpyC5rxY5aD.json b/src/packs/adversaries/adversary_Giant_Recruit_5s8wSvpyC5rxY5aD.json index a38fce28..0ef9eb18 100644 --- a/src/packs/adversaries/adversary_Giant_Recruit_5s8wSvpyC5rxY5aD.json +++ b/src/packs/adversaries/adversary_Giant_Recruit_5s8wSvpyC5rxY5aD.json @@ -274,7 +274,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "FMgB28X1LammRInU", "img": "icons/creatures/abilities/tail-strike-bone-orange.webp", diff --git a/src/packs/adversaries/adversary_Giant_Scorpion_fmfntuJ8mHRCAktP.json b/src/packs/adversaries/adversary_Giant_Scorpion_fmfntuJ8mHRCAktP.json index d5f25734..b65a27ba 100644 --- a/src/packs/adversaries/adversary_Giant_Scorpion_fmfntuJ8mHRCAktP.json +++ b/src/packs/adversaries/adversary_Giant_Scorpion_fmfntuJ8mHRCAktP.json @@ -314,7 +314,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -419,7 +420,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { @@ -552,7 +554,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Glass_Snake_8KWVLWXFhlY2kYx0.json b/src/packs/adversaries/adversary_Glass_Snake_8KWVLWXFhlY2kYx0.json index ec94123b..67d9a7d7 100644 --- a/src/packs/adversaries/adversary_Glass_Snake_8KWVLWXFhlY2kYx0.json +++ b/src/packs/adversaries/adversary_Glass_Snake_8KWVLWXFhlY2kYx0.json @@ -385,7 +385,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -565,7 +566,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { diff --git a/src/packs/adversaries/adversary_Gorgon_8mJYMpbLTb8qIOrr.json b/src/packs/adversaries/adversary_Gorgon_8mJYMpbLTb8qIOrr.json index 7445c992..98080be6 100644 --- a/src/packs/adversaries/adversary_Gorgon_8mJYMpbLTb8qIOrr.json +++ b/src/packs/adversaries/adversary_Gorgon_8mJYMpbLTb8qIOrr.json @@ -484,7 +484,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "9SO2ov36lFH2YV0S", "img": "icons/creatures/reptiles/snake-fangs-bite-green.webp", @@ -600,7 +601,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "047o6OtNlUwLG1H1", "img": "icons/magic/earth/strike-body-stone-crumble.webp", @@ -695,7 +697,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "IRIaFxFughjXVu0Y", "img": "icons/skills/melee/strike-weapons-orange.webp", diff --git a/src/packs/adversaries/adversary_Greater_Earth_Elemental_dsfB3YhoL5SudvS2.json b/src/packs/adversaries/adversary_Greater_Earth_Elemental_dsfB3YhoL5SudvS2.json index 3a19084d..e8bc6601 100644 --- a/src/packs/adversaries/adversary_Greater_Earth_Elemental_dsfB3YhoL5SudvS2.json +++ b/src/packs/adversaries/adversary_Greater_Earth_Elemental_dsfB3YhoL5SudvS2.json @@ -487,7 +487,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "q45DiEFlXqcXZ5hv", "img": "icons/magic/earth/barrier-stone-brown-green.webp", @@ -621,7 +622,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "ag7t5EW358M0qiSL", "img": "icons/skills/melee/strike-weapons-orange.webp", diff --git a/src/packs/adversaries/adversary_Greater_Water_Elemental_xIICT6tEdnA7dKDV.json b/src/packs/adversaries/adversary_Greater_Water_Elemental_xIICT6tEdnA7dKDV.json index bdc22b1a..73b702fb 100644 --- a/src/packs/adversaries/adversary_Greater_Water_Elemental_xIICT6tEdnA7dKDV.json +++ b/src/packs/adversaries/adversary_Greater_Water_Elemental_xIICT6tEdnA7dKDV.json @@ -310,7 +310,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "B8ZrtRCZrwwwWJOE", "img": "icons/magic/water/projectile-icecicle-glowing.webp", @@ -438,7 +439,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "bcwFQeuU6ZfIGjau", "img": "icons/magic/water/vortex-water-whirlpool-blue.webp", @@ -533,7 +535,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "BGE42W1XPd0vpimR", "img": "icons/magic/water/tendrils-ice-thorns.webp", diff --git a/src/packs/adversaries/adversary_Green_Ooze_SHXedd9zZPVfUgUa.json b/src/packs/adversaries/adversary_Green_Ooze_SHXedd9zZPVfUgUa.json index 426803c2..5746f57b 100644 --- a/src/packs/adversaries/adversary_Green_Ooze_SHXedd9zZPVfUgUa.json +++ b/src/packs/adversaries/adversary_Green_Ooze_SHXedd9zZPVfUgUa.json @@ -447,7 +447,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { @@ -540,7 +541,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Hallowed_Archer_kabueAo6BALApWqp.json b/src/packs/adversaries/adversary_Hallowed_Archer_kabueAo6BALApWqp.json index 43e10f5f..6ad8d177 100644 --- a/src/packs/adversaries/adversary_Hallowed_Archer_kabueAo6BALApWqp.json +++ b/src/packs/adversaries/adversary_Hallowed_Archer_kabueAo6BALApWqp.json @@ -330,7 +330,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "Ye35DuZroQfeFoNw", "img": "icons/skills/ranged/arrows-flying-salvo-yellow.webp", diff --git a/src/packs/adversaries/adversary_Hallowed_Soldier_VENwg7xEFcYObjmT.json b/src/packs/adversaries/adversary_Hallowed_Soldier_VENwg7xEFcYObjmT.json index b9a50759..5a1ccc65 100644 --- a/src/packs/adversaries/adversary_Hallowed_Soldier_VENwg7xEFcYObjmT.json +++ b/src/packs/adversaries/adversary_Hallowed_Soldier_VENwg7xEFcYObjmT.json @@ -327,7 +327,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "ZpypjDbaurs1YSFb", "img": "icons/creatures/abilities/tail-strike-bone-orange.webp", diff --git a/src/packs/adversaries/adversary_Harrier_uRtghKE9mHlII4rs.json b/src/packs/adversaries/adversary_Harrier_uRtghKE9mHlII4rs.json index b2ebe434..d5ce14ff 100644 --- a/src/packs/adversaries/adversary_Harrier_uRtghKE9mHlII4rs.json +++ b/src/packs/adversaries/adversary_Harrier_uRtghKE9mHlII4rs.json @@ -339,7 +339,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Head_Guard_mK3A5FTx6k8iPU3F.json b/src/packs/adversaries/adversary_Head_Guard_mK3A5FTx6k8iPU3F.json index e0e2a946..d9f6e8b9 100644 --- a/src/packs/adversaries/adversary_Head_Guard_mK3A5FTx6k8iPU3F.json +++ b/src/packs/adversaries/adversary_Head_Guard_mK3A5FTx6k8iPU3F.json @@ -292,7 +292,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -356,7 +357,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, @@ -452,7 +454,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Head_Vampire_i2UNbRvgyoSs07M6.json b/src/packs/adversaries/adversary_Head_Vampire_i2UNbRvgyoSs07M6.json index 0c22e7fa..d80504a7 100644 --- a/src/packs/adversaries/adversary_Head_Vampire_i2UNbRvgyoSs07M6.json +++ b/src/packs/adversaries/adversary_Head_Vampire_i2UNbRvgyoSs07M6.json @@ -448,7 +448,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "Oj6qkLG1N6uqQHcx", "img": "icons/creatures/abilities/fang-tooth-blood-red.webp", @@ -503,7 +504,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "IWtpuQCuV82lOSry", "img": "icons/creatures/mammals/bat-giant-tattered-purple.webp", @@ -601,7 +603,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "6FsQf339qGHnz3ZF", "img": "icons/magic/unholy/strike-beam-blood-small-red-purple.webp", diff --git a/src/packs/adversaries/adversary_High_Seraph_r1mbfSSwKWdcFdAU.json b/src/packs/adversaries/adversary_High_Seraph_r1mbfSSwKWdcFdAU.json index d03fdea1..58b26f24 100644 --- a/src/packs/adversaries/adversary_High_Seraph_r1mbfSSwKWdcFdAU.json +++ b/src/packs/adversaries/adversary_High_Seraph_r1mbfSSwKWdcFdAU.json @@ -371,7 +371,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "FilEB21L5q9XxKE1", "img": "icons/magic/light/beams-rays-orange-purple-small.webp", @@ -514,7 +515,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "Vrb8dIJcOJ3ClwO5", "img": "icons/magic/light/beam-strike-orange-gold.webp", @@ -569,7 +571,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "9LpLXpQBfQryJA60", "img": "icons/magic/holy/barrier-shield-winged-blue.webp", diff --git a/src/packs/adversaries/adversary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json b/src/packs/adversaries/adversary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json index 9341c9ab..d291f805 100644 --- a/src/packs/adversaries/adversary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json +++ b/src/packs/adversaries/adversary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json @@ -416,7 +416,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "pfXYuH7rtsyVjSXh", "img": "icons/creatures/slimes/slime-face-melting-green.webp", @@ -508,7 +509,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "Mq90kFBM5ix2pzzh", "img": "icons/creatures/slimes/slime-movement-pseudopods-green.webp", diff --git a/src/packs/adversaries/adversary_Hydra_MI126iMOOobQ1Obn.json b/src/packs/adversaries/adversary_Hydra_MI126iMOOobQ1Obn.json index 0bc04c03..3c39550c 100644 --- a/src/packs/adversaries/adversary_Hydra_MI126iMOOobQ1Obn.json +++ b/src/packs/adversaries/adversary_Hydra_MI126iMOOobQ1Obn.json @@ -354,7 +354,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "b2KflqWoOxHMQf97", "img": "icons/magic/life/cross-beam-green.webp", @@ -432,7 +433,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "bCeCu8M25izOAsuY", "img": "icons/magic/death/skull-energy-light-white.webp", @@ -485,7 +487,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "sJzjcRBgYRp5f53E", "img": "icons/magic/symbols/star-rising-purple.webp", diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Hexer_MbBPIOxaxXYNApXz.json b/src/packs/adversaries/adversary_Jagged_Knife_Hexer_MbBPIOxaxXYNApXz.json index 465dd7a2..26d83e78 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Hexer_MbBPIOxaxXYNApXz.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Hexer_MbBPIOxaxXYNApXz.json @@ -260,7 +260,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { @@ -397,7 +398,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Kneebreaker_CBKixLH3yhivZZuL.json b/src/packs/adversaries/adversary_Jagged_Knife_Kneebreaker_CBKixLH3yhivZZuL.json index e7ec011d..698ef485 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Kneebreaker_CBKixLH3yhivZZuL.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Kneebreaker_CBKixLH3yhivZZuL.json @@ -316,7 +316,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Lackey_C0OMQqV7pN6t7ouR.json b/src/packs/adversaries/adversary_Jagged_Knife_Lackey_C0OMQqV7pN6t7ouR.json index 99381bd6..668852a8 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Lackey_C0OMQqV7pN6t7ouR.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Lackey_C0OMQqV7pN6t7ouR.json @@ -282,7 +282,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Lieutenant_aTljstqteGoLpCBq.json b/src/packs/adversaries/adversary_Jagged_Knife_Lieutenant_aTljstqteGoLpCBq.json index 7e448a62..6f4b54a5 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Lieutenant_aTljstqteGoLpCBq.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Lieutenant_aTljstqteGoLpCBq.json @@ -262,7 +262,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -288,7 +289,8 @@ "actions": {}, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -420,7 +422,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -516,7 +519,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Shadow_XF4tYTq9nPJAy2ox.json b/src/packs/adversaries/adversary_Jagged_Knife_Shadow_XF4tYTq9nPJAy2ox.json index 10dc241f..ad53f212 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Shadow_XF4tYTq9nPJAy2ox.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Shadow_XF4tYTq9nPJAy2ox.json @@ -362,7 +362,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { diff --git a/src/packs/adversaries/adversary_Juvenile_Flickerfly_MYXmTx2FHcIjdfYZ.json b/src/packs/adversaries/adversary_Juvenile_Flickerfly_MYXmTx2FHcIjdfYZ.json index 25b0b8b0..fc30a072 100644 --- a/src/packs/adversaries/adversary_Juvenile_Flickerfly_MYXmTx2FHcIjdfYZ.json +++ b/src/packs/adversaries/adversary_Juvenile_Flickerfly_MYXmTx2FHcIjdfYZ.json @@ -450,7 +450,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "Bt7MqMkPpPpzWksK", "img": "icons/magic/light/explosion-glow-spiral-yellow.webp", @@ -610,7 +611,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "EjfM83eVCdcVGC3c", "img": "icons/magic/air/fog-gas-smoke-purple.webp", diff --git a/src/packs/adversaries/adversary_Knight_of_the_Realm_7ai2opemrclQe3VF.json b/src/packs/adversaries/adversary_Knight_of_the_Realm_7ai2opemrclQe3VF.json index 298af435..51e7979d 100644 --- a/src/packs/adversaries/adversary_Knight_of_the_Realm_7ai2opemrclQe3VF.json +++ b/src/packs/adversaries/adversary_Knight_of_the_Realm_7ai2opemrclQe3VF.json @@ -475,7 +475,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "djKDZawLnGF1zkbY", "img": "icons/skills/movement/arrow-upward-yellow.webp", @@ -530,7 +531,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "RoxNNIn0m9rHQDH8", "img": "icons/environment/people/charge.webp", diff --git a/src/packs/adversaries/adversary_Kraken_4nqv3ZwJGjnmic8j.json b/src/packs/adversaries/adversary_Kraken_4nqv3ZwJGjnmic8j.json index 12f881d4..62d443c9 100644 --- a/src/packs/adversaries/adversary_Kraken_4nqv3ZwJGjnmic8j.json +++ b/src/packs/adversaries/adversary_Kraken_4nqv3ZwJGjnmic8j.json @@ -365,7 +365,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "vz2BWhispgR7mSWF", "img": "icons/magic/water/orb-water-bubbles-blue.webp", @@ -504,7 +505,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "eksa3E2ecBgdib6h", "img": "icons/magic/water/projectile-icecicle-glowing.webp", @@ -599,7 +601,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "m4aybzb8tXWHelDU", "img": "icons/skills/melee/strike-weapons-orange.webp", diff --git a/src/packs/adversaries/adversary_Masked_Thief_niBpVU7yeo5ccskE.json b/src/packs/adversaries/adversary_Masked_Thief_niBpVU7yeo5ccskE.json index 90ede3ec..5af8b388 100644 --- a/src/packs/adversaries/adversary_Masked_Thief_niBpVU7yeo5ccskE.json +++ b/src/packs/adversaries/adversary_Masked_Thief_niBpVU7yeo5ccskE.json @@ -302,7 +302,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "Cgk36WXthA9LwOYb", "img": "icons/skills/melee/strike-sword-gray.webp", @@ -379,7 +380,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "tP2DD751nOLxFVps", "img": "icons/environment/traps/trap-jaw-tan.webp", diff --git a/src/packs/adversaries/adversary_Master_Assassin_dNta0cUzr96xcFhf.json b/src/packs/adversaries/adversary_Master_Assassin_dNta0cUzr96xcFhf.json index 557ef607..5ac80827 100644 --- a/src/packs/adversaries/adversary_Master_Assassin_dNta0cUzr96xcFhf.json +++ b/src/packs/adversaries/adversary_Master_Assassin_dNta0cUzr96xcFhf.json @@ -372,7 +372,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "za6Qr0CjI9Kb4I0U", "img": "icons/skills/movement/arrows-up-trio-red.webp", @@ -427,7 +428,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "s0WcpK43WN2ptqNc", "img": "icons/skills/melee/strike-dagger-blood-red.webp", @@ -522,7 +524,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "PcNgHScmTd9l3exN", "img": "icons/skills/melee/strike-weapons-orange.webp", diff --git a/src/packs/adversaries/adversary_Merchant_Baron_Vy02IhGhkJLuezu4.json b/src/packs/adversaries/adversary_Merchant_Baron_Vy02IhGhkJLuezu4.json index a3ab2363..0dea7b8e 100644 --- a/src/packs/adversaries/adversary_Merchant_Baron_Vy02IhGhkJLuezu4.json +++ b/src/packs/adversaries/adversary_Merchant_Baron_Vy02IhGhkJLuezu4.json @@ -308,7 +308,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "7dxToUpxOyISXXde", "img": "icons/commodities/currency/coins-plain-stack-gold-yellow.webp", @@ -363,7 +364,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "QnDvERcyaq3XLCjF", "img": "icons/environment/people/charge.webp", diff --git a/src/packs/adversaries/adversary_Minor_Chaos_Elemental_sRn4bqerfARvhgSV.json b/src/packs/adversaries/adversary_Minor_Chaos_Elemental_sRn4bqerfARvhgSV.json index edb50cf1..8d7c1888 100644 --- a/src/packs/adversaries/adversary_Minor_Chaos_Elemental_sRn4bqerfARvhgSV.json +++ b/src/packs/adversaries/adversary_Minor_Chaos_Elemental_sRn4bqerfARvhgSV.json @@ -362,7 +362,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { @@ -488,7 +489,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -514,7 +516,8 @@ "actions": {}, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, @@ -610,7 +613,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Minor_Demon_3tqCjDwJAQ7JKqMb.json b/src/packs/adversaries/adversary_Minor_Demon_3tqCjDwJAQ7JKqMb.json index 5d6c34cd..813af3c3 100644 --- a/src/packs/adversaries/adversary_Minor_Demon_3tqCjDwJAQ7JKqMb.json +++ b/src/packs/adversaries/adversary_Minor_Demon_3tqCjDwJAQ7JKqMb.json @@ -445,7 +445,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -501,7 +502,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, @@ -597,7 +599,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Minor_Fire_Elemental_DscWkNVoHak6P4hh.json b/src/packs/adversaries/adversary_Minor_Fire_Elemental_DscWkNVoHak6P4hh.json index 7421e270..f57abdd9 100644 --- a/src/packs/adversaries/adversary_Minor_Fire_Elemental_DscWkNVoHak6P4hh.json +++ b/src/packs/adversaries/adversary_Minor_Fire_Elemental_DscWkNVoHak6P4hh.json @@ -358,7 +358,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -465,7 +466,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -631,7 +633,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, @@ -727,7 +730,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Minor_Treant_G62k4oSkhkoXEs2D.json b/src/packs/adversaries/adversary_Minor_Treant_G62k4oSkhkoXEs2D.json index 267a1e14..c16b2c36 100644 --- a/src/packs/adversaries/adversary_Minor_Treant_G62k4oSkhkoXEs2D.json +++ b/src/packs/adversaries/adversary_Minor_Treant_G62k4oSkhkoXEs2D.json @@ -276,7 +276,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json b/src/packs/adversaries/adversary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json index 570db804..9ac0caa9 100644 --- a/src/packs/adversaries/adversary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json +++ b/src/packs/adversaries/adversary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json @@ -414,7 +414,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "b2QvDYOq1nreI2uD", "img": "icons/creatures/mammals/bull-horned-blue.webp", @@ -512,7 +513,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "WxbHcbaeb6L7g8qN", "img": "icons/skills/melee/strike-slashes-red.webp", diff --git a/src/packs/adversaries/adversary_Monarch_yx0vK2yfNVZKWUUi.json b/src/packs/adversaries/adversary_Monarch_yx0vK2yfNVZKWUUi.json index 3f2d7d88..8ec7b09d 100644 --- a/src/packs/adversaries/adversary_Monarch_yx0vK2yfNVZKWUUi.json +++ b/src/packs/adversaries/adversary_Monarch_yx0vK2yfNVZKWUUi.json @@ -235,7 +235,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "iYHCYTJzZbw5f0pF", "img": "icons/commodities/treasure/crown-gold-satin-gems-red.webp", @@ -290,7 +291,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "9K7C1PR4Q6QrUjjb", "img": "icons/environment/people/charge.webp", @@ -435,7 +437,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "kA5NZTdiknsh7wxp", "img": "icons/sundries/scrolls/scroll-bound-sealed-red-tan.webp", diff --git a/src/packs/adversaries/adversary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json b/src/packs/adversaries/adversary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json index 721d8973..febdc8e7 100644 --- a/src/packs/adversaries/adversary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json +++ b/src/packs/adversaries/adversary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json @@ -424,7 +424,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "r1T70u9n3bRfUTX5", "img": "icons/magic/unholy/hand-marked-pink.webp", @@ -540,7 +541,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "5AQTqW1GDidHfU3a", "img": "icons/skills/movement/arrows-up-trio-red.webp", @@ -676,7 +678,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "IOCG3J20wUHvyvvh", "img": "icons/magic/movement/trail-streak-zigzag-yellow.webp", diff --git a/src/packs/adversaries/adversary_Oak_Treant_XK78QUfY8c8Go8Uv.json b/src/packs/adversaries/adversary_Oak_Treant_XK78QUfY8c8Go8Uv.json index 00ba4dfe..977792ea 100644 --- a/src/packs/adversaries/adversary_Oak_Treant_XK78QUfY8c8Go8Uv.json +++ b/src/packs/adversaries/adversary_Oak_Treant_XK78QUfY8c8Go8Uv.json @@ -315,7 +315,8 @@ } }, "originItemType": null, - "multiclassOrigin": false + "multiclassOrigin": false, + "featureForm": "action" }, "_id": "Q2slH9qkBO5SPw43", "img": "icons/consumables/nuts/nut-spiked-shell.webp", @@ -378,7 +379,8 @@ } }, "originItemType": null, - "multiclassOrigin": false + "multiclassOrigin": false, + "featureForm": "action" }, "_id": "sqkgw26P2KiQVtXT", "img": "icons/consumables/plants/thorned-stem-brown.webp", diff --git a/src/packs/adversaries/adversary_Oracle_of_Doom_befIqd5IYKg6eUz2.json b/src/packs/adversaries/adversary_Oracle_of_Doom_befIqd5IYKg6eUz2.json index 0925049d..be97acf2 100644 --- a/src/packs/adversaries/adversary_Oracle_of_Doom_befIqd5IYKg6eUz2.json +++ b/src/packs/adversaries/adversary_Oracle_of_Doom_befIqd5IYKg6eUz2.json @@ -467,7 +467,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "QoFecwKWBFzrk4Wp", "img": "icons/magic/death/skeleton-skull-soul-blue.webp", @@ -546,7 +547,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "A4yI2RENCuLk6mg9", "img": "icons/magic/death/skull-horned-worn-fire-blue.webp", @@ -571,7 +573,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "IPoWZmSQ2kgWek5T", "img": "icons/magic/symbols/mask-yellow-orange.webp", @@ -657,7 +660,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "kuxTMjy8lOmNSa8e", "img": "icons/magic/control/sihouette-hold-beam-green.webp", diff --git a/src/packs/adversaries/adversary_Outer_Realms_Abomination_A0SeeDzwjvqOsyof.json b/src/packs/adversaries/adversary_Outer_Realms_Abomination_A0SeeDzwjvqOsyof.json index 8e9d6b37..d4b37075 100644 --- a/src/packs/adversaries/adversary_Outer_Realms_Abomination_A0SeeDzwjvqOsyof.json +++ b/src/packs/adversaries/adversary_Outer_Realms_Abomination_A0SeeDzwjvqOsyof.json @@ -422,7 +422,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "K3MQO1I42nmfM2F2", "img": "icons/magic/sonic/explosion-shock-sound-wave.webp", @@ -531,7 +532,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "u9dR2Qh3swHZalXj", "img": "icons/magic/unholy/orb-contained-pink.webp", diff --git a/src/packs/adversaries/adversary_Outer_Realms_Corrupter_ms6nuOl3NFkhPj1k.json b/src/packs/adversaries/adversary_Outer_Realms_Corrupter_ms6nuOl3NFkhPj1k.json index 4226d346..f84bc04d 100644 --- a/src/packs/adversaries/adversary_Outer_Realms_Corrupter_ms6nuOl3NFkhPj1k.json +++ b/src/packs/adversaries/adversary_Outer_Realms_Corrupter_ms6nuOl3NFkhPj1k.json @@ -375,7 +375,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "gBLVvHbyekmIUITD", "img": "icons/magic/unholy/barrier-shield-glowing-pink.webp", diff --git a/src/packs/adversaries/adversary_Outer_Realms_Thrall_moJhHgKqTKPS2WYS.json b/src/packs/adversaries/adversary_Outer_Realms_Thrall_moJhHgKqTKPS2WYS.json index f5558098..38ed9db0 100644 --- a/src/packs/adversaries/adversary_Outer_Realms_Thrall_moJhHgKqTKPS2WYS.json +++ b/src/packs/adversaries/adversary_Outer_Realms_Thrall_moJhHgKqTKPS2WYS.json @@ -272,7 +272,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "7DWNmxZvp1Fm3aq3", "img": "icons/creatures/abilities/tail-strike-bone-orange.webp", diff --git a/src/packs/adversaries/adversary_Patchwork_Zombie_Hulk_EQTOAOUrkIvS2z88.json b/src/packs/adversaries/adversary_Patchwork_Zombie_Hulk_EQTOAOUrkIvS2z88.json index efffaf03..1575bbf8 100644 --- a/src/packs/adversaries/adversary_Patchwork_Zombie_Hulk_EQTOAOUrkIvS2z88.json +++ b/src/packs/adversaries/adversary_Patchwork_Zombie_Hulk_EQTOAOUrkIvS2z88.json @@ -438,7 +438,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -544,7 +545,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Perfected_Zombie_CP6iRfHdyFWniTHY.json b/src/packs/adversaries/adversary_Perfected_Zombie_CP6iRfHdyFWniTHY.json index ae8bb68f..3a7af054 100644 --- a/src/packs/adversaries/adversary_Perfected_Zombie_CP6iRfHdyFWniTHY.json +++ b/src/packs/adversaries/adversary_Perfected_Zombie_CP6iRfHdyFWniTHY.json @@ -413,7 +413,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "CKy2r6FguyTSO9Fm", "img": "icons/skills/melee/strike-axe-energy-pink.webp", @@ -500,7 +501,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "hWxjmdc1O5J1otLM", "img": "icons/magic/perception/shadow-stealth-eyes-purple.webp", diff --git a/src/packs/adversaries/adversary_Petty_Noble_wycLpvebWdUqRhpP.json b/src/packs/adversaries/adversary_Petty_Noble_wycLpvebWdUqRhpP.json index fc5d8f01..6e3c052c 100644 --- a/src/packs/adversaries/adversary_Petty_Noble_wycLpvebWdUqRhpP.json +++ b/src/packs/adversaries/adversary_Petty_Noble_wycLpvebWdUqRhpP.json @@ -313,7 +313,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -369,7 +370,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Pirate_Captain_OROJbjsqagVh7ECV.json b/src/packs/adversaries/adversary_Pirate_Captain_OROJbjsqagVh7ECV.json index 5b3db044..a1c05eab 100644 --- a/src/packs/adversaries/adversary_Pirate_Captain_OROJbjsqagVh7ECV.json +++ b/src/packs/adversaries/adversary_Pirate_Captain_OROJbjsqagVh7ECV.json @@ -347,7 +347,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -452,7 +453,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -548,7 +550,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Pirate_Tough_mhcVkVFrzIJ18FDm.json b/src/packs/adversaries/adversary_Pirate_Tough_mhcVkVFrzIJ18FDm.json index 919b8aaf..6d15f7da 100644 --- a/src/packs/adversaries/adversary_Pirate_Tough_mhcVkVFrzIJ18FDm.json +++ b/src/packs/adversaries/adversary_Pirate_Tough_mhcVkVFrzIJ18FDm.json @@ -407,7 +407,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "uzlxE1Cxm9GGmrNs", "img": "icons/skills/melee/unarmed-punch-fist-blue.webp", diff --git a/src/packs/adversaries/adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json b/src/packs/adversaries/adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json index f555999d..dc5b66f4 100644 --- a/src/packs/adversaries/adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json +++ b/src/packs/adversaries/adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json @@ -391,7 +391,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { @@ -484,7 +485,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Rotted_Zombie_gP3fWTLzSFnpA8EJ.json b/src/packs/adversaries/adversary_Rotted_Zombie_gP3fWTLzSFnpA8EJ.json index 461846a2..6a7ae3ff 100644 --- a/src/packs/adversaries/adversary_Rotted_Zombie_gP3fWTLzSFnpA8EJ.json +++ b/src/packs/adversaries/adversary_Rotted_Zombie_gP3fWTLzSFnpA8EJ.json @@ -276,7 +276,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Royal_Advisor_EtLJiTsilPPZvLUX.json b/src/packs/adversaries/adversary_Royal_Advisor_EtLJiTsilPPZvLUX.json index 36c5a617..ef295cb0 100644 --- a/src/packs/adversaries/adversary_Royal_Advisor_EtLJiTsilPPZvLUX.json +++ b/src/packs/adversaries/adversary_Royal_Advisor_EtLJiTsilPPZvLUX.json @@ -343,7 +343,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "lG6vMc0zUbijpvCM", "img": "icons/skills/social/diplomacy-handshake.webp", @@ -398,7 +399,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "iwNrNBbvm3RMgSw5", "img": "icons/skills/social/diplomacy-unity-alliance.webp", diff --git a/src/packs/adversaries/adversary_Secret_Keeper_sLAccjvCWfeedbpI.json b/src/packs/adversaries/adversary_Secret_Keeper_sLAccjvCWfeedbpI.json index 113d8f73..9c158011 100644 --- a/src/packs/adversaries/adversary_Secret_Keeper_sLAccjvCWfeedbpI.json +++ b/src/packs/adversaries/adversary_Secret_Keeper_sLAccjvCWfeedbpI.json @@ -289,7 +289,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "WLnguxRo9egh2hfX", "img": "icons/skills/movement/arrows-up-trio-red.webp", @@ -389,7 +390,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "O5Nn1Slv8RJJpNeT", "img": "icons/magic/unholy/hand-claw-glow-orange.webp", @@ -474,7 +476,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "4L7aM9NDLbjvuwI3", "img": "icons/magic/unholy/silhouette-light-fire-blue.webp", @@ -529,7 +532,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "Q28NPuSMccjzykib", "img": "icons/creatures/unholy/demon-fire-horned-clawed.webp", diff --git a/src/packs/adversaries/adversary_Sellsword_bgreCaQ6ap2DVpCr.json b/src/packs/adversaries/adversary_Sellsword_bgreCaQ6ap2DVpCr.json index 8f490686..d5da4bca 100644 --- a/src/packs/adversaries/adversary_Sellsword_bgreCaQ6ap2DVpCr.json +++ b/src/packs/adversaries/adversary_Sellsword_bgreCaQ6ap2DVpCr.json @@ -276,7 +276,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Shark_YmVAkdNsyuXWTtYp.json b/src/packs/adversaries/adversary_Shark_YmVAkdNsyuXWTtYp.json index 8729ac0a..dce37d5a 100644 --- a/src/packs/adversaries/adversary_Shark_YmVAkdNsyuXWTtYp.json +++ b/src/packs/adversaries/adversary_Shark_YmVAkdNsyuXWTtYp.json @@ -456,7 +456,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "LBKPfi8XktBAwbrt", "img": "icons/skills/wounds/blood-spurt-spray-red.webp", diff --git a/src/packs/adversaries/adversary_Siren_BK4jwyXSRx7IOQiO.json b/src/packs/adversaries/adversary_Siren_BK4jwyXSRx7IOQiO.json index 4e3f2aca..e6700b73 100644 --- a/src/packs/adversaries/adversary_Siren_BK4jwyXSRx7IOQiO.json +++ b/src/packs/adversaries/adversary_Siren_BK4jwyXSRx7IOQiO.json @@ -388,7 +388,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "Ks3HpB4W1l5FqR7p", "img": "icons/magic/control/hypnosis-mesmerism-eye.webp", diff --git a/src/packs/adversaries/adversary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json b/src/packs/adversaries/adversary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json index aeb2dd0e..845bd708 100644 --- a/src/packs/adversaries/adversary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json +++ b/src/packs/adversaries/adversary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json @@ -327,7 +327,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Skeleton_Dredge_6l1a3Fazq8BoKIcc.json b/src/packs/adversaries/adversary_Skeleton_Dredge_6l1a3Fazq8BoKIcc.json index 22d00f72..e5daed4f 100644 --- a/src/packs/adversaries/adversary_Skeleton_Dredge_6l1a3Fazq8BoKIcc.json +++ b/src/packs/adversaries/adversary_Skeleton_Dredge_6l1a3Fazq8BoKIcc.json @@ -276,7 +276,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Skeleton_Knight_Q9LaVTyXF9NF12C7.json b/src/packs/adversaries/adversary_Skeleton_Knight_Q9LaVTyXF9NF12C7.json index c16d878b..b4a349b5 100644 --- a/src/packs/adversaries/adversary_Skeleton_Knight_Q9LaVTyXF9NF12C7.json +++ b/src/packs/adversaries/adversary_Skeleton_Knight_Q9LaVTyXF9NF12C7.json @@ -412,7 +412,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -512,7 +513,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Skeleton_Warrior_10YIQl0lvCJXZLfX.json b/src/packs/adversaries/adversary_Skeleton_Warrior_10YIQl0lvCJXZLfX.json index 1a1ca906..dbf39bed 100644 --- a/src/packs/adversaries/adversary_Skeleton_Warrior_10YIQl0lvCJXZLfX.json +++ b/src/packs/adversaries/adversary_Skeleton_Warrior_10YIQl0lvCJXZLfX.json @@ -344,7 +344,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Spectral_Archer_5tCkhnBByUIN5UdG.json b/src/packs/adversaries/adversary_Spectral_Archer_5tCkhnBByUIN5UdG.json index 9832d7ce..7dfe0c09 100644 --- a/src/packs/adversaries/adversary_Spectral_Archer_5tCkhnBByUIN5UdG.json +++ b/src/packs/adversaries/adversary_Spectral_Archer_5tCkhnBByUIN5UdG.json @@ -403,7 +403,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "0h4IVmCgWXyQngAw", "img": "icons/skills/targeting/crosshair-triple-strike-orange.webp", diff --git a/src/packs/adversaries/adversary_Spectral_Captain_65cSO3EQEh6ZH6Xk.json b/src/packs/adversaries/adversary_Spectral_Captain_65cSO3EQEh6ZH6Xk.json index 3cb0a37c..dd044b50 100644 --- a/src/packs/adversaries/adversary_Spectral_Captain_65cSO3EQEh6ZH6Xk.json +++ b/src/packs/adversaries/adversary_Spectral_Captain_65cSO3EQEh6ZH6Xk.json @@ -359,7 +359,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "7YVe4DfEWMNLXNvu", "img": "icons/magic/death/undead-skeleton-worn-blue.webp", @@ -414,7 +415,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "X0vtV30ACVVZ6NfF", "img": "icons/magic/defensive/shield-barrier-flaming-diamond-teal.webp", @@ -509,7 +511,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "b9wn9oVMne8E1OYx", "img": "icons/skills/melee/strike-weapons-orange.webp", diff --git a/src/packs/adversaries/adversary_Spectral_Guardian_UFVGl1osOsJTneLf.json b/src/packs/adversaries/adversary_Spectral_Guardian_UFVGl1osOsJTneLf.json index 04062b0d..6dcd83c4 100644 --- a/src/packs/adversaries/adversary_Spectral_Guardian_UFVGl1osOsJTneLf.json +++ b/src/packs/adversaries/adversary_Spectral_Guardian_UFVGl1osOsJTneLf.json @@ -435,7 +435,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "L48tQmj5O3s2pjBn", "img": "icons/weapons/swords/sword-flanged-lightning.webp", diff --git a/src/packs/adversaries/adversary_Spellblade_ldbWEL7uZs84vyrR.json b/src/packs/adversaries/adversary_Spellblade_ldbWEL7uZs84vyrR.json index f096aeef..d9b3dbf3 100644 --- a/src/packs/adversaries/adversary_Spellblade_ldbWEL7uZs84vyrR.json +++ b/src/packs/adversaries/adversary_Spellblade_ldbWEL7uZs84vyrR.json @@ -341,7 +341,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -397,7 +398,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -493,7 +495,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Spy_8zlynOhnVA59KpKT.json b/src/packs/adversaries/adversary_Spy_8zlynOhnVA59KpKT.json index 88f8eb5b..ffc4dfe7 100644 --- a/src/packs/adversaries/adversary_Spy_8zlynOhnVA59KpKT.json +++ b/src/packs/adversaries/adversary_Spy_8zlynOhnVA59KpKT.json @@ -260,7 +260,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "csCWQuSqic5ckHeO", "img": "icons/magic/perception/orb-eye-scrying.webp", @@ -381,7 +382,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "UvgVDn0YjISLdKE4", "img": "icons/magic/perception/silhouette-stealth-shadow.webp", diff --git a/src/packs/adversaries/adversary_Stag_Knight_KGVwnLq85ywP9xvB.json b/src/packs/adversaries/adversary_Stag_Knight_KGVwnLq85ywP9xvB.json index 0f6fbc5f..2fb0c531 100644 --- a/src/packs/adversaries/adversary_Stag_Knight_KGVwnLq85ywP9xvB.json +++ b/src/packs/adversaries/adversary_Stag_Knight_KGVwnLq85ywP9xvB.json @@ -363,7 +363,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "CYaSykD9BUxpiOxg", "img": "icons/skills/melee/strike-blade-hooked-green-purple.webp", @@ -447,7 +448,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "1LHHdn4ToSwSznuP", "img": "icons/magic/nature/root-vine-barrier-wall-brown.webp", diff --git a/src/packs/adversaries/adversary_Stonewraith_3aAS2Qm3R6cgaYfE.json b/src/packs/adversaries/adversary_Stonewraith_3aAS2Qm3R6cgaYfE.json index 6572d058..807d6675 100644 --- a/src/packs/adversaries/adversary_Stonewraith_3aAS2Qm3R6cgaYfE.json +++ b/src/packs/adversaries/adversary_Stonewraith_3aAS2Qm3R6cgaYfE.json @@ -339,7 +339,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "tQgxiSS48TJ3X1Dl", "img": "icons/creatures/abilities/mouth-teeth-rows-white.webp", @@ -521,7 +522,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "9Z0i0uURfBMVIapJ", "img": "icons/magic/sonic/projectile-sound-rings-wave.webp", @@ -616,7 +618,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "faM1UzclP0X3ZrkJ", "img": "icons/skills/melee/strike-weapons-orange.webp", diff --git a/src/packs/adversaries/adversary_Sylvan_Soldier_VtFBt9XBE0WrGGxP.json b/src/packs/adversaries/adversary_Sylvan_Soldier_VtFBt9XBE0WrGGxP.json index bcaf166a..af64867f 100644 --- a/src/packs/adversaries/adversary_Sylvan_Soldier_VtFBt9XBE0WrGGxP.json +++ b/src/packs/adversaries/adversary_Sylvan_Soldier_VtFBt9XBE0WrGGxP.json @@ -414,7 +414,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -475,7 +476,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [ { diff --git a/src/packs/adversaries/adversary_Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json b/src/packs/adversaries/adversary_Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json index 2a753812..1d686445 100644 --- a/src/packs/adversaries/adversary_Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json +++ b/src/packs/adversaries/adversary_Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json @@ -353,7 +353,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -407,7 +408,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [ { diff --git a/src/packs/adversaries/adversary_Tangle_Bramble_XcAGOSmtCFLT1unN.json b/src/packs/adversaries/adversary_Tangle_Bramble_XcAGOSmtCFLT1unN.json index 8b984fc1..74b228f5 100644 --- a/src/packs/adversaries/adversary_Tangle_Bramble_XcAGOSmtCFLT1unN.json +++ b/src/packs/adversaries/adversary_Tangle_Bramble_XcAGOSmtCFLT1unN.json @@ -315,7 +315,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -341,7 +342,8 @@ "actions": {}, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Tiny_Red_Ooze_1fkLQXVtmILqfJ44.json b/src/packs/adversaries/adversary_Tiny_Red_Ooze_1fkLQXVtmILqfJ44.json index f3ea25ff..7c3da937 100644 --- a/src/packs/adversaries/adversary_Tiny_Red_Ooze_1fkLQXVtmILqfJ44.json +++ b/src/packs/adversaries/adversary_Tiny_Red_Ooze_1fkLQXVtmILqfJ44.json @@ -277,7 +277,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Treant_Sapling_o63nS0k3wHu6EgKP.json b/src/packs/adversaries/adversary_Treant_Sapling_o63nS0k3wHu6EgKP.json index e4e5f6f7..0ff01c70 100644 --- a/src/packs/adversaries/adversary_Treant_Sapling_o63nS0k3wHu6EgKP.json +++ b/src/packs/adversaries/adversary_Treant_Sapling_o63nS0k3wHu6EgKP.json @@ -271,7 +271,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "fh8ehANkVOnxEKVa", "img": "icons/creatures/abilities/tail-strike-bone-orange.webp", diff --git a/src/packs/adversaries/adversary_Vampire_WWyUp6Mxl1S3KYUG.json b/src/packs/adversaries/adversary_Vampire_WWyUp6Mxl1S3KYUG.json index f2522a90..59bdb150 100644 --- a/src/packs/adversaries/adversary_Vampire_WWyUp6Mxl1S3KYUG.json +++ b/src/packs/adversaries/adversary_Vampire_WWyUp6Mxl1S3KYUG.json @@ -352,7 +352,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "X0VgwJbK2n3mez0p", "img": "icons/creatures/abilities/fang-tooth-blood-red.webp", @@ -407,7 +408,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "DKVB4rbX2M1CCVM7", "img": "icons/magic/air/fog-gas-smoke-blue-gray.webp", diff --git a/src/packs/adversaries/adversary_Vault_Guardian_Gaoler_JqYraOqNmmhHk4Yy.json b/src/packs/adversaries/adversary_Vault_Guardian_Gaoler_JqYraOqNmmhHk4Yy.json index 38cddad7..575d88ee 100644 --- a/src/packs/adversaries/adversary_Vault_Guardian_Gaoler_JqYraOqNmmhHk4Yy.json +++ b/src/packs/adversaries/adversary_Vault_Guardian_Gaoler_JqYraOqNmmhHk4Yy.json @@ -308,7 +308,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "VlHp8RjHy7MK8rqC", "img": "icons/environment/traps/cage-grey-steel.webp", diff --git a/src/packs/adversaries/adversary_Vault_Guardian_Sentinel_FVgYb28fhxlVcGwA.json b/src/packs/adversaries/adversary_Vault_Guardian_Sentinel_FVgYb28fhxlVcGwA.json index 10e023c1..e0776c8c 100644 --- a/src/packs/adversaries/adversary_Vault_Guardian_Sentinel_FVgYb28fhxlVcGwA.json +++ b/src/packs/adversaries/adversary_Vault_Guardian_Sentinel_FVgYb28fhxlVcGwA.json @@ -284,7 +284,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "DLspoIclNJcTB3YJ", "img": "icons/magic/perception/eye-ringed-glow-angry-red.webp", @@ -434,7 +435,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "LVFZ4AfVhS6Q9hRy", "img": "icons/magic/sonic/projectile-shock-wave-blue.webp", @@ -529,7 +531,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "N4446BxubUanUQHH", "img": "icons/skills/melee/strike-weapons-orange.webp", diff --git a/src/packs/adversaries/adversary_Vault_Guardian_Turret_c5hGdvY5UnSjlHws.json b/src/packs/adversaries/adversary_Vault_Guardian_Turret_c5hGdvY5UnSjlHws.json index 6b4671ea..a11bef82 100644 --- a/src/packs/adversaries/adversary_Vault_Guardian_Turret_c5hGdvY5UnSjlHws.json +++ b/src/packs/adversaries/adversary_Vault_Guardian_Turret_c5hGdvY5UnSjlHws.json @@ -289,7 +289,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "uwAr6wR4k7ppI2cW", "img": "icons/skills/targeting/crosshair-pointed-orange.webp", @@ -388,7 +389,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "G7qZ9RHPyNns3axX", "img": "icons/commodities/tech/cog-brass.webp", @@ -487,7 +489,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "ALDtQci3ktq9cajU", "img": "icons/magic/sonic/explosion-shock-wave-teal.webp", diff --git a/src/packs/adversaries/adversary_Volcanic_Dragon__Ashen_Tyrant_pMuXGCSOQaxpi5tb.json b/src/packs/adversaries/adversary_Volcanic_Dragon__Ashen_Tyrant_pMuXGCSOQaxpi5tb.json index 3bcdd49a..6f3d436e 100644 --- a/src/packs/adversaries/adversary_Volcanic_Dragon__Ashen_Tyrant_pMuXGCSOQaxpi5tb.json +++ b/src/packs/adversaries/adversary_Volcanic_Dragon__Ashen_Tyrant_pMuXGCSOQaxpi5tb.json @@ -614,7 +614,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "AXhSVGL33i0j6DAw", "img": "icons/creatures/abilities/tail-swipe-green.webp", @@ -669,7 +670,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "ggCol5LQ2ZpeQjly", "img": "icons/magic/air/fog-gas-smoke-brown.webp", @@ -819,7 +821,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "uWiyaJPXcoW06pOM", "img": "icons/creatures/abilities/mouth-teeth-fire-orange.webp", diff --git a/src/packs/adversaries/adversary_Volcanic_Dragon__Molten_Scourge_eArAPuB38CNR0ZIM.json b/src/packs/adversaries/adversary_Volcanic_Dragon__Molten_Scourge_eArAPuB38CNR0ZIM.json index d04dab50..2fcc4ada 100644 --- a/src/packs/adversaries/adversary_Volcanic_Dragon__Molten_Scourge_eArAPuB38CNR0ZIM.json +++ b/src/packs/adversaries/adversary_Volcanic_Dragon__Molten_Scourge_eArAPuB38CNR0ZIM.json @@ -419,7 +419,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "bpjpHxf6tj4i3H4r", "img": "icons/creatures/abilities/tail-swipe-green.webp", @@ -518,7 +519,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "NuksKUrbf4yj4vR2", "img": "icons/magic/fire/blast-jet-stream-embers-red.webp", @@ -699,7 +701,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "2mK8kxfp2WBUeBri", "img": "icons/magic/fire/blast-jet-stream-embers-orange.webp", @@ -818,7 +821,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "3VdQdUDULZCQPvLZ", "img": "icons/magic/fire/blast-jet-stream-embers-red.webp", @@ -843,7 +847,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "qYFoyDSdZ5X2h245", "img": "icons/magic/fire/flame-burning-eye.webp", diff --git a/src/packs/adversaries/adversary_Volcanic_Dragon__Obsidian_Predator_ladm7wykhZczYzrQ.json b/src/packs/adversaries/adversary_Volcanic_Dragon__Obsidian_Predator_ladm7wykhZczYzrQ.json index 2be56990..1eb81b18 100644 --- a/src/packs/adversaries/adversary_Volcanic_Dragon__Obsidian_Predator_ladm7wykhZczYzrQ.json +++ b/src/packs/adversaries/adversary_Volcanic_Dragon__Obsidian_Predator_ladm7wykhZczYzrQ.json @@ -528,7 +528,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "8bMOItTuL7PfAYcJ", "img": "icons/creatures/abilities/tail-swipe-green.webp", @@ -716,7 +717,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "5wLxyaWJuUhkx1EX", "img": "icons/creatures/reptiles/dragon-winged-blue.webp", @@ -741,7 +743,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "5llfnRwO7mfzDFgT", "img": "icons/magic/fire/flame-burning-eye.webp", diff --git a/src/packs/adversaries/adversary_War_Wizard_noDdT0tsN6FXSmC8.json b/src/packs/adversaries/adversary_War_Wizard_noDdT0tsN6FXSmC8.json index fcb3dc5a..efe20210 100644 --- a/src/packs/adversaries/adversary_War_Wizard_noDdT0tsN6FXSmC8.json +++ b/src/packs/adversaries/adversary_War_Wizard_noDdT0tsN6FXSmC8.json @@ -320,7 +320,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "dI2MGjC7NFAru1Gd", "img": "icons/magic/defensive/shield-barrier-blades-teal.webp", @@ -426,7 +427,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "PnQ0m0FLnpht7oE4", "img": "icons/magic/earth/barrier-stone-explosion-red.webp", @@ -532,7 +534,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "s2luvEVxJLZmOrdh", "img": "icons/magic/light/projectiles-trio-pink.webp", @@ -565,7 +568,7 @@ "actionType": "action", "cost": [], "uses": { - "value": null, + "value": 0, "max": "1", "recovery": null }, @@ -611,7 +614,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "9cPigHRcUfJC9gD8", "img": "icons/magic/defensive/barrier-shield-dome-blue-purple.webp", diff --git a/src/packs/adversaries/adversary_Weaponmaster_ZNbQ2jg35LG4t9eH.json b/src/packs/adversaries/adversary_Weaponmaster_ZNbQ2jg35LG4t9eH.json index d1d936e1..6319c895 100644 --- a/src/packs/adversaries/adversary_Weaponmaster_ZNbQ2jg35LG4t9eH.json +++ b/src/packs/adversaries/adversary_Weaponmaster_ZNbQ2jg35LG4t9eH.json @@ -306,7 +306,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { @@ -484,7 +485,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -580,7 +582,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Young_Dryad_8yUj2Mzvnifhxegm.json b/src/packs/adversaries/adversary_Young_Dryad_8yUj2Mzvnifhxegm.json index 80fb7ce2..9cfb1884 100644 --- a/src/packs/adversaries/adversary_Young_Dryad_8yUj2Mzvnifhxegm.json +++ b/src/packs/adversaries/adversary_Young_Dryad_8yUj2Mzvnifhxegm.json @@ -287,7 +287,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [], "folder": null, @@ -348,7 +349,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "effects": [ { @@ -483,7 +485,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/adversaries/adversary_Young_Ice_Dragon_UGPiPLJsPvMTSKEF.json b/src/packs/adversaries/adversary_Young_Ice_Dragon_UGPiPLJsPvMTSKEF.json index 28c00c51..f025f45f 100644 --- a/src/packs/adversaries/adversary_Young_Ice_Dragon_UGPiPLJsPvMTSKEF.json +++ b/src/packs/adversaries/adversary_Young_Ice_Dragon_UGPiPLJsPvMTSKEF.json @@ -477,7 +477,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "QV2ytK4b1VWF71OS", "img": "icons/magic/water/projectiles-ice-faceted-shard-salvo-blue.webp", @@ -600,7 +601,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "CcRTxCDCJskiu3fI", "img": "icons/magic/water/barrier-ice-wall-snow.webp", @@ -722,7 +724,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "nXZHOfcYvjg3YMNU", "img": "icons/commodities/leather/scales-blue.webp", @@ -861,7 +864,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "QHdJgT2fvwqquyf7", "img": "icons/skills/melee/strike-weapons-orange.webp", diff --git a/src/packs/adversaries/adversary_Zombie_Legion_YhJrP7rTBiRdX5Fp.json b/src/packs/adversaries/adversary_Zombie_Legion_YhJrP7rTBiRdX5Fp.json index a67dda37..0650319b 100644 --- a/src/packs/adversaries/adversary_Zombie_Legion_YhJrP7rTBiRdX5Fp.json +++ b/src/packs/adversaries/adversary_Zombie_Legion_YhJrP7rTBiRdX5Fp.json @@ -406,7 +406,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "d5Vilu9cUub1O6TD", "img": "icons/skills/melee/strike-slashes-orange.webp", diff --git a/src/packs/adversaries/adversary_Zombie_Pack_Nf0v43rtflV56V2T.json b/src/packs/adversaries/adversary_Zombie_Pack_Nf0v43rtflV56V2T.json index 9b8a118d..3e94c738 100644 --- a/src/packs/adversaries/adversary_Zombie_Pack_Nf0v43rtflV56V2T.json +++ b/src/packs/adversaries/adversary_Zombie_Pack_Nf0v43rtflV56V2T.json @@ -283,7 +283,8 @@ }, "originItemType": null, "subType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "effects": [], "folder": null, diff --git a/src/packs/environments/environment_Abandoned_Grove_pGEdzdLkqYtBhxnG.json b/src/packs/environments/environment_Abandoned_Grove_pGEdzdLkqYtBhxnG.json index 4d9be4f8..c1006da4 100644 --- a/src/packs/environments/environment_Abandoned_Grove_pGEdzdLkqYtBhxnG.json +++ b/src/packs/environments/environment_Abandoned_Grove_pGEdzdLkqYtBhxnG.json @@ -49,7 +49,7 @@ "width": 1, "height": 1, "texture": { - "src": "AbominationVaults.webp", + "src": "systems/daggerheart/assets/icons/documents/actors/forest.svg", "anchorX": 0.5, "anchorY": 0.5, "offsetX": 0, @@ -67,10 +67,10 @@ "disposition": -1, "displayBars": 0, "bar1": { - "attribute": "resources.hitPoints" + "attribute": null }, "bar2": { - "attribute": "resources.stress" + "attribute": null }, "light": { "negative": false, @@ -118,7 +118,7 @@ "ring": null, "background": null }, - "effects": 1, + "effects": 0, "subject": { "scale": 1, "texture": null @@ -249,7 +249,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "maK5OyfrOxcjCoPt", "img": "icons/magic/nature/root-vine-spiral-thorns-teal.webp", @@ -313,7 +314,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "uG5A2XQuUcPsXzgP", "img": "icons/magic/nature/hand-weapon-wood-bark-brown.webp", @@ -361,7 +363,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "3kkkbnWEvXk5TPK8", "img": "icons/magic/unholy/strike-hand-glow-pink.webp", diff --git a/src/packs/environments/environment_Ambushed_uGEdNYERCTJBEjc5.json b/src/packs/environments/environment_Ambushed_uGEdNYERCTJBEjc5.json index b32128dd..b0ccd435 100644 --- a/src/packs/environments/environment_Ambushed_uGEdNYERCTJBEjc5.json +++ b/src/packs/environments/environment_Ambushed_uGEdNYERCTJBEjc5.json @@ -221,7 +221,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "HfuVxgVidIVsapvI", "img": "icons/magic/perception/shadow-stealth-eyes-purple.webp", diff --git a/src/packs/environments/environment_Ambushers_uXZpebPR77YQ1oXI.json b/src/packs/environments/environment_Ambushers_uXZpebPR77YQ1oXI.json index ed40af4a..e8ba889a 100644 --- a/src/packs/environments/environment_Ambushers_uXZpebPR77YQ1oXI.json +++ b/src/packs/environments/environment_Ambushers_uXZpebPR77YQ1oXI.json @@ -183,7 +183,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "b6Qviz1ANG8OrAYq", "img": "icons/skills/wounds/injury-face-impact-orange.webp", 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 39070236..dc42fb07 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 @@ -252,7 +252,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "1aOeMMX0XuDtZbbB", "img": "icons/magic/nature/root-vine-spiral-thorns-teal.webp", @@ -391,7 +392,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "JKFkDvwUOP35Tsr1", "img": "icons/creatures/magical/construct-face-stone-pink.webp", @@ -508,7 +510,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "kYxuTZjH7HDUGeWh", "img": "icons/magic/air/fog-gas-smoke-brown.webp", diff --git a/src/packs/environments/environment_Bustling_Marketplace_HZKA7hkej7JJY503.json b/src/packs/environments/environment_Bustling_Marketplace_HZKA7hkej7JJY503.json index b0b5b591..ad96108b 100644 --- a/src/packs/environments/environment_Bustling_Marketplace_HZKA7hkej7JJY503.json +++ b/src/packs/environments/environment_Bustling_Marketplace_HZKA7hkej7JJY503.json @@ -168,7 +168,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "60uDqt9omFifZ7xd", "img": "icons/commodities/treasure/brooch-jeweled-pink.webp", @@ -291,7 +292,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "56qjiKMoN6S9riI6", "img": "icons/skills/social/theft-pickpocket-bribery-brown.webp", @@ -316,7 +318,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "l2FzZpR2reVmlkdp", "img": "icons/skills/movement/arrow-upward-blue.webp", diff --git a/src/packs/environments/environment_Castle_Siege_1eZ32Esq7rfZOjlu.json b/src/packs/environments/environment_Castle_Siege_1eZ32Esq7rfZOjlu.json index 80344b0f..411a10c7 100644 --- a/src/packs/environments/environment_Castle_Siege_1eZ32Esq7rfZOjlu.json +++ b/src/packs/environments/environment_Castle_Siege_1eZ32Esq7rfZOjlu.json @@ -277,7 +277,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "eSTq8Y0v4Dwd13XU", "img": "icons/weapons/artillery/catapult-simple.webp", @@ -302,7 +303,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "U59K0WKVjwbgzMZU", "img": "icons/environment/people/charge.webp", @@ -401,7 +403,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "bemKmwjBtbEFVWXM", "img": "icons/magic/earth/projectile-stone-boulder-brown.webp", diff --git a/src/packs/environments/environment_Chaos_Realm_2Z1mKc65LxNk2PqR.json b/src/packs/environments/environment_Chaos_Realm_2Z1mKc65LxNk2PqR.json index 9ceca2a6..77781de0 100644 --- a/src/packs/environments/environment_Chaos_Realm_2Z1mKc65LxNk2PqR.json +++ b/src/packs/environments/environment_Chaos_Realm_2Z1mKc65LxNk2PqR.json @@ -335,7 +335,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "0OYHJZqT0DlVz5be", "img": "icons/magic/control/sihouette-hold-beam-green.webp", @@ -441,7 +442,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "RNbAdBZM6gDNaRPn", "img": "icons/magic/unholy/energy-smoke-pink.webp", @@ -496,7 +498,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "SZpUJeJETVQtZwae", "img": "icons/creatures/unholy/demons-horned-glowing-pink.webp", @@ -574,7 +577,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "MyIh4CJsDnkjmeYs", "img": "icons/magic/perception/hand-eye-pink.webp", diff --git a/src/packs/environments/environment_Cliffside_Ascent_LPpfdlNKqiZIl04w.json b/src/packs/environments/environment_Cliffside_Ascent_LPpfdlNKqiZIl04w.json index e72ac02e..548cf7c4 100644 --- a/src/packs/environments/environment_Cliffside_Ascent_LPpfdlNKqiZIl04w.json +++ b/src/packs/environments/environment_Cliffside_Ascent_LPpfdlNKqiZIl04w.json @@ -462,7 +462,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "EP4FXeQqbqFGQoIX", "img": "icons/skills/movement/arrow-down-pink.webp", diff --git a/src/packs/environments/environment_Cult_Ritual_QAXXiOKBDmCTauHD.json b/src/packs/environments/environment_Cult_Ritual_QAXXiOKBDmCTauHD.json index 80074b2e..705c9585 100644 --- a/src/packs/environments/environment_Cult_Ritual_QAXXiOKBDmCTauHD.json +++ b/src/packs/environments/environment_Cult_Ritual_QAXXiOKBDmCTauHD.json @@ -195,7 +195,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "0Rgqw1kUPeJ11ldd", "img": "icons/magic/unholy/orb-swirling-teal.webp", @@ -370,7 +371,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "oFfu3hUhp4ta4qwT", "img": "icons/magic/unholy/barrier-fire-pink.webp", @@ -395,7 +397,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "WltEUhtYwfnX8WCc", "img": "icons/skills/wounds/blood-drip-droplet-red.webp", diff --git a/src/packs/environments/environment_Divine_Usurpation_4DLYez7VbMCFDAuZ.json b/src/packs/environments/environment_Divine_Usurpation_4DLYez7VbMCFDAuZ.json index ada17126..aacf87e9 100644 --- a/src/packs/environments/environment_Divine_Usurpation_4DLYez7VbMCFDAuZ.json +++ b/src/packs/environments/environment_Divine_Usurpation_4DLYez7VbMCFDAuZ.json @@ -279,7 +279,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "OWUM3eFiZrIn0Bjd", "img": "icons/magic/unholy/orb-hands-pink.webp", @@ -384,7 +385,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "CL3wPZNOtw6m5WVT", "img": "icons/magic/unholy/hand-light-pink.webp", @@ -561,7 +563,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "AJdG1krRvixBFCZG", "img": "icons/magic/unholy/silhouette-robe-evil-glow.webp", @@ -638,7 +641,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "GUAo44cJCnS1GE9p", "img": "icons/magic/unholy/barrier-fire-pink.webp", diff --git a/src/packs/environments/environment_Hallowed_Temple_dsA6j69AnaJhUyqH.json b/src/packs/environments/environment_Hallowed_Temple_dsA6j69AnaJhUyqH.json index 342039be..f005fa59 100644 --- a/src/packs/environments/environment_Hallowed_Temple_dsA6j69AnaJhUyqH.json +++ b/src/packs/environments/environment_Hallowed_Temple_dsA6j69AnaJhUyqH.json @@ -226,7 +226,7 @@ "name": "Divine Guidance", "type": "feature", "system": { - "description": "

A PC who prays to a deity while in the Hallowed Temple can make an Instinct Roll to receive answers. If the god they beseech isn’t welcome in this temple, the roll is made with disadvantage.

What does it feel like as you are touched by this vision? What feeling lingers after the images have passed?
", + "description": "

A PC who prays to a deity while in the Hallowed Temple can make an Instinct Roll to receive answers. If the god they beseech isn’t welcome in this temple, the roll is made with disadvantage.

What does it feel like as you are touched by this vision? What feeling lingers after the images have passed?

", "resource": null, "actions": {}, "originItemType": null, @@ -308,7 +308,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "vICfHK2urDQ2Jm8s", "img": "icons/magic/holy/barrier-shield-winged-blue.webp", @@ -363,7 +364,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "8tGAuFRyM4onvQ2o", "img": "icons/magic/holy/projectiles-blades-salvo-yellow.webp", diff --git a/src/packs/environments/environment_Haunted_City_OzYbizKraK92FDiI.json b/src/packs/environments/environment_Haunted_City_OzYbizKraK92FDiI.json index 30a436bd..1bd07a57 100644 --- a/src/packs/environments/environment_Haunted_City_OzYbizKraK92FDiI.json +++ b/src/packs/environments/environment_Haunted_City_OzYbizKraK92FDiI.json @@ -259,7 +259,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "ZA2RzxH5FlnrcYLN", "img": "icons/magic/death/undead-ghosts-trio-blue.webp", @@ -331,7 +332,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "i0FV2Djaq0vB57cq", "img": "icons/magic/death/skull-weapon-staff-glow-pink.webp", diff --git a/src/packs/environments/environment_Imperial_Court_jr1xAoXzVwVblzxI.json b/src/packs/environments/environment_Imperial_Court_jr1xAoXzVwVblzxI.json index 5af29dd0..4b49c341 100644 --- a/src/packs/environments/environment_Imperial_Court_jr1xAoXzVwVblzxI.json +++ b/src/packs/environments/environment_Imperial_Court_jr1xAoXzVwVblzxI.json @@ -268,7 +268,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "tm9FL5gJF7Oheu21", "img": "icons/magic/death/skull-energy-light-white.webp", @@ -340,7 +341,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "HwSKX5r40ux0OfJN", "img": "icons/sundries/documents/document-sealed-red-white.webp", @@ -419,7 +421,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "YPMgWUagVq1Hicqo", "img": "icons/magic/perception/orb-eye-scrying.webp", diff --git a/src/packs/environments/environment_Local_Tavern_cM4X81DOyvxNIi52.json b/src/packs/environments/environment_Local_Tavern_cM4X81DOyvxNIi52.json index 8ff4d3b5..105f230f 100644 --- a/src/packs/environments/environment_Local_Tavern_cM4X81DOyvxNIi52.json +++ b/src/packs/environments/environment_Local_Tavern_cM4X81DOyvxNIi52.json @@ -201,7 +201,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "cAbSo5VQHxJqJPKm", "img": "icons/magic/unholy/silhouette-robe-evil-power.webp", @@ -222,11 +223,12 @@ "name": "Someone Comes to Town", "type": "feature", "system": { - "description": "

Introduce a signifi cant NPC who wants to hire the party for something or who relates to a PC’s background.

Did they know the PCs were here? What do they want in this town?

", + "description": "

Introduce a significant NPC who wants to hire the party for something or who relates to a PC’s background.

Did they know the PCs were here? What do they want in this town?

", "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "QPezCAC18vIc5xRC", "img": "icons/environment/people/commoner.webp", @@ -303,7 +305,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "H3LNvVrUbsAkgjni", "img": "icons/skills/melee/unarmed-punch-fist-white.webp", diff --git a/src/packs/environments/environment_Mountain_Pass_acMu9wJrMZZzLSTJ.json b/src/packs/environments/environment_Mountain_Pass_acMu9wJrMZZzLSTJ.json index 3be39fc8..8e7cf1c8 100644 --- a/src/packs/environments/environment_Mountain_Pass_acMu9wJrMZZzLSTJ.json +++ b/src/packs/environments/environment_Mountain_Pass_acMu9wJrMZZzLSTJ.json @@ -222,7 +222,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "jkm03DXYYajsRk2j", "img": "icons/magic/earth/projectile-boulder-dust.webp", @@ -247,7 +248,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "hkZVEduCWJFR0h2S", "img": "icons/creatures/birds/corvid-flying-wings-purple.webp", @@ -382,7 +384,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "K8ld4m5yTA6WZwUs", "img": "icons/magic/water/snowflake-ice-blue-white.webp", diff --git a/src/packs/environments/environment_Necromancer_s_Ossuary_h3KyRL7AshhLAmcH.json b/src/packs/environments/environment_Necromancer_s_Ossuary_h3KyRL7AshhLAmcH.json index 1cb43050..e96b9177 100644 --- a/src/packs/environments/environment_Necromancer_s_Ossuary_h3KyRL7AshhLAmcH.json +++ b/src/packs/environments/environment_Necromancer_s_Ossuary_h3KyRL7AshhLAmcH.json @@ -311,7 +311,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "asSGMUdf4gG4PO8F", "img": "icons/magic/death/bones-crossed-gray.webp", @@ -383,7 +384,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "mnpqMpYCjdlwtvBp", "img": "icons/magic/death/skull-weapon-staff-glow-pink.webp", @@ -438,7 +440,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "chJRXNg5zyTGbcG5", "img": "icons/magic/death/undead-zombie-grave-green.webp", diff --git a/src/packs/environments/environment_Outpost_Town_YezryR32uo39xRxW.json b/src/packs/environments/environment_Outpost_Town_YezryR32uo39xRxW.json index d0f4eae2..bc3c211d 100644 --- a/src/packs/environments/environment_Outpost_Town_YezryR32uo39xRxW.json +++ b/src/packs/environments/environment_Outpost_Town_YezryR32uo39xRxW.json @@ -222,7 +222,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "uxu8YrvYVxP3Qc2y", "img": "icons/skills/melee/unarmed-punch-fist-yellow-red.webp", @@ -277,7 +278,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "reaction" }, "_id": "21tdueq5Wgvj3vG4", "img": "icons/environment/settlement/watchtower-moonlit-blue.webp", diff --git a/src/packs/environments/environment_Pitched_Battle_EWD3ZsLoK6VMVOf7.json b/src/packs/environments/environment_Pitched_Battle_EWD3ZsLoK6VMVOf7.json index 36e21f82..7be27924 100644 --- a/src/packs/environments/environment_Pitched_Battle_EWD3ZsLoK6VMVOf7.json +++ b/src/packs/environments/environment_Pitched_Battle_EWD3ZsLoK6VMVOf7.json @@ -172,7 +172,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "fnvOiHKsd34EaLqG", "img": "icons/magic/fire/flame-burning-building.webp", @@ -278,7 +279,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "r9kkodHghWm01mje", "img": "icons/magic/fire/explosion-flame-lightning-strike.webp", @@ -303,7 +305,8 @@ "resource": null, "actions": {}, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "ZAIvH5CfhehW48EY", "img": "icons/environment/people/charge.webp", diff --git a/src/packs/environments/environment_Raging_River_t4cdqTfzcqP3H1vJ.json b/src/packs/environments/environment_Raging_River_t4cdqTfzcqP3H1vJ.json index 40dbb1c6..5c973fa6 100644 --- a/src/packs/environments/environment_Raging_River_t4cdqTfzcqP3H1vJ.json +++ b/src/packs/environments/environment_Raging_River_t4cdqTfzcqP3H1vJ.json @@ -296,7 +296,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "WsNoSwwtv0r80BMj", "img": "icons/magic/water/wave-water-teal.webp", @@ -390,7 +391,8 @@ } }, "originItemType": null, - "originId": null + "originId": null, + "featureForm": "action" }, "_id": "SDTS3LOPMVJOt1S1", "img": "icons/creatures/reptiles/snake-fangs-bite-green-yellow.webp", diff --git a/templates/sheets-settings/action-settings/base.hbs b/templates/sheets-settings/action-settings/base.hbs index 69b5dfce..65010903 100644 --- a/templates/sheets-settings/action-settings/base.hbs +++ b/templates/sheets-settings/action-settings/base.hbs @@ -7,7 +7,6 @@ {{localize "DAGGERHEART.GENERAL.identify"}} {{formField fields.name value=source.name label="Name" name="name"}} {{formField fields.img value=source.img label="Icon" name="img"}} - {{formField fields.actionType value=source.actionType label="Type" name="actionType" localize=true}} {{formField fields.chatDisplay value=source.chatDisplay name="chatDisplay" classes="checkbox" localize=true}}
diff --git a/templates/sheets/global/partials/inventory-item-V2.hbs b/templates/sheets/global/partials/inventory-item-V2.hbs index cd9626e3..daf12132 100644 --- a/templates/sheets/global/partials/inventory-item-V2.hbs +++ b/templates/sheets/global/partials/inventory-item-V2.hbs @@ -49,6 +49,19 @@ Parameters: {{tag}} {{/each}} + + {{!-- Feature Form Tag Start --}} + {{#if (eq ../type 'feature')}} + {{#if (or (eq @root.document.type 'adversary') (eq @root.document.type 'environment'))}} + {{#if system.featureForm}} +
+ {{localize (concat "DAGGERHEART.CONFIG.FeatureForm." system.featureForm)}} +
+ {{/if}} + {{/if}} + {{/if}} + {{!-- Feature Form Tag End --}} + {{/if}} {{/with}} @@ -145,10 +158,12 @@ Parameters:
{{#if (and (eq action.type 'beastform') @root.beastformActive)}} {{else}} {{/if}} diff --git a/templates/sheets/global/partials/inventory-item.hbs b/templates/sheets/global/partials/inventory-item.hbs index b239e226..d69b0abb 100644 --- a/templates/sheets/global/partials/inventory-item.hbs +++ b/templates/sheets/global/partials/inventory-item.hbs @@ -67,6 +67,21 @@
{{/if}} {{/if}} + + + {{#if (eq type 'feature')}} + {{#if (or (eq @root.document.type 'adversary') (eq @root.document.type 'environment'))}} + {{#if item.system.featureForm}} +
+
+ {{localize "DAGGERHEART.CONFIG.FeatureForm.label"}}: + {{localize (concat "DAGGERHEART.CONFIG.FeatureForm." item.system.featureForm)}} +
+
+ {{/if}} + {{/if}} + {{/if}} + {{#if (eq type 'domainCard')}} {{#if isSidebar}}
diff --git a/templates/sheets/items/feature/header.hbs b/templates/sheets/items/feature/header.hbs index e603c0f7..efaba77b 100755 --- a/templates/sheets/items/feature/header.hbs +++ b/templates/sheets/items/feature/header.hbs @@ -4,7 +4,7 @@

-

{{localize 'TYPES.Item.feature'}}

+

{{localize (concat 'DAGGERHEART.CONFIG.FeatureForm.' source.system.featureForm)}} {{localize 'TYPES.Item.feature'}}

\ No newline at end of file diff --git a/templates/sheets/items/feature/settings.hbs b/templates/sheets/items/feature/settings.hbs index c2ecb3fe..63aa9502 100644 --- a/templates/sheets/items/feature/settings.hbs +++ b/templates/sheets/items/feature/settings.hbs @@ -3,5 +3,12 @@ data-tab='{{tabs.settings.id}}' data-group='{{tabs.settings.group}}' > + {{#if (or (eq document.parent.type "adversary") (eq document.parent.type "environment"))}} +
+ {{localize "DAGGERHEART.GENERAL.general"}} + {{localize "DAGGERHEART.CONFIG.FeatureForm.label"}} + {{formInput document.system.schema.fields.featureForm value=document.system.featureForm choices=featureFormChoices localize=true}} +
+ {{/if}} {{> "systems/daggerheart/templates/sheets/global/partials/resource-section/resource-section.hbs" }} \ No newline at end of file From 605a23ab58d4c7c711e89504fb25193c767ad5db Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Sat, 20 Dec 2025 15:25:51 -0500 Subject: [PATCH 02/17] Fix invalid form control is not focusable error on gold fields (#1451) --- module/applications/sheets/api/application-mixin.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index 619305f1..d25a1a4e 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -183,7 +183,6 @@ export default function DHApplicationMixin(Base) { for (const deltaInput of htmlElement.querySelectorAll('input[data-allow-delta]')) { deltaInput.dataset.numValue = deltaInput.value; deltaInput.inputMode = 'numeric'; - deltaInput.pattern = '^[+=\\-]?\d*'; const handleUpdate = (delta = 0) => { const min = Number(deltaInput.min) || 0; From 0508bf4188097294ffe960a1aa4feed5e1369b7c Mon Sep 17 00:00:00 2001 From: Nick Salyzyn Date: Sat, 20 Dec 2025 14:00:16 -0700 Subject: [PATCH 03/17] [PR] Removing refreshables the user doesn't have during rest actions (#1449) * Marking up the places that need changing for bug #1160 * Creating a shared method called isItemAvailable and using it in downtime * Explicitely adding the false value rather than relying on undefined returns. Oops * Removing spaces * Removing a needless return line * Adding missing semicolon --- module/applications/dialogs/downtime.mjs | 2 +- module/data/actor/base.mjs | 12 +++++++ module/data/actor/character.mjs | 45 ++++++++++++++++-------- module/documents/activeEffect.mjs | 25 +++---------- 4 files changed, 47 insertions(+), 37 deletions(-) diff --git a/module/applications/dialogs/downtime.mjs b/module/applications/dialogs/downtime.mjs index 96e06446..3d5b7f0f 100644 --- a/module/applications/dialogs/downtime.mjs +++ b/module/applications/dialogs/downtime.mjs @@ -93,7 +93,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV } getRefreshables() { - const actionItems = this.actor.items.reduce((acc, x) => { + const actionItems = this.actor.items.filter(x => this.actor.system.isItemAvailable(x)).reduce((acc, x) => { if (x.system.actions) { const recoverable = x.system.actions.reduce((acc, action) => { if (refreshIsAllowed([this.shortrest ? 'shortRest' : 'longRest'], action.uses.recovery)) { diff --git a/module/data/actor/base.mjs b/module/data/actor/base.mjs index c7f7ee75..f3662da2 100644 --- a/module/data/actor/base.mjs +++ b/module/data/actor/base.mjs @@ -1,4 +1,5 @@ import DHBaseActorSettings from '../../applications/sheets/api/actor-setting.mjs'; +import DHItem from '../../documents/item.mjs'; import { getScrollTextData } from '../../helpers/utils.mjs'; const resistanceField = (resistanceLabel, immunityLabel, reductionLabel) => @@ -106,6 +107,17 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel { return data; } + /** + * Checks if an item is available for use, such as multiclass features being disabled + * on a character. + * + * @param {DHItem} item The item being checked for availability + * @return {boolean} whether the item is available + */ + isItemAvailable(item) { + return true; + } + async _preDelete() { /* Clear all partyMembers from tagTeam setting.*/ /* Revisit this when tagTeam is improved for many parties */ diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index c5ab914c..5bce5c55 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -435,6 +435,34 @@ export default class DhCharacter extends BaseDataActor { return attack; } + /** @inheritDoc */ + isItemAvailable(item) { + if (!super.isItemAvailable(this)) return false; + /** + * Preventing subclass features from being available if the chacaracter does not + * have the right subclass advancement + */ + if (item.system.originItemType !== CONFIG.DH.ITEM.featureTypes.subclass.id) { + return true; + } + if (!this.class.subclass) return false; + + const prop = item.system.multiclassOrigin ? 'multiclass' : 'class'; + const subclassState = this[prop].subclass?.system?.featureState; + if (!subclassState) return false; + + if ( + item.system.identifier === CONFIG.DH.ITEM.featureSubTypes.foundation || + (item.system.identifier === CONFIG.DH.ITEM.featureSubTypes.specialization && + subclassState >= 2) || + (item.system.identifier === CONFIG.DH.ITEM.featureSubTypes.mastery && subclassState >= 3) + ) { + return true; + } else { + return false; + } + } + get sheetLists() { const ancestryFeatures = [], communityFeatures = [], @@ -443,7 +471,7 @@ export default class DhCharacter extends BaseDataActor { companionFeatures = [], features = []; - for (let item of this.parent.items) { + for (let item of this.parent.items.filter(x => this.isItemAvailable(x))) { if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.ancestry.id) { ancestryFeatures.push(item); } else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.community.id) { @@ -451,20 +479,7 @@ export default class DhCharacter extends BaseDataActor { } else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.class.id) { classFeatures.push(item); } else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.subclass.id) { - if (this.class.subclass) { - const prop = item.system.multiclassOrigin ? 'multiclass' : 'class'; - const subclassState = this[prop].subclass?.system?.featureState; - if (!subclassState) continue; - - if ( - item.system.identifier === CONFIG.DH.ITEM.featureSubTypes.foundation || - (item.system.identifier === CONFIG.DH.ITEM.featureSubTypes.specialization && - subclassState >= 2) || - (item.system.identifier === CONFIG.DH.ITEM.featureSubTypes.mastery && subclassState >= 3) - ) { - subclassFeatures.push(item); - } - } + subclassFeatures.push(item); } else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.companion.id) { companionFeatures.push(item); } else if (item.type === 'feature' && !item.system.type) { diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index fcf1d590..2297ea27 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -194,27 +194,10 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect { } prepareDerivedData() { - /* Preventing subclass features from transferring to actor if they do not have the right subclass advancement */ - if (this.parent?.type === 'feature') { - const origSubclassParent = this.parent.system.originItemType === 'subclass'; - if (origSubclassParent) { - const subclass = this.parent.parent.items.find( - x => - x.type === 'subclass' && - x.system.isMulticlass === (this.parent.system.identifier === 'multiclass') - ); - - if (subclass) { - const featureState = subclass.system.featureState; - - if ( - (this.parent.system.identifier === CONFIG.DH.ITEM.featureSubTypes.specialization && - featureState < 2) || - (this.parent.system.identifier === CONFIG.DH.ITEM.featureSubTypes.mastery && featureState < 3) - ) { - this.transfer = false; - } - } + /* Check for item availability such as in the case of subclass advancement. */ + if (this.parent?.parent?.system?.isItemAvailable) { + if (!this.parent.parent.system.isItemAvailable(this.parent)) { + this.transfer = false; } } } From 9cfa206adc156eda75ea994f9f883c5009bff11a Mon Sep 17 00:00:00 2001 From: Nick Salyzyn Date: Sat, 20 Dec 2025 14:56:22 -0700 Subject: [PATCH 04/17] [PR] Checking for empty data in renderChatMessageHTML calls (#1452) --- daggerheart.mjs | 4 ++-- module/applications/ui/chatLog.mjs | 17 +++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/daggerheart.mjs b/daggerheart.mjs index 644d6d86..eeed29dc 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -193,9 +193,9 @@ Hooks.on('ready', async () => { Hooks.once('dicesoniceready', () => {}); -Hooks.on('renderChatMessageHTML', (_, element, message) => { +Hooks.on('renderChatMessageHTML', (document, element) => { enricherRenderSetup(element); - const cssClass = message.message.flags?.daggerheart?.cssClass; + const cssClass = document.flags?.daggerheart?.cssClass; if (cssClass) cssClass.split(' ').forEach(cls => element.classList.add(cls)); }); diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 47dfe500..45d9c0b3 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -55,27 +55,28 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo ]; } - addChatListeners = async (app, html, data) => { + addChatListeners = async (document, html, data) => { + const message = data?.message ?? document.toObject(false); html.querySelectorAll('.simple-roll-button').forEach(element => - element.addEventListener('click', event => this.onRollSimple(event, data.message)) + element.addEventListener('click', event => this.onRollSimple(event, message)) ); html.querySelectorAll('.ability-use-button').forEach(element => - element.addEventListener('click', event => this.abilityUseButton(event, data.message)) + element.addEventListener('click', event => this.abilityUseButton(event, message)) ); html.querySelectorAll('.action-use-button').forEach(element => - element.addEventListener('click', event => this.actionUseButton(event, data.message)) + element.addEventListener('click', event => this.actionUseButton(event, message)) ); html.querySelectorAll('.reroll-button').forEach(element => - element.addEventListener('click', event => this.rerollEvent(event, data.message)) + element.addEventListener('click', event => this.rerollEvent(event, message)) ); html.querySelectorAll('.group-roll-button').forEach(element => - element.addEventListener('click', event => this.groupRollButton(event, data.message)) + element.addEventListener('click', event => this.groupRollButton(event, message)) ); html.querySelectorAll('.group-roll-reroll').forEach(element => - element.addEventListener('click', event => this.groupRollReroll(event, data.message)) + element.addEventListener('click', event => this.groupRollReroll(event, message)) ); html.querySelectorAll('.group-roll-success').forEach(element => - element.addEventListener('click', event => this.groupRollSuccessEvent(event, data.message)) + element.addEventListener('click', event => this.groupRollSuccessEvent(event, message)) ); html.querySelectorAll('.group-roll-header-expand-section').forEach(element => element.addEventListener('click', this.groupRollExpandSection) From 148c9c019a30ceca242d0b4c10cdd5a0dd85f4cb Mon Sep 17 00:00:00 2001 From: Nick Salyzyn Date: Sat, 20 Dec 2025 15:04:36 -0700 Subject: [PATCH 05/17] [PR] Use the token name in the chat message targets window (#1441) --- module/data/fields/action/targetField.mjs | 2 +- templates/ui/chat/parts/target-part.hbs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module/data/fields/action/targetField.mjs b/module/data/fields/action/targetField.mjs index 41383fea..73766118 100644 --- a/module/data/fields/action/targetField.mjs +++ b/module/data/fields/action/targetField.mjs @@ -79,7 +79,7 @@ export default class TargetField extends fields.SchemaField { return { id: token.id, actorId: token.actor.uuid, - name: token.actor.name, + name: token.name, img: token.actor.img, difficulty: token.actor.system.difficulty, evasion: token.actor.system.evasion, diff --git a/templates/ui/chat/parts/target-part.hbs b/templates/ui/chat/parts/target-part.hbs index 7c777fdb..477445a3 100644 --- a/templates/ui/chat/parts/target-part.hbs +++ b/templates/ui/chat/parts/target-part.hbs @@ -29,7 +29,7 @@
-
{{name}}
+
{{name}}
{{#if (and ../hasRoll (hasProperty this "hit"))}}
{{#if hit}} From fe80b4d0f882ea1408cf26ece015f321cbc7685f Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Sat, 20 Dec 2025 17:08:24 -0500 Subject: [PATCH 06/17] [PR] [Feature] Refocus consumable quantity and simple resource fields on change (#1401) * Refocus quantity and simple resource fields on change * Swap to uuid --- templates/sheets/global/partials/inventory-item-V2.hbs | 2 +- templates/sheets/global/partials/item-resource.hbs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/sheets/global/partials/inventory-item-V2.hbs b/templates/sheets/global/partials/inventory-item-V2.hbs index daf12132..91f8d581 100644 --- a/templates/sheets/global/partials/inventory-item-V2.hbs +++ b/templates/sheets/global/partials/inventory-item-V2.hbs @@ -74,7 +74,7 @@ Parameters: {{/if}} {{#if (and (not hideResources) (gte item.system.quantity 0))}}
- +
{{/if}} diff --git a/templates/sheets/global/partials/item-resource.hbs b/templates/sheets/global/partials/item-resource.hbs index def153ea..fbcf02ca 100644 --- a/templates/sheets/global/partials/item-resource.hbs +++ b/templates/sheets/global/partials/item-resource.hbs @@ -1,7 +1,7 @@ {{#if (eq item.system.resource.type 'simple')}}
- +
{{else if (eq item.system.resource.type 'diceValue')}}
From b8e08fccd104d6a378b4c9fd4ad9fa808ccf39dc Mon Sep 17 00:00:00 2001 From: Nick Salyzyn Date: Sat, 20 Dec 2025 15:14:23 -0700 Subject: [PATCH 07/17] [PR] Removing a potential reference error when creating a tag team roll (#1430) --- module/applications/dialogs/tagTeamDialog.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/applications/dialogs/tagTeamDialog.mjs b/module/applications/dialogs/tagTeamDialog.mjs index b53d03ab..0bc4bf0c 100644 --- a/module/applications/dialogs/tagTeamDialog.mjs +++ b/module/applications/dialogs/tagTeamDialog.mjs @@ -220,8 +220,8 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio !roll.system.isCritical && criticalRoll ? (await getCritDamageBonus(damage.formula)) + damage.total : damage.total; + const updatedDamageParts = damage.parts; if (systemData.damage[key]) { - const updatedDamageParts = damage.parts; if (!roll.system.isCritical && criticalRoll) { for (let part of updatedDamageParts) { const criticalDamage = await getCritDamageBonus(part.formula); From f786ee5f06168b014aa09b971f337ddd5fe3d1e8 Mon Sep 17 00:00:00 2001 From: WBHarry Date: Sun, 21 Dec 2025 15:39:05 +0100 Subject: [PATCH 08/17] Fixed actionType constants --- module/applications/dialogs/d20RollDialog.mjs | 6 +-- module/dice/dhRoll.mjs | 38 +++++++++---------- module/dice/dualityRoll.mjs | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/module/applications/dialogs/d20RollDialog.mjs b/module/applications/dialogs/d20RollDialog.mjs index b28a3ffb..5ef9e005 100644 --- a/module/applications/dialogs/d20RollDialog.mjs +++ b/module/applications/dialogs/d20RollDialog.mjs @@ -195,9 +195,9 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio if (this.config.roll) { this.reactionOverride = !this.reactionOverride; this.config.actionType = this.reactionOverride - ? CONFIG.DH.ITEM.actionTypes.reaction.id - : this.config.actionType === CONFIG.DH.ITEM.actionTypes.reaction.id - ? CONFIG.DH.ITEM.actionTypes.action.id + ? 'reaction' + : this.config.actionType === 'reaction' + ? 'action' : this.config.actionType; this.render(); } diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index ce39ed6a..ec289941 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -240,11 +240,13 @@ export default class DHRoll extends Roll { async function automateHopeFear(config) { const automationSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); const hopeFearAutomation = automationSettings.hopeFear; - if (!config.source?.actor || + if ( + !config.source?.actor || (game.user.isGM ? !hopeFearAutomation.gm : !hopeFearAutomation.players) || config.actionType === 'reaction' || config.tagTeamSelected || - config.skips?.resources) + config.skips?.resources + ) return; const actor = await fromUuid(config.source.actor); let updates = []; @@ -252,26 +254,22 @@ async function automateHopeFear(config) { if (config.rerolledRoll) { if (config.roll.result.duality != config.rerolledRoll.result.duality) { - const hope = (config.roll.isCritical || config.roll.result.duality === 1 ? 1 : 0) - - (config.rerolledRoll.isCritical || config.rerolledRoll.result.duality === 1 ? 1 : 0); + const hope = + (config.roll.isCritical || config.roll.result.duality === 1 ? 1 : 0) - + (config.rerolledRoll.isCritical || config.rerolledRoll.result.duality === 1 ? 1 : 0); const stress = (config.roll.isCritical ? 1 : 0) - (config.rerolledRoll.isCritical ? 1 : 0); - const fear = (config.roll.result.duality === -1 ? 1 : 0) - - (config.rerolledRoll.result.duality === -1 ? 1 : 0) + const fear = + (config.roll.result.duality === -1 ? 1 : 0) - (config.rerolledRoll.result.duality === -1 ? 1 : 0); - if (hope !== 0) - updates.push({ key: 'hope', value: hope, total: -1 * hope, enabled: true }); - if (stress !== 0) - updates.push({ key: 'stress', value: -1 * stress, total: stress, enabled: true }); - if (fear !== 0) - updates.push({ key: 'fear', value: fear, total: -1 * fear, enabled: true }); + if (hope !== 0) updates.push({ key: 'hope', value: hope, total: -1 * hope, enabled: true }); + if (stress !== 0) updates.push({ key: 'stress', value: -1 * stress, total: stress, enabled: true }); + if (fear !== 0) updates.push({ key: 'fear', value: fear, total: -1 * fear, enabled: true }); } } else { if (config.roll.isCritical || config.roll.result.duality === 1) updates.push({ key: 'hope', value: 1, total: -1, enabled: true }); - if (config.roll.isCritical) - updates.push({ key: 'stress', value: -1, total: 1, enabled: true }); - if (config.roll.result.duality === -1) - updates.push({ key: 'fear', value: 1, total: -1, enabled: true }); + if (config.roll.isCritical) updates.push({ key: 'stress', value: -1, total: 1, enabled: true }); + if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1, total: -1, enabled: true }); } if (updates.length) { @@ -287,15 +285,17 @@ export const registerRollDiceHooks = () => { const automationSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); if ( automationSettings.countdownAutomation && - config.actionType !== CONFIG.DH.ITEM.actionTypes.reaction.id && + config.actionType !== 'reaction' && !config.tagTeamSelected && !config.skips?.updateCountdowns ) { const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns; if (config.roll.result.duality === -1) { - await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.actionRoll.id, - CONFIG.DH.GENERAL.countdownProgressionTypes.fear.id); + await updateCountdowns( + CONFIG.DH.GENERAL.countdownProgressionTypes.actionRoll.id, + CONFIG.DH.GENERAL.countdownProgressionTypes.fear.id + ); } else { await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.actionRoll.id); } diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index 59cb6e02..4d305c6c 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -19,7 +19,7 @@ export default class DualityRoll extends D20Roll { get title() { return game.i18n.localize( - `DAGGERHEART.GENERAL.${this.options?.actionType === CONFIG.DH.ITEM.actionTypes.reaction.id ? 'reactionRoll' : 'dualityRoll'}` + `DAGGERHEART.GENERAL.${this.options?.actionType === 'reaction' ? 'reactionRoll' : 'dualityRoll'}` ); } From 99d0eab5bdaea6a431807def45353f55c777c6c9 Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Sun, 21 Dec 2025 11:37:00 -0500 Subject: [PATCH 09/17] [PR] [Feature] Support drag dropping currencies to actor sheets (#1431) * Support drag dropping currencies to actor sheets * Adjust sizing and spacing * Restore ItemTransferDialog subclass for module use * Bigger is better --- module/applications/dialogs/itemTransfer.mjs | 62 ++++++++----------- module/applications/sheets/api/base-actor.mjs | 50 ++++++++++++--- styles/less/dialog/item-transfer/sheet.less | 43 ++++++++----- templates/dialogs/item-transfer.hbs | 31 +++++++--- .../sheets/actors/character/inventory.hbs | 6 +- templates/sheets/actors/party/inventory.hbs | 6 +- 6 files changed, 128 insertions(+), 70 deletions(-) diff --git a/module/applications/dialogs/itemTransfer.mjs b/module/applications/dialogs/itemTransfer.mjs index aba43d27..ad3cf103 100644 --- a/module/applications/dialogs/itemTransfer.mjs +++ b/module/applications/dialogs/itemTransfer.mjs @@ -1,69 +1,61 @@ const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; export default class ItemTransferDialog extends HandlebarsApplicationMixin(ApplicationV2) { - constructor(item) { + constructor(data) { super({}); - - this.item = item; - this.quantity = item.system.quantity; + this.data = data; } get title() { - return this.item.name; + return this.data.title; } static DEFAULT_OPTIONS = { tag: 'form', classes: ['daggerheart', 'dh-style', 'dialog', 'item-transfer'], - position: { width: 300, height: 'auto' }, + position: { width: 400, height: 'auto' }, window: { icon: 'fa-solid fa-hand-holding-hand' }, actions: { finish: ItemTransferDialog.#finish - }, - form: { handler: this.updateData, submitOnChange: true, closeOnSubmit: false } + } }; static PARTS = { - main: { template: 'systems/daggerheart/templates/dialogs/item-transfer.hbs' } + main: { template: 'systems/daggerheart/templates/dialogs/item-transfer.hbs', root: true } }; - _attachPartListeners(partId, htmlElement, options) { - super._attachPartListeners(partId, htmlElement, options); - - htmlElement.querySelector('.number-display').addEventListener('change', event => { - this.quantity = isNaN(event.target.value) ? this.quantity : Number(event.target.value); - this.render(); - }); - } - async _prepareContext(_options) { const context = await super._prepareContext(_options); - context.item = this.item; - context.quantity = this.quantity; - - return context; - } - - static async updateData(_event, _element, formData) { - const { quantity } = foundry.utils.expandObject(formData.object); - this.quantity = quantity; - this.render(); + return foundry.utils.mergeObject(context, this.data); } static async #finish() { - this.close({ submitted: true }); + this.selected = this.form.elements.quantity.valueAsNumber || null; + this.close(); } - close(options = {}) { - if (!options.submitted) this.quantity = null; + static #determineTransferOptions({ originActor, targetActor, item, currency }) { + originActor ??= item?.actor; + const homebrewKey = CONFIG.DH.SETTINGS.gameSettings.Homebrew; + const currencySetting = game.settings.get(CONFIG.DH.id, homebrewKey).currency?.[currency] ?? null; - super.close(); + return { + originActor, + targetActor, + itemImage: item?.img, + currencyIcon: currencySetting?.icon, + max: item?.system.quantity ?? originActor.system.gold[currency] ?? 0, + title: item?.name ?? currencySetting?.label + }; } - static async configure(item) { + static async configure(options) { return new Promise(resolve => { - const app = new this(item); - app.addEventListener('close', () => resolve(app.quantity), { once: true }); + const data = this.#determineTransferOptions(options); + if (data.max <= 1) return resolve(data.max); + + const app = new this(data); + app.addEventListener('close', () => resolve(app.selected), { once: true }); app.render({ force: true }); }); } diff --git a/module/applications/sheets/api/base-actor.mjs b/module/applications/sheets/api/base-actor.mjs index adb0d39a..5d054949 100644 --- a/module/applications/sheets/api/base-actor.mjs +++ b/module/applications/sheets/api/base-actor.mjs @@ -34,7 +34,10 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { } } ], - dragDrop: [{ dragSelector: '.inventory-item[data-type="attack"]', dropSelector: null }] + dragDrop: [ + { dragSelector: '.inventory-item[data-type="attack"]', dropSelector: null }, + { dragSelector: ".currency[data-currency] .drag-handle", dropSelector: null } + ] }; /* -------------------------------------------- */ @@ -254,14 +257,35 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { /* Application Drag/Drop */ /* -------------------------------------------- */ + async _onDrop(event) { + event.stopPropagation(); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); + if (data.type === 'Currency' && ['character', 'party'].includes(this.document.type)) { + const originActor = await foundry.utils.fromUuid(data.originActor); + if (!originActor || originActor.uuid === this.document.uuid) return; + const currency = data.currency; + const quantity = await game.system.api.applications.dialogs.ItemTransferDialog.configure({ + originActor, + targetActor: this.document, + currency + }); + if (quantity) { + originActor.update({ [`system.gold.${currency}`]: Math.max(0, originActor.system.gold[currency] - quantity) }); + this.document.update({ [`system.gold.${currency}`]: this.document.system.gold[currency] + quantity }); + } + return; + } + + return super._onDrop(event); + } + async _onDropItem(event, item) { const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); - const physicalActorTypes = ['character', 'party']; const originActor = item.actor; if ( item.actor?.uuid === this.document.uuid || !originActor || - !physicalActorTypes.includes(this.document.type) + !['character', 'party'].includes(this.document.type) ) { return super._onDropItem(event, item); } @@ -270,10 +294,10 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { if (item.system.metadata.isInventoryItem) { if (item.system.metadata.isQuantifiable) { const actorItem = originActor.items.get(data.originId); - const quantityTransfered = - actorItem.system.quantity === 1 - ? 1 - : await game.system.api.applications.dialogs.ItemTransferDialog.configure(item); + const quantityTransfered = await game.system.api.applications.dialogs.ItemTransferDialog.configure({ + item, + targetActor: this.document + }); if (quantityTransfered) { if (quantityTransfered === actorItem.system.quantity) { @@ -314,6 +338,16 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { * @param {DragEvent} event - The drag event */ async _onDragStart(event) { + // Handle drag/dropping currencies + const currencyEl = event.currentTarget.closest(".currency[data-currency]"); + if (currencyEl) { + const currency = currencyEl.dataset.currency; + const data = { type: 'Currency', currency, originActor: this.document.uuid }; + event.dataTransfer.setData('text/plain', JSON.stringify(data)); + return; + } + + // Handle drag/dropping attacks const attackItem = event.currentTarget.closest('.inventory-item[data-type="attack"]'); if (attackItem) { const attackData = { @@ -340,4 +374,4 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { super._onDragStart(event); } -} +} \ No newline at end of file diff --git a/styles/less/dialog/item-transfer/sheet.less b/styles/less/dialog/item-transfer/sheet.less index dd55fdb2..7807e479 100644 --- a/styles/less/dialog/item-transfer/sheet.less +++ b/styles/less/dialog/item-transfer/sheet.less @@ -1,20 +1,35 @@ .daggerheart.dh-style.dialog.item-transfer { - .item-transfer-container { - display: grid; - grid-template-columns: 1fr 42px; - gap: 4px; + .summary { + display: flex; + align-items: center; + justify-content: center; + gap: 3rem; + + .actor-img { + border-radius: 50%; + width: 5rem; + height: 5rem; + object-fit: cover; + object-position: top center; + } - .number-display { - text-align: center; + .granted-item { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: var(--font-size-32); + + img { + width: 2rem; + height: 2rem; + object-fit: contain; + border-radius: 3px; + } } } - - .item-sheet-footer { - padding-top: 8px; - display: flex; - - button { - flex: 1; - } + label { + flex: 0; + margin-right: 0.5rem; } } diff --git a/templates/dialogs/item-transfer.hbs b/templates/dialogs/item-transfer.hbs index 2b9fa19c..0e7df3dc 100644 --- a/templates/dialogs/item-transfer.hbs +++ b/templates/dialogs/item-transfer.hbs @@ -1,9 +1,26 @@ -
-
- - +
+
+ +
+ {{#if itemImage}} + + {{else}} + + {{/if}} + +
+
-
- -
+
+ +
+ +
+
+
+
+
\ No newline at end of file diff --git a/templates/sheets/actors/character/inventory.hbs b/templates/sheets/actors/character/inventory.hbs index f9dee872..a05fed35 100644 --- a/templates/sheets/actors/character/inventory.hbs +++ b/templates/sheets/actors/character/inventory.hbs @@ -14,10 +14,10 @@ {{#if this.inventory.hasCurrency}}
- {{#each this.inventory.currencies as | currency |}} + {{#each this.inventory.currencies as |currency key|}} {{#if currency.enabled}} -
- +
+ {{localize currency.label}} diff --git a/templates/sheets/actors/party/inventory.hbs b/templates/sheets/actors/party/inventory.hbs index 09f3ba62..92371b8d 100644 --- a/templates/sheets/actors/party/inventory.hbs +++ b/templates/sheets/actors/party/inventory.hbs @@ -17,10 +17,10 @@ {{#if inventory.hasCurrency}}
- {{#each this.inventory.currencies as | currency |}} + {{#each this.inventory.currencies as |currency key|}} {{#if currency.enabled}} -
- +
+ {{localize currency.label}} From e8dd38fbfa4330c18062ef771a313d58c2f89c8d Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Mon, 22 Dec 2025 07:48:03 -0500 Subject: [PATCH 10/17] [PR] [Feature] Refresh actors when a homebrew setting is changed (#1382) * Refresh actors when a homebrew setting is changed * Newline at end of file * Close open prosemirror documents during reset --- module/systemRegistration/settings.mjs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/module/systemRegistration/settings.mjs b/module/systemRegistration/settings.mjs index d08d65d1..46aa2a84 100644 --- a/module/systemRegistration/settings.mjs +++ b/module/systemRegistration/settings.mjs @@ -46,6 +46,9 @@ const registerMenuSettings = () => { if (value.maxFear) { if (ui.resources) ui.resources.render({ force: true }); } + + // Some homebrew settings may change sheets in various ways, so trigger a re-render + resetActors(); } }); @@ -140,3 +143,25 @@ const registerNonConfigSettings = () => { type: DhTagTeamRoll }); }; + +/** + * Triggers a reset and non-forced re-render on all given actors (if given) + * or all world actors and actors in all scenes to show immediate results for a changed setting. + */ +function resetActors(actors) { + actors ??= [ + game.actors.contents, + game.scenes.contents.flatMap(s => s.tokens.contents).flatMap(t => t.actor ?? []) + ].flat(); + actors = new Set(actors); + for (const actor of actors) { + for (const app of Object.values(actor.apps)) { + for (const element of app.element?.querySelectorAll('prose-mirror.active')) { + element.open = false; // This triggers a save + } + } + + actor.reset(); + actor.render(); + } +} From 659f73116a2e0748fab6666589dd6428d7084f74 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Mon, 22 Dec 2025 13:56:49 +0100 Subject: [PATCH 11/17] [Fix] 1453 - Async Resource Generation Errors (#1454) * Fixed so that we do not run separate actor.modifyResource calls during actions and dice rolls * . * Simplified resourcemap --- daggerheart.mjs | 2 - .../applications/sheets/actors/character.mjs | 15 ++- module/data/action/baseAction.mjs | 47 ++++++++- module/data/fields/action/costField.mjs | 2 +- module/dice/dhRoll.mjs | 78 --------------- module/dice/dualityRoll.mjs | 96 ++++++++++++++++++- module/documents/actor.mjs | 9 +- 7 files changed, 153 insertions(+), 96 deletions(-) diff --git a/daggerheart.mjs b/daggerheart.mjs index eeed29dc..f1fe602e 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -17,7 +17,6 @@ import { socketRegistration } from './module/systemRegistration/_module.mjs'; import { placeables } from './module/canvas/_module.mjs'; -import { registerRollDiceHooks } from './module/dice/dhRoll.mjs'; import './node_modules/@yaireo/tagify/dist/tagify.css'; import TemplateManager from './module/documents/templateManager.mjs'; @@ -177,7 +176,6 @@ Hooks.on('ready', async () => { ui.compendiumBrowser = new applications.ui.ItemBrowser(); socketRegistration.registerSocketHooks(); - registerRollDiceHooks(); socketRegistration.registerUserQueries(); if (!game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.userFlags.welcomeMessage)) { diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 953a0cf6..51df2fc9 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -675,16 +675,21 @@ export default class CharacterSheet extends DHBaseActorSheet { roll: { trait: button.dataset.attribute }, - hasRoll: true - }; - const result = await this.document.diceRoll({ - ...config, + hasRoll: true, actionType: 'action', headerTitle: `${game.i18n.localize('DAGGERHEART.GENERAL.dualityRoll')}: ${this.actor.name}`, title: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { ability: abilityLabel }) - }); + }; + const result = await this.document.diceRoll(config); + + /* This could be avoided by baking config.costs into config.resourceUpdates. Didn't feel like messing with it at the time */ + const costResources = result.costs + .filter(x => x.enabled) + .map(cost => ({ ...cost, value: -cost.value, total: -cost.total })); + config.resourceUpdates.addResources(costResources); + await config.resourceUpdates.updateResources(); } //TODO: redo toggleEquipItem method diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index b15d6c4e..998fe0ab 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -206,6 +206,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel // Execute the Action Worflow in order based of schema fields await this.executeWorkflow(config); + await config.resourceUpdates.updateResources(); if (Hooks.call(`${CONFIG.DH.id}.postUseAction`, this, config) === false) return; @@ -239,8 +240,10 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel isDirect: !!this.damage?.direct, selectedRollMode: game.settings.get('core', 'rollMode'), data: this.getRollData(), - evaluate: this.hasRoll + evaluate: this.hasRoll, + resourceUpdates: new ResourceUpdateMap(this.actor) }; + DHBaseAction.applyKeybindings(config); return config; } @@ -322,10 +325,46 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel * @returns {string[]} An array of localized tag strings. */ _getTags() { - const tags = [ - game.i18n.localize(`DAGGERHEART.ACTIONS.TYPES.${this.type}.name`), - ]; + const tags = [game.i18n.localize(`DAGGERHEART.ACTIONS.TYPES.${this.type}.name`)]; return tags; } } + +export class ResourceUpdateMap extends Map { + #actor; + + constructor(actor) { + super(); + + this.#actor = actor; + } + + addResources(resources) { + for (const resource of resources) { + if (!resource.key) continue; + + const existing = this.get(resource.key); + if (existing) { + this.set(resource.key, { + ...existing, + value: existing.value + (resource.value ?? 0), + total: existing.total + (resource.total ?? 0) + }); + } else { + this.set(resource.key, resource); + } + } + } + + #getResources() { + return Array.from(this.values()); + } + + async updateResources() { + if (this.#actor) { + const target = this.#actor.system.partner ?? this.#actor; + await target.modifyResource(this.#getResources()); + } + } +} diff --git a/module/data/fields/action/costField.mjs b/module/data/fields/action/costField.mjs index 656edee3..9271f6b0 100644 --- a/module/data/fields/action/costField.mjs +++ b/module/data/fields/action/costField.mjs @@ -75,7 +75,7 @@ export default class CostField extends fields.ArrayField { } }, []); - await actor.modifyResource(resources); + config.resourceUpdates.addResources(resources); } /** diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index ec289941..ea24f238 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -236,81 +236,3 @@ export default class DHRoll extends Roll { return {}; } } - -async function automateHopeFear(config) { - const automationSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); - const hopeFearAutomation = automationSettings.hopeFear; - if ( - !config.source?.actor || - (game.user.isGM ? !hopeFearAutomation.gm : !hopeFearAutomation.players) || - config.actionType === 'reaction' || - config.tagTeamSelected || - config.skips?.resources - ) - return; - const actor = await fromUuid(config.source.actor); - let updates = []; - if (!actor) return; - - if (config.rerolledRoll) { - if (config.roll.result.duality != config.rerolledRoll.result.duality) { - const hope = - (config.roll.isCritical || config.roll.result.duality === 1 ? 1 : 0) - - (config.rerolledRoll.isCritical || config.rerolledRoll.result.duality === 1 ? 1 : 0); - const stress = (config.roll.isCritical ? 1 : 0) - (config.rerolledRoll.isCritical ? 1 : 0); - const fear = - (config.roll.result.duality === -1 ? 1 : 0) - (config.rerolledRoll.result.duality === -1 ? 1 : 0); - - if (hope !== 0) updates.push({ key: 'hope', value: hope, total: -1 * hope, enabled: true }); - if (stress !== 0) updates.push({ key: 'stress', value: -1 * stress, total: stress, enabled: true }); - if (fear !== 0) updates.push({ key: 'fear', value: fear, total: -1 * fear, enabled: true }); - } - } else { - if (config.roll.isCritical || config.roll.result.duality === 1) - updates.push({ key: 'hope', value: 1, total: -1, enabled: true }); - if (config.roll.isCritical) updates.push({ key: 'stress', value: -1, total: 1, enabled: true }); - if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1, total: -1, enabled: true }); - } - - if (updates.length) { - const target = actor.system.partner ?? actor; - if (!['dead', 'defeated', 'unconscious'].some(x => actor.statuses.has(x))) { - await target.modifyResource(updates); - } - } -} - -export const registerRollDiceHooks = () => { - Hooks.on(`${CONFIG.DH.id}.postRollDuality`, async (config, message) => { - const automationSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); - if ( - automationSettings.countdownAutomation && - config.actionType !== 'reaction' && - !config.tagTeamSelected && - !config.skips?.updateCountdowns - ) { - const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns; - - if (config.roll.result.duality === -1) { - await updateCountdowns( - CONFIG.DH.GENERAL.countdownProgressionTypes.actionRoll.id, - CONFIG.DH.GENERAL.countdownProgressionTypes.fear.id - ); - } else { - await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.actionRoll.id); - } - } - - await automateHopeFear(config); - - if (!config.roll.hasOwnProperty('success') && !config.targets?.length) return; - - const rollResult = config.roll.success || config.targets.some(t => t.hit), - looseSpotlight = !rollResult || config.roll.result.duality === -1; - - if (looseSpotlight && game.combat?.active) { - const currentCombatant = game.combat.combatants.get(game.combat.current?.combatantId); - if (currentCombatant?.actorId == actor.id) ui.combat.setCombatantSpotlight(currentCombatant.id); - } - }); -}; diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index 4d305c6c..3b00dd7c 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -2,6 +2,7 @@ import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs'; import D20Roll from './d20Roll.mjs'; import { setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs'; import { getDiceSoNicePresets } from '../config/generalConfig.mjs'; +import { ResourceUpdateMap } from '../data/action/baseAction.mjs'; export default class DualityRoll extends D20Roll { _advantageFaces = 6; @@ -219,6 +220,88 @@ export default class DualityRoll extends D20Roll { return data; } + static async buildPost(roll, config, message) { + await super.buildPost(roll, config, message); + + await DualityRoll.dualityUpdate(config); + } + + static async addDualityResourceUpdates(config) { + const automationSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); + const hopeFearAutomation = automationSettings.hopeFear; + if ( + !config.source?.actor || + (game.user.isGM ? !hopeFearAutomation.gm : !hopeFearAutomation.players) || + config.actionType === 'reaction' || + config.tagTeamSelected || + config.skips?.resources + ) + return; + const actor = await fromUuid(config.source.actor); + let updates = []; + if (!actor) return; + + if (config.rerolledRoll) { + if (config.roll.result.duality != config.rerolledRoll.result.duality) { + const hope = + (config.roll.isCritical || config.roll.result.duality === 1 ? 1 : 0) - + (config.rerolledRoll.isCritical || config.rerolledRoll.result.duality === 1 ? 1 : 0); + const stress = (config.roll.isCritical ? 1 : 0) - (config.rerolledRoll.isCritical ? 1 : 0); + const fear = + (config.roll.result.duality === -1 ? 1 : 0) - (config.rerolledRoll.result.duality === -1 ? 1 : 0); + + if (hope !== 0) updates.push({ key: 'hope', value: hope, total: -1 * hope, enabled: true }); + if (stress !== 0) updates.push({ key: 'stress', value: -1 * stress, total: stress, enabled: true }); + if (fear !== 0) updates.push({ key: 'fear', value: fear, total: -1 * fear, enabled: true }); + } + } else { + if (config.roll.isCritical || config.roll.result.duality === 1) + updates.push({ key: 'hope', value: 1, total: -1, enabled: true }); + if (config.roll.isCritical) updates.push({ key: 'stress', value: -1, total: 1, enabled: true }); + if (config.roll.result.duality === -1) updates.push({ key: 'fear', value: 1, total: -1, enabled: true }); + } + + if (updates.length) { + // const target = actor.system.partner ?? actor; + if (!['dead', 'defeated', 'unconscious'].some(x => actor.statuses.has(x))) { + config.resourceUpdates.addResources(updates); + } + } + } + + static async dualityUpdate(config) { + const automationSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); + if ( + automationSettings.countdownAutomation && + config.actionType !== 'reaction' && + !config.tagTeamSelected && + !config.skips?.updateCountdowns + ) { + const { updateCountdowns } = game.system.api.applications.ui.DhCountdowns; + + if (config.roll.result.duality === -1) { + await updateCountdowns( + CONFIG.DH.GENERAL.countdownProgressionTypes.actionRoll.id, + CONFIG.DH.GENERAL.countdownProgressionTypes.fear.id + ); + } else { + await updateCountdowns(CONFIG.DH.GENERAL.countdownProgressionTypes.actionRoll.id); + } + } + + await DualityRoll.addDualityResourceUpdates(config); + + if (!config.roll.hasOwnProperty('success') && !config.targets?.length) return; + + const rollResult = config.roll.success || config.targets.some(t => t.hit), + looseSpotlight = !rollResult || config.roll.result.duality === -1; + + if (looseSpotlight && game.combat?.active) { + const currentCombatant = game.combat.combatants.get(game.combat.current?.combatantId); + if (currentCombatant?.actorId == actor.id) ui.combat.setCombatantSpotlight(currentCombatant.id); + } + } + static async reroll(rollString, target, message) { let parsedRoll = game.system.api.dice.DualityRoll.fromData({ ...rollString, evaluated: false }); const term = parsedRoll.terms[target.dataset.dieIndex]; @@ -257,13 +340,20 @@ export default class DualityRoll extends D20Roll { newRoll.extra = newRoll.extra.slice(2); const tagTeamSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll); - Hooks.call(`${CONFIG.DH.id}.postRollDuality`, { + + const actor = message.system.source.actor ? await foundry.utils.fromUuid(message.system.source.actor) : null; + const config = { source: { actor: message.system.source.actor ?? '' }, targets: message.system.targets, tagTeamSelected: Object.values(tagTeamSettings.members).some(x => x.messageId === message._id), roll: newRoll, - rerolledRoll: message.system.roll - }); + rerolledRoll: message.system.roll, + resourceUpdates: new ResourceUpdateMap(actor) + }; + + await DualityRoll.addDualityResourceUpdates(config); + await config.resourceUpdates.updateResources(); + return { newRoll, parsedRoll }; } } diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 35ab5cc6..3e1a9eca 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -3,6 +3,7 @@ import { LevelOptionType } from '../data/levelTier.mjs'; import DHFeature from '../data/item/feature.mjs'; import { createScrollText, damageKeyToNumber } from '../helpers/utils.mjs'; import DhCompanionLevelUp from '../applications/levelup/companionLevelup.mjs'; +import { ResourceUpdateMap } from '../data/action/baseAction.mjs'; export default class DhpActor extends Actor { parties = new Set(); @@ -477,6 +478,7 @@ export default class DhpActor extends Actor { async diceRoll(config) { config.source = { ...(config.source ?? {}), actor: this.uuid }; config.data = this.getRollData(); + config.resourceUpdates = new ResourceUpdateMap(this); const rollClass = config.roll.lite ? CONFIG.Dice.daggerheart['DHRoll'] : this.rollClass; return await rollClass.build(config); } @@ -765,9 +767,10 @@ export default class DhpActor extends Actor { } convertDamageToThreshold(damage) { - const massiveDamageEnabled=game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).massiveDamage.enabled; - if (massiveDamageEnabled && damage >= (this.system.damageThresholds.severe * 2)) { - return 4; + const massiveDamageEnabled = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules) + .massiveDamage.enabled; + if (massiveDamageEnabled && damage >= this.system.damageThresholds.severe * 2) { + return 4; } return damage >= this.system.damageThresholds.severe ? 3 : damage >= this.system.damageThresholds.major ? 2 : 1; } From 16f6fa98a6985be0f608975ce72ec826b346c36f Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Mon, 22 Dec 2025 14:34:43 +0100 Subject: [PATCH 12/17] Fixed so that players rolling reactions will update the message (#1455) --- module/data/fields/actionField.mjs | 2 +- module/dice/dualityRoll.mjs | 2 +- module/systemRegistration/settings.mjs | 4 ++-- module/systemRegistration/socket.mjs | 11 +++++++---- templates/dialogs/dice-roll/header.hbs | 2 +- templates/sheets/global/partials/inventory-item.hbs | 4 ++-- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/module/data/fields/actionField.mjs b/module/data/fields/actionField.mjs index 2d968fe0..6257da38 100644 --- a/module/data/fields/actionField.mjs +++ b/module/data/fields/actionField.mjs @@ -262,7 +262,7 @@ export function ActionMixin(Base) { async toChat(origin) { const cls = getDocumentClass('ChatMessage'); const systemData = { - title: game.i18n.localize('DAGGERHEART.CONFIG.ActionType.action'), + title: game.i18n.localize('DAGGERHEART.CONFIG.FeatureForm.action'), origin: origin, action: { name: this.name, diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index 3b00dd7c..91c0a197 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -293,7 +293,7 @@ export default class DualityRoll extends D20Roll { if (!config.roll.hasOwnProperty('success') && !config.targets?.length) return; - const rollResult = config.roll.success || config.targets.some(t => t.hit), + const rollResult = config.roll.success || config.targets?.some(t => t.hit), looseSpotlight = !rollResult || config.roll.result.duality === -1; if (looseSpotlight && game.combat?.active) { diff --git a/module/systemRegistration/settings.mjs b/module/systemRegistration/settings.mjs index 46aa2a84..053325a8 100644 --- a/module/systemRegistration/settings.mjs +++ b/module/systemRegistration/settings.mjs @@ -21,8 +21,8 @@ export const registerDHSettings = () => { scope: 'world', config: true, type: Boolean, - onChange: () => ui.combat.render(), - }) + onChange: () => ui.combat.render() + }); }; const registerMenuSettings = () => { diff --git a/module/systemRegistration/socket.mjs b/module/systemRegistration/socket.mjs index 27bf48c5..046f1b68 100644 --- a/module/systemRegistration/socket.mjs +++ b/module/systemRegistration/socket.mjs @@ -73,10 +73,13 @@ export const registerSocketHooks = () => { Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.Countdown }); break; case GMUpdateEvent.UpdateSaveMessage: - const action = await fromUuid(data.update.action), - message = game.messages.get(data.update.message); - if (!action || !message) return; - action.updateSaveMessage(data.update.result, message, data.update.token); + const message = game.messages.get(data.update.message); + if (!message) return; + game.system.api.fields.ActionFields.SaveField.updateSaveMessage( + data.update.result, + message, + data.update.token + ); break; } diff --git a/templates/dialogs/dice-roll/header.hbs b/templates/dialogs/dice-roll/header.hbs index b2ca18cd..21967655 100644 --- a/templates/dialogs/dice-roll/header.hbs +++ b/templates/dialogs/dice-roll/header.hbs @@ -2,7 +2,7 @@

{{#if reactionOverride}} - {{localize "DAGGERHEART.CONFIG.ActionType.reaction"}} + {{localize "DAGGERHEART.CONFIG.FeatureForm.reaction"}} {{else}} {{ifThen rollConfig.headerTitle rollConfig.headerTitle rollConfig.title}} {{/if}} diff --git a/templates/sheets/global/partials/inventory-item.hbs b/templates/sheets/global/partials/inventory-item.hbs index d69b0abb..c2b2a241 100644 --- a/templates/sheets/global/partials/inventory-item.hbs +++ b/templates/sheets/global/partials/inventory-item.hbs @@ -136,7 +136,7 @@ {{localize (concat 'DAGGERHEART.ACTIONS.TYPES.' item.type '.name')}}

- {{localize (concat 'DAGGERHEART.CONFIG.ActionType.' item.actionType)}} + {{localize (concat 'DAGGERHEART.CONFIG.FeatureForm.' item.actionType)}}
{{/if}} @@ -146,7 +146,7 @@ {{localize 'DAGGERHEART.GENERAL.unarmed'}}
- {{localize 'DAGGERHEART.CONFIG.ActionType.action'}} + {{localize 'DAGGERHEART.CONFIG.FeatureForm.action'}}
{{/if}} From 7926c614e31193573a8ac96d6f6e20d3b857ae1e Mon Sep 17 00:00:00 2001 From: Nick Salyzyn Date: Mon, 22 Dec 2025 06:45:27 -0700 Subject: [PATCH 13/17] [PR] Updating the logic for rangeDependencies so that paired weapons work with multiple adversaries (#1434) * Include item effects when applying rangeDependence * Creating a new method to update range dependent effects that uses the players targets * Using debouncing to fix an issue with selected and unselecting targets * Using token destinations instead of their current location for calculation range --- daggerheart.mjs | 84 ++++++++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 33 deletions(-) diff --git a/daggerheart.mjs b/daggerheart.mjs index f1fe602e..acbffd38 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -246,52 +246,70 @@ Hooks.on('chatMessage', (_, message) => { } }); -Hooks.on('moveToken', async (movedToken, data) => { - const effectsAutomation = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).effects; - if (!effectsAutomation.rangeDependent) return; +const updateActorsRangeDependentEffects = async (token) => { + const rangeMeasurement = game.settings.get( + CONFIG.DH.id, + CONFIG.DH.SETTINGS.gameSettings.variantRules + ).rangeMeasurement; - const rangeDependantEffects = movedToken.actor.effects.filter(effect => effect.system.rangeDependence?.enabled); + for (let effect of token.actor.allApplicableEffects()) { + if (!effect.system.rangeDependence?.enabled) continue; + const { target, range, type } = effect.system.rangeDependence; - const updateEffects = async (disposition, token, effects, effectUpdates) => { - const rangeMeasurement = game.settings.get( - CONFIG.DH.id, - CONFIG.DH.SETTINGS.gameSettings.variantRules - ).rangeMeasurement; - - for (let effect of effects.filter(x => x.system.rangeDependence?.enabled)) { - const { target, range, type } = effect.system.rangeDependence; - if ((target === 'friendly' && disposition !== 1) || (target === 'hostile' && disposition !== -1)) - return false; + // If there are no targets, assume false. Otherwise, start with the effect enabled. + let enabledEffect = game.user.targets.size !== 0; + // Expect all targets to meet the rangeDependence requirements + for (let userTarget of game.user.targets) { + const disposition = userTarget.document.disposition; + if ((target === 'friendly' && disposition !== 1) || (target === 'hostile' && disposition !== -1)) { + enabledEffect = false; + break; + } const distanceBetween = canvas.grid.measurePath([ - { ...movedToken.toObject(), x: data.destination.x, y: data.destination.y }, - token + userTarget.document.movement.destination, + token.movement.destination ]).distance; const distance = rangeMeasurement[range]; const reverse = type === CONFIG.DH.GENERAL.rangeInclusion.outsideRange.id; - const newDisabled = reverse ? distanceBetween <= distance : distanceBetween > distance; - const oldDisabled = effectUpdates[effect.uuid] ? effectUpdates[effect.uuid].disabled : newDisabled; - effectUpdates[effect.uuid] = { - disabled: oldDisabled || newDisabled, - value: effect - }; - } - }; - - const effectUpdates = {}; - for (let token of game.scenes.find(x => x.active).tokens) { - if (token.id !== movedToken.id) { - await updateEffects(token.disposition, token, rangeDependantEffects, effectUpdates); + if (reverse ? distanceBetween <= distance : distanceBetween > distance) { + enabledEffect = false; + break; + } } - if (token.actor) await updateEffects(movedToken.disposition, token, token.actor.effects, effectUpdates); + await effect.update({ disabled: !enabledEffect }); } +} - for (let key in effectUpdates) { - const effect = effectUpdates[key]; - await effect.value.update({ disabled: effect.disabled }); +const updateAllRangeDependentEffects = async () => { + const effectsAutomation = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).effects; + if (!effectsAutomation.rangeDependent) return; + + // Only consider tokens on the active scene + const tokens = game.scenes.find(x => x.active).tokens; + if (game.user.character) { + // The character updates their character's token. There can be only one token. + const characterToken = tokens.find(x => x.actor === game.user.character); + updateActorsRangeDependentEffects(characterToken); + } else if (game.user.isGM) { + // The GM is responsible for all other tokens. + const playerCharacters = game.users.players.filter(x => x.active).map(x => x.character); + for (let token of tokens.filter(x => !playerCharacters.includes(x.actor))) { + updateActorsRangeDependentEffects(token); + } } +}; + +const debouncedRangeEffectCall = foundry.utils.debounce(updateAllRangeDependentEffects, 50); + +Hooks.on('targetToken', async (user, token, targeted) => { + debouncedRangeEffectCall(); +}); + +Hooks.on('moveToken', async (movedToken, data) => { + debouncedRangeEffectCall(); }); Hooks.on('renderCompendiumDirectory', (app, html) => applications.ui.ItemBrowser.injectSidebarButton(html)); From 8178fa57384f08403a30a053bcdd4f4fdf9cfc2a Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:58:53 +0100 Subject: [PATCH 14/17] [PR][Feature] Actor Sizes (#1433) * Added support for adversary actor sizes * . * . * Finished token implementation * Fixed token-config * Updated SRD adversaries * . * Added size to Beastform tokenData * Fixed sizing for evolved beastforms * Beastform compendium update * . --- daggerheart.mjs | 2 + lang/en.json | 20 +- .../settings/homebrewSettings.mjs | 9 + .../sheets-configs/prototype-token-config.mjs | 21 + .../sheets-configs/token-config.mjs | 21 + .../applications/sheets/items/beastform.mjs | 1 + .../sidebar/tabs/actorDirectory.mjs | 26 ++ module/config/actorConfig.mjs | 38 ++ module/data/activeEffect/beastformEffect.mjs | 38 +- module/data/actor/adversary.mjs | 5 +- module/data/actor/base.mjs | 10 +- module/data/actor/party.mjs | 2 +- module/data/fields/action/beastformField.mjs | 12 + module/data/item/beastform.mjs | 46 +- module/data/settings/Homebrew.mjs | 32 ++ module/documents/_module.mjs | 1 + module/documents/actor.mjs | 23 +- module/documents/scene.mjs | 40 ++ module/documents/token.mjs | 438 +++++++++++++++++- ...ersary_Acid_Burrower_89yAh30vaNQOALlz.json | 6 +- ...ary_Adult_Flickerfly_G7jiltRjgvVhZewm.json | 3 +- ..._Apprentice_Assassin_vNIbYQ4YSzNf0WPE.json | 3 +- ...ary_Arch_Necromancer_WPEOIGfclNJxWb87.json | 3 +- ...versary_Archer_Guard_JRhrrEg5UroURiAD.json | 6 +- ...sary_Archer_Squadron_0ts6CGd93lLqGZI5.json | 3 +- ...ry_Assassin_Poisoner_h5RuhzGL17dW5FBT.json | 3 +- ...adversary_Battle_Box_dgH3fW9FTYLaIDvS.json | 3 +- .../adversary_Bear_71qKDLKO3CsrNkdy.json | 3 +- ...versary_Bladed_Guard_B4LZcGuBAHzyVdzy.json | 3 +- ...ersary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json | 3 +- .../adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json | 3 +- ...dversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json | 3 +- .../adversary_Conscript_99TqczuQipBmaB8i.json | 3 +- .../adversary_Construct_uOP5oT9QzXPlnf3p.json | 3 +- .../adversary_Courtesan_ZxWaWPdzFIUPNC62.json | 3 +- .../adversary_Courtier_CBBuEXAlLKFMJdjg.json | 3 +- ...adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json | 3 +- .../adversary_Cult_Fang_tyBOpLfigAhI9bU3.json | 3 +- ...ersary_Cult_Initiate_zx99sOGTXicP4SSD.json | 3 +- ...ry_Deeproot_Defender_9x2xY9zwc3xzbXo5.json | 3 +- ...ary_Demon_of_Avarice_pnyjIGxxvurcWmTv.json | 3 +- ...ary_Demon_of_Despair_kE4dfhqmIQpNd44e.json | 3 +- ...sary_Demon_of_Hubris_2VN3BftageoTTIzu.json | 3 +- ...ry_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json | 3 +- ...rsary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json | 3 +- ...y_Demonic_Hound_Pack_NoRZ1PqB8N5wcIw0.json | 3 +- .../adversary_Dire_Bat_tBWHW00epmMnkawe.json | 3 +- .../adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json | 3 +- .../adversary_Dryad_wR7cFKrHvRzbzhBT.json | 3 +- ...ersary_Electric_Eels_TLzY1nDw0Bu9Ud40.json | 3 +- ...sary_Elemental_Spark_P7h54ZePFPHpYwvB.json | 3 +- ...ersary_Elite_Soldier_bfhVWMBUh61b9J6n.json | 3 +- ...ry_Failed_Experiment_ChwwVqowFw8hJQwT.json | 3 +- ...y_Fallen_Shock_Troop_OsLG2BjaEdTZUJU9.json | 3 +- ...sary_Fallen_Sorcerer_PELRry1vqjBzSAlr.json | 3 +- ...rlord__Realm_Breaker_hxZ0sgoFJubh5aj6.json | 3 +- ..._Undefeated_Champion_RXkZTwBRi4dJ3JE5.json | 3 +- ...ry_Giant_Beastmaster_8VZIgU12cB3cvlyH.json | 3 +- ...ersary_Giant_Brawler_YnObCleGjPT7yqEc.json | 3 +- ...dversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json | 3 +- ...ary_Giant_Mosquitoes_IIWV4ysJPFPnTP7W.json | 3 +- .../adversary_Giant_Rat_4PfLnaCrOcMdb4dK.json | 3 +- ...ersary_Giant_Recruit_5s8wSvpyC5rxY5aD.json | 3 +- ...rsary_Giant_Scorpion_fmfntuJ8mHRCAktP.json | 3 +- ...dversary_Glass_Snake_8KWVLWXFhlY2kYx0.json | 3 +- .../adversary_Gorgon_8mJYMpbLTb8qIOrr.json | 3 +- ...ater_Earth_Elemental_dsfB3YhoL5SudvS2.json | 3 +- ...ater_Water_Elemental_xIICT6tEdnA7dKDV.json | 3 +- ...adversary_Green_Ooze_SHXedd9zZPVfUgUa.json | 3 +- ...sary_Hallowed_Archer_kabueAo6BALApWqp.json | 3 +- ...ary_Hallowed_Soldier_VENwg7xEFcYObjmT.json | 3 +- .../adversary_Harrier_uRtghKE9mHlII4rs.json | 3 +- ...adversary_Head_Guard_mK3A5FTx6k8iPU3F.json | 3 +- ...versary_Head_Vampire_i2UNbRvgyoSs07M6.json | 3 +- ...dversary_High_Seraph_r1mbfSSwKWdcFdAU.json | 3 +- ...sary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json | 3 +- .../adversary_Hydra_MI126iMOOobQ1Obn.json | 3 +- ..._Jagged_Knife_Bandit_5Lh1T0zaT8Pkr2U2.json | 3 +- ...y_Jagged_Knife_Hexer_MbBPIOxaxXYNApXz.json | 3 +- ...ed_Knife_Kneebreaker_CBKixLH3yhivZZuL.json | 3 +- ..._Jagged_Knife_Lackey_C0OMQqV7pN6t7ouR.json | 3 +- ...ged_Knife_Lieutenant_aTljstqteGoLpCBq.json | 3 +- ..._Jagged_Knife_Shadow_XF4tYTq9nPJAy2ox.json | 3 +- ..._Jagged_Knife_Sniper_1zuyof1XuIfi3aMG.json | 3 +- ..._Juvenile_Flickerfly_MYXmTx2FHcIjdfYZ.json | 3 +- ..._Knight_of_the_Realm_7ai2opemrclQe3VF.json | 3 +- .../adversary_Kraken_4nqv3ZwJGjnmic8j.json | 3 +- ...versary_Masked_Thief_niBpVU7yeo5ccskE.json | 3 +- ...sary_Master_Assassin_dNta0cUzr96xcFhf.json | 3 +- .../adversary_Merchant_Al3w2CgjfdT3p9ma.json | 3 +- ...rsary_Merchant_Baron_Vy02IhGhkJLuezu4.json | 3 +- ...inor_Chaos_Elemental_sRn4bqerfARvhgSV.json | 3 +- ...dversary_Minor_Demon_3tqCjDwJAQ7JKqMb.json | 3 +- ...Minor_Fire_Elemental_DscWkNVoHak6P4hh.json | 3 +- ...versary_Minor_Treant_G62k4oSkhkoXEs2D.json | 3 +- ...ary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json | 3 +- .../adversary_Monarch_yx0vK2yfNVZKWUUi.json | 3 +- ...ersary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json | 3 +- ...adversary_Oak_Treant_XK78QUfY8c8Go8Uv.json | 3 +- ...rsary_Oracle_of_Doom_befIqd5IYKg6eUz2.json | 3 +- ...r_Realms_Abomination_A0SeeDzwjvqOsyof.json | 3 +- ...ter_Realms_Corrupter_ms6nuOl3NFkhPj1k.json | 3 +- ..._Outer_Realms_Thrall_moJhHgKqTKPS2WYS.json | 3 +- ...atchwork_Zombie_Hulk_EQTOAOUrkIvS2z88.json | 9 +- ...ary_Perfected_Zombie_CP6iRfHdyFWniTHY.json | 3 +- ...dversary_Petty_Noble_wycLpvebWdUqRhpP.json | 3 +- ...rsary_Pirate_Captain_OROJbjsqagVh7ECV.json | 3 +- ...rsary_Pirate_Raiders_5YgEajn0wa4i85kC.json | 3 +- ...versary_Pirate_Tough_mhcVkVFrzIJ18FDm.json | 3 +- .../adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json | 3 +- ...ersary_Rotted_Zombie_gP3fWTLzSFnpA8EJ.json | 3 +- ...ersary_Royal_Advisor_EtLJiTsilPPZvLUX.json | 3 +- ...ersary_Secret_Keeper_sLAccjvCWfeedbpI.json | 3 +- .../adversary_Sellsword_bgreCaQ6ap2DVpCr.json | 3 +- ...ary_Shambling_Zombie_2nXz4ilAY4xuhKLm.json | 3 +- .../adversary_Shark_YmVAkdNsyuXWTtYp.json | 3 +- .../adversary_Siren_BK4jwyXSRx7IOQiO.json | 3 +- ...sary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json | 3 +- ...sary_Skeleton_Dredge_6l1a3Fazq8BoKIcc.json | 3 +- ...sary_Skeleton_Knight_Q9LaVTyXF9NF12C7.json | 3 +- ...ary_Skeleton_Warrior_10YIQl0lvCJXZLfX.json | 3 +- ...sary_Spectral_Archer_5tCkhnBByUIN5UdG.json | 3 +- ...ary_Spectral_Captain_65cSO3EQEh6ZH6Xk.json | 3 +- ...ry_Spectral_Guardian_UFVGl1osOsJTneLf.json | 3 +- ...adversary_Spellblade_ldbWEL7uZs84vyrR.json | 3 +- .../adversary_Spy_8zlynOhnVA59KpKT.json | 3 +- ...dversary_Stag_Knight_KGVwnLq85ywP9xvB.json | 3 +- ...dversary_Stonewraith_3aAS2Qm3R6cgaYfE.json | 3 +- ...ersary_Swarm_of_Rats_qNgs3AbLyJrY19nt.json | 3 +- ...rsary_Sylvan_Soldier_VtFBt9XBE0WrGGxP.json | 3 +- ...Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json | 3 +- ...rsary_Tangle_Bramble_XcAGOSmtCFLT1unN.json | 3 +- ...sary_Tiny_Green_Ooze_aLkLFuVoKz2NLoBK.json | 3 +- ...ersary_Tiny_Red_Ooze_1fkLQXVtmILqfJ44.json | 3 +- ...rsary_Treant_Sapling_o63nS0k3wHu6EgKP.json | 6 +- .../adversary_Vampire_WWyUp6Mxl1S3KYUG.json | 3 +- ...ault_Guardian_Gaoler_JqYraOqNmmhHk4Yy.json | 3 +- ...lt_Guardian_Sentinel_FVgYb28fhxlVcGwA.json | 3 +- ...ault_Guardian_Turret_c5hGdvY5UnSjlHws.json | 3 +- ...Dragon__Ashen_Tyrant_pMuXGCSOQaxpi5tb.json | 3 +- ...agon__Molten_Scourge_eArAPuB38CNR0ZIM.json | 3 +- ...n__Obsidian_Predator_ladm7wykhZczYzrQ.json | 3 +- ...adversary_War_Wizard_noDdT0tsN6FXSmC8.json | 3 +- ...versary_Weaponmaster_ZNbQ2jg35LG4t9eH.json | 3 +- ...dversary_Young_Dryad_8yUj2Mzvnifhxegm.json | 3 +- ...ary_Young_Ice_Dragon_UGPiPLJsPvMTSKEF.json | 3 +- ...ersary_Zombie_Legion_YhJrP7rTBiRdX5Fp.json | 3 +- ...dversary_Zombie_Pack_Nf0v43rtflV56V2T.json | 3 +- ...eastform_Agile_Scout_a9UoCwtrbgKk02mK.json | 3 +- ...orm_Aquatic_Predator_ItBVeCl2u5uetgy7.json | 3 +- ...stform_Aquatic_Scout_qqzdFCxyYupWZK23.json | 3 +- ...tform_Armored_Sentry_8pUHJv3BYdjA4Qdf.json | 3 +- ...m_Epic_Aquatic_Beast_wT4xbF99I55yjKZV.json | 3 +- ...tform_Great_Predator_afbMt4Ld6nY3mw0N.json | 3 +- ...m_Great_Winged_Beast_b4BMnTbJ3iPPidSb.json | 3 +- ...orm_Household_Friend_iDmOtiHJJ80AIAVT.json | 3 +- ...orm_Massive_Behemoth_qjwMzPn33aKZACkv.json | 3 +- ...stform_Mighty_Lizard_94tvcC3D5Kp4lzuN.json | 3 +- ...tform_Mighty_Strider_zRLjqKx4Rn2TjivL.json | 3 +- ...Mythic_Aerial_Hunter_jV6EuEacyQlHW4SN.json | 3 +- ...stform_Nimble_Grazer_CItO8yX6amQaqyk7.json | 3 +- ...stform_Pack_Predator_YLisKYYhAGca50WM.json | 3 +- ...rm_Pouncing_Predator_33oFSZ1PwFqInHPe.json | 3 +- ...tform_Powerful_Beast_m8BVTuJI1wCvzTcf.json | 3 +- ...rm_Stalking_Arachnid_A4TVRY0D5r9EiVwA.json | 3 +- ...orm_Striking_Serpent_1XrZWGDttBAAUxR1.json | 3 +- ...form_Terrible_Lizard_5BABxRe2XVrYTj8N.json | 3 +- ...astform_Winged_Beast_mZ4Wlqtss2FlNNvL.json | 3 +- .../less/sheets/actors/adversary/header.less | 1 + styles/less/sheets/items/beastform.less | 3 + styles/less/ui/settings/settings.less | 6 + .../settings/homebrew-settings/settings.hbs | 14 + .../adversary-settings/details.hbs | 1 + .../token-config/appearance.hbs | 82 ++++ templates/sheets/actors/adversary/header.hbs | 8 + templates/sheets/items/beastform/settings.hbs | 39 +- 176 files changed, 1198 insertions(+), 203 deletions(-) create mode 100644 module/documents/scene.mjs create mode 100644 templates/sheets-settings/token-config/appearance.hbs diff --git a/daggerheart.mjs b/daggerheart.mjs index acbffd38..08a1be02 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -53,6 +53,8 @@ CONFIG.Canvas.rulerClass = placeables.DhRuler; CONFIG.Canvas.layers.templates.layerClass = placeables.DhTemplateLayer; CONFIG.MeasuredTemplate.objectClass = placeables.DhMeasuredTemplate; +CONFIG.Scene.documentClass = documents.DhScene; + CONFIG.Token.documentClass = documents.DhToken; CONFIG.Token.prototypeSheetClass = applications.sheetConfigs.DhPrototypeTokenConfig; CONFIG.Token.objectClass = placeables.DhTokenPlaceable; diff --git a/lang/en.json b/lang/en.json index 8a3481c8..498a45cb 100755 --- a/lang/en.json +++ b/lang/en.json @@ -611,6 +611,9 @@ "insufficientHope": "The initiating character doesn't have enough hope", "createTagTeam": "Create TagTeam Roll", "chatMessageRollTitle": "Roll" + }, + "TokenConfig": { + "actorSizeUsed": "Actor size is set, determining the dimensions" } }, "CLASS": { @@ -1147,6 +1150,14 @@ "rect": "Rectangle", "ray": "Ray" }, + "TokenSize": { + "tiny": "Tiny", + "small": "Small", + "medium": "Medium", + "large": "Large", + "huge": "Huge", + "gargantuan": "Gargantuan" + }, "Traits": { "agility": { "name": "Agility", @@ -2168,6 +2179,7 @@ "plural": "Targets" }, "title": "Title", + "tokenSize": "Token Size", "total": "Total", "traitModifier": "Trait Modifier", "true": "True", @@ -2224,6 +2236,7 @@ "tokenRingImg": { "label": "Subject Texture" }, "tokenSize": { "placeholder": "Using character dimensions", + "disabledPlaceholder": "Set by character size", "height": { "label": "Height" }, "width": { "label": "Width" } }, @@ -2249,7 +2262,9 @@ "hybridizeFeatureTitle": "Hybrid Features", "hybridizeDrag": "Drag a form here to hybridize it.", "mainTrait": "Main Trait", - "traitBonus": "Trait Bonus" + "traitBonus": "Trait Bonus", + "evolvedTokenHint": "An evolved beastform's token is based on that of the form you evolve", + "evolvedImagePlaceholder": "The image for the form selected for evolution will be used" }, "Class": { "hopeFeatures": "Hope Features", @@ -2802,7 +2817,8 @@ "companionPartnerLevelBlock": "The companion needs an assigned partner to level up.", "configureAttribution": "Configure Attribution", "deleteItem": "Delete Item", - "immune": "Immune" + "immune": "Immune", + "tokenSize": "The token size used on the canvas" } } } diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs index 6d36a2b3..3c4486c1 100644 --- a/module/applications/settings/homebrewSettings.mjs +++ b/module/applications/settings/homebrewSettings.mjs @@ -44,6 +44,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli deleteAdversaryType: this.deleteAdversaryType, selectAdversaryType: this.selectAdversaryType, save: this.save, + resetTokenSizes: this.resetTokenSizes, reset: this.reset }, form: { handler: this.updateData, submitOnChange: true } @@ -424,6 +425,14 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli this.close(); } + static async resetTokenSizes() { + await this.settings.updateSource({ + tokenSizes: this.settings.schema.fields.tokenSizes.initial + }); + + this.render(); + } + static async reset() { const confirmed = await foundry.applications.api.DialogV2.confirm({ window: { diff --git a/module/applications/sheets-configs/prototype-token-config.mjs b/module/applications/sheets-configs/prototype-token-config.mjs index 24c9dabb..0bb9703a 100644 --- a/module/applications/sheets-configs/prototype-token-config.mjs +++ b/module/applications/sheets-configs/prototype-token-config.mjs @@ -1,4 +1,18 @@ export default class DhPrototypeTokenConfig extends foundry.applications.sheets.PrototypeTokenConfig { + /** @override */ + static PARTS = { + tabs: super.PARTS.tabs, + identity: super.PARTS.identity, + appearance: { + template: 'systems/daggerheart/templates/sheets-settings/token-config/appearance.hbs', + scrollable: [''] + }, + vision: super.PARTS.vision, + light: super.PARTS.light, + resources: super.PARTS.resources, + footer: super.PARTS.footer + }; + /** @inheritDoc */ async _prepareResourcesTab() { const token = this.token; @@ -17,4 +31,11 @@ export default class DhPrototypeTokenConfig extends foundry.applications.sheets. turnMarkerAnimations: CONFIG.Combat.settings.turnMarkerAnimations }; } + + async _prepareAppearanceTab() { + const context = await super._prepareAppearanceTab(); + context.actorSizeUsed = this.token.actor ? Boolean(this.token.actor.system.size) : false; + + return context; + } } diff --git a/module/applications/sheets-configs/token-config.mjs b/module/applications/sheets-configs/token-config.mjs index ee573e5d..5f4e4f56 100644 --- a/module/applications/sheets-configs/token-config.mjs +++ b/module/applications/sheets-configs/token-config.mjs @@ -1,4 +1,18 @@ export default class DhTokenConfig extends foundry.applications.sheets.TokenConfig { + /** @override */ + static PARTS = { + tabs: super.PARTS.tabs, + identity: super.PARTS.identity, + appearance: { + template: 'systems/daggerheart/templates/sheets-settings/token-config/appearance.hbs', + scrollable: [''] + }, + vision: super.PARTS.vision, + light: super.PARTS.light, + resources: super.PARTS.resources, + footer: super.PARTS.footer + }; + /** @inheritDoc */ async _prepareResourcesTab() { const token = this.token; @@ -17,4 +31,11 @@ export default class DhTokenConfig extends foundry.applications.sheets.TokenConf turnMarkerAnimations: CONFIG.Combat.settings.turnMarkerAnimations }; } + + async _prepareAppearanceTab() { + const context = await super._prepareAppearanceTab(); + context.actorSizeUsed = this.token.actor ? Boolean(this.token.actor.system.size) : false; + + return context; + } } diff --git a/module/applications/sheets/items/beastform.mjs b/module/applications/sheets/items/beastform.mjs index 1c4a4880..880c0796 100644 --- a/module/applications/sheets/items/beastform.mjs +++ b/module/applications/sheets/items/beastform.mjs @@ -77,6 +77,7 @@ export default class BeastformSheet extends DHBaseItemSheet { name: context.document.system.advantageOn[key].value })) ); + context.dimensionsDisabled = context.document.system.tokenSize.size !== 'custom'; break; case 'effects': context.effects.actives = context.effects.actives.map(effect => { diff --git a/module/applications/sidebar/tabs/actorDirectory.mjs b/module/applications/sidebar/tabs/actorDirectory.mjs index 4a528e74..d40443a0 100644 --- a/module/applications/sidebar/tabs/actorDirectory.mjs +++ b/module/applications/sidebar/tabs/actorDirectory.mjs @@ -17,4 +17,30 @@ export default class DhActorDirectory extends foundry.applications.sidebar.tabs. : null; }; } + + /** @inheritDoc */ + _onDragStart(event) { + let actor; + const { entryId } = event.currentTarget.dataset; + if (entryId) { + actor = this.collection.get(entryId); + if (!actor?.visible) return false; + } + super._onDragStart(event); + + // Create the drag preview. + if (actor && canvas.ready) { + const img = event.currentTarget.querySelector('img'); + const pt = actor.prototypeToken; + const usesSize = actor.system.metadata.usesSize; + const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes; + const width = usesSize ? tokenSizes[actor.system.size] : pt.width; + const height = usesSize ? tokenSizes[actor.system.size] : pt.height; + + const w = width * canvas.dimensions.size * Math.abs(pt.texture.scaleX) * canvas.stage.scale.x; + const h = height * canvas.dimensions.size * Math.abs(pt.texture.scaleY) * canvas.stage.scale.y; + const preview = foundry.applications.ux.DragDrop.implementation.createDragImage(img, w, h); + event.dataTransfer.setDragImage(preview, w / 2, h / 2); + } + } } diff --git a/module/config/actorConfig.mjs b/module/config/actorConfig.mjs index 7ff42754..fdef7d03 100644 --- a/module/config/actorConfig.mjs +++ b/module/config/actorConfig.mjs @@ -211,6 +211,44 @@ export const adversaryTraits = { } }; +export const tokenSize = { + custom: { + id: 'custom', + value: 0, + label: 'DAGGERHEART.GENERAL.custom' + }, + tiny: { + id: 'tiny', + value: 1, + label: 'DAGGERHEART.CONFIG.TokenSize.tiny' + }, + small: { + id: 'small', + value: 2, + label: 'DAGGERHEART.CONFIG.TokenSize.small' + }, + medium: { + id: 'medium', + value: 3, + label: 'DAGGERHEART.CONFIG.TokenSize.medium' + }, + large: { + id: 'large', + value: 4, + label: 'DAGGERHEART.CONFIG.TokenSize.large' + }, + huge: { + id: 'huge', + value: 5, + label: 'DAGGERHEART.CONFIG.TokenSize.huge' + }, + gargantuan: { + id: 'gargantuan', + value: 6, + label: 'DAGGERHEART.CONFIG.TokenSize.gargantuan' + } +}; + export const levelChoices = { attributes: { name: 'attributes', diff --git a/module/data/activeEffect/beastformEffect.mjs b/module/data/activeEffect/beastformEffect.mjs index b5e775fc..b041b59e 100644 --- a/module/data/activeEffect/beastformEffect.mjs +++ b/module/data/activeEffect/beastformEffect.mjs @@ -65,20 +65,30 @@ export default class BeastformEffect extends BaseEffect { } }; - const updateToken = token => ({ - ...baseUpdate, - 'texture': { - enabled: this.characterTokenData.usesDynamicToken, - src: token.flags.daggerheart?.beastformTokenImg ?? this.characterTokenData.tokenImg - }, - 'ring': { - subject: { - texture: - token.flags.daggerheart?.beastformSubjectTexture ?? this.characterTokenData.tokenRingImg - } - }, - 'flags.daggerheart': { '-=beastformTokenImg': null, '-=beastformSubjectTexture': null } - }); + const updateToken = token => { + const { x, y } = game.system.api.documents.DhToken.getSnappedPositionInSquareGrid( + token.object.scene.grid, + { x: token.x, y: token.y, elevation: token.elevation }, + baseUpdate.width, + baseUpdate.height + ); + return { + ...baseUpdate, + x, + y, + 'texture': { + enabled: this.characterTokenData.usesDynamicToken, + src: token.flags.daggerheart?.beastformTokenImg ?? this.characterTokenData.tokenImg + }, + 'ring': { + subject: { + texture: + token.flags.daggerheart?.beastformSubjectTexture ?? this.characterTokenData.tokenRingImg + } + }, + 'flags.daggerheart': { '-=beastformTokenImg': null, '-=beastformSubjectTexture': null } + }; + }; await updateActorTokens(this.parent.parent, update, updateToken); diff --git a/module/data/actor/adversary.mjs b/module/data/actor/adversary.mjs index bb8df3ee..a7b66d4d 100644 --- a/module/data/actor/adversary.mjs +++ b/module/data/actor/adversary.mjs @@ -11,7 +11,8 @@ export default class DhpAdversary extends BaseDataActor { label: 'TYPES.Actor.adversary', type: 'adversary', settingSheet: DHAdversarySettings, - hasAttribution: true + hasAttribution: true, + usesSize: true }); } @@ -142,7 +143,7 @@ export default class DhpAdversary extends BaseDataActor { } isItemValid(source) { - return source.type === "feature"; + return source.type === 'feature'; } async _preUpdate(changes, options, user) { diff --git a/module/data/actor/base.mjs b/module/data/actor/base.mjs index f3662da2..29b0af28 100644 --- a/module/data/actor/base.mjs +++ b/module/data/actor/base.mjs @@ -42,7 +42,8 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel { settingSheet: null, hasResistances: true, hasAttribution: false, - hasLimitedView: true + hasLimitedView: true, + usesSize: false }; } @@ -77,6 +78,13 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel { 'DAGGERHEART.GENERAL.DamageResistance.magicalReduction' ) }); + if (this.metadata.usesSize) + schema.size = new fields.StringField({ + required: true, + nullable: false, + choices: CONFIG.DH.ACTOR.tokenSize, + initial: CONFIG.DH.ACTOR.tokenSize.custom.id + }); return schema; } diff --git a/module/data/actor/party.mjs b/module/data/actor/party.mjs index b306c486..236d65db 100644 --- a/module/data/actor/party.mjs +++ b/module/data/actor/party.mjs @@ -26,7 +26,7 @@ export default class DhParty extends BaseDataActor { /* -------------------------------------------- */ isItemValid(source) { - return ["weapon", "armor", "consumable", "loot"].includes(source.type); + return ['weapon', 'armor', 'consumable', 'loot'].includes(source.type); } prepareBaseData() { diff --git a/module/data/fields/action/beastformField.mjs b/module/data/fields/action/beastformField.mjs index 6ec5fdac..6185f0f8 100644 --- a/module/data/fields/action/beastformField.mjs +++ b/module/data/fields/action/beastformField.mjs @@ -92,6 +92,18 @@ export default class BeastformField extends fields.SchemaField { beastformEffect.changes = [...beastformEffect.changes, ...evolvedForm.changes]; formData.system.features = [...formData.system.features, ...selectedForm.system.features.map(x => x.uuid)]; + + const baseSize = evolvedData.form.system.tokenSize.size; + const evolvedSize = + baseSize === 'custom' + ? 'custom' + : (Object.keys(CONFIG.DH.ACTOR.tokenSize).find( + x => CONFIG.DH.ACTOR.tokenSize[x].value === CONFIG.DH.ACTOR.tokenSize[baseSize].value + 1 + ) ?? baseSize); + formData.system.tokenSize = { + ...evolvedData.form.system.tokenSize, + size: evolvedSize + }; } if (selectedForm.system.beastformType === CONFIG.DH.ITEM.beastformTypes.hybrid.id) { diff --git a/module/data/item/beastform.mjs b/module/data/item/beastform.mjs index 51ca298d..669cd4b1 100644 --- a/module/data/item/beastform.mjs +++ b/module/data/item/beastform.mjs @@ -43,6 +43,12 @@ export default class DHBeastform extends BaseDataItem { base64: false }), tokenSize: new fields.SchemaField({ + size: new fields.StringField({ + required: true, + nullable: false, + choices: CONFIG.DH.ACTOR.tokenSize, + initial: CONFIG.DH.ACTOR.tokenSize.custom.id + }), height: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true }), width: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true }) }), @@ -190,9 +196,18 @@ export default class DHBeastform extends BaseDataItem { await this.parent.parent.createEmbeddedDocuments('ActiveEffect', [beastformEffect.toObject()]); + const autoTokenSize = + this.tokenSize.size !== 'custom' + ? game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes[ + this.tokenSize.size + ] + : null; + const width = autoTokenSize ?? this.tokenSize.width; + const height = autoTokenSize ?? this.tokenSize.height; + const prototypeTokenUpdate = { - height: this.tokenSize.height, - width: this.tokenSize.width, + height, + width, texture: { src: this.tokenImg }, @@ -202,16 +217,25 @@ export default class DHBeastform extends BaseDataItem { } } }; - - const tokenUpdate = token => ({ - ...prototypeTokenUpdate, - flags: { - daggerheart: { - beastformTokenImg: token.texture.src, - beastformSubjectTexture: token.ring.subject.texture + const tokenUpdate = token => { + const { x, y } = game.system.api.documents.DhToken.getSnappedPositionInSquareGrid( + token.object.scene.grid, + { x: token.x, y: token.y, elevation: token.elevation }, + width ?? token.width, + height ?? token.height + ); + return { + ...prototypeTokenUpdate, + x, + y, + flags: { + daggerheart: { + beastformTokenImg: token.texture.src, + beastformSubjectTexture: token.ring.subject.texture + } } - } - }); + }; + }; await updateActorTokens(this.parent.parent, prototypeTokenUpdate, tokenUpdate); diff --git a/module/data/settings/Homebrew.mjs b/module/data/settings/Homebrew.mjs index 6f280cbd..7572c9ea 100644 --- a/module/data/settings/Homebrew.mjs +++ b/module/data/settings/Homebrew.mjs @@ -40,6 +40,38 @@ export default class DhHomebrew extends foundry.abstract.DataModel { traitArray: new fields.ArrayField(new fields.NumberField({ required: true, integer: true }), { initial: () => [2, 1, 1, 0, 0, -1] }), + tokenSizes: new fields.SchemaField({ + tiny: new fields.NumberField({ + integer: false, + initial: 0.5, + label: 'DAGGERHEART.CONFIG.TokenSize.tiny' + }), + small: new fields.NumberField({ + integer: false, + initial: 0.8, + label: 'DAGGERHEART.CONFIG.TokenSize.small' + }), + medium: new fields.NumberField({ + integer: false, + initial: 1, + label: 'DAGGERHEART.CONFIG.TokenSize.medium' + }), + large: new fields.NumberField({ + integer: false, + initial: 2, + label: 'DAGGERHEART.CONFIG.TokenSize.large' + }), + huge: new fields.NumberField({ + integer: false, + initial: 3, + label: 'DAGGERHEART.CONFIG.TokenSize.huge' + }), + gargantuan: new fields.NumberField({ + integer: false, + initial: 4, + label: 'DAGGERHEART.CONFIG.TokenSize.gargantuan' + }) + }), currency: new fields.SchemaField({ title: new fields.StringField({ required: true, diff --git a/module/documents/_module.mjs b/module/documents/_module.mjs index af1e9942..22718bea 100644 --- a/module/documents/_module.mjs +++ b/module/documents/_module.mjs @@ -4,6 +4,7 @@ export { default as DhpCombat } from './combat.mjs'; export { default as DHCombatant } from './combatant.mjs'; export { default as DhActiveEffect } from './activeEffect.mjs'; export { default as DhChatMessage } from './chatMessage.mjs'; +export { default as DhScene } from './scene.mjs'; export { default as DhToken } from './token.mjs'; export { default as DhTooltipManager } from './tooltipManager.mjs'; export { default as DhTemplateManager } from './templateManager.mjs'; diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 3e1a9eca..06b60447 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -74,16 +74,27 @@ export default class DhpActor extends Actor { /**@inheritdoc */ async _preCreate(data, options, user) { if ((await super._preCreate(data, options, user)) === false) return false; + const update = {}; + + // Set default token size. Done here as we do not want to set a datamodel default, since that would apply the sizing to third party actor modules that aren't set up with the size system. + if (this.system.metadata.usesSize && !data.system?.size) { + Object.assign(update, { + system: { + size: CONFIG.DH.ACTOR.tokenSize.medium.id + } + }); + } // Configure prototype token settings - const prototypeToken = {}; if (['character', 'companion', 'party'].includes(this.type)) - Object.assign(prototypeToken, { - sight: { enabled: true }, - actorLink: true, - disposition: CONST.TOKEN_DISPOSITIONS.FRIENDLY + Object.assign(update, { + prototypeToken: { + sight: { enabled: true }, + actorLink: true, + disposition: CONST.TOKEN_DISPOSITIONS.FRIENDLY + } }); - this.updateSource({ prototypeToken }); + this.updateSource(update); } _onUpdate(changes, options, userId) { diff --git a/module/documents/scene.mjs b/module/documents/scene.mjs new file mode 100644 index 00000000..c6cdd2c2 --- /dev/null +++ b/module/documents/scene.mjs @@ -0,0 +1,40 @@ +import DHToken from './token.mjs'; + +export default class DhScene extends Scene { + /** A map of `TokenDocument` IDs embedded in this scene long with new dimensions from actor size-category changes */ + #sizeSyncBatch = new Map(); + + /** Synchronize a token's dimensions with its actor's size category. */ + syncTokenDimensions(tokenDoc, tokenSize) { + if (!tokenDoc.parent?.tokens.has(tokenDoc.id)) return; + const prototype = tokenDoc.actor?.prototypeToken ?? tokenDoc; + this.#sizeSyncBatch.set(tokenDoc.id, { + size: tokenSize, + prototypeSize: { width: prototype.width, height: prototype.height }, + position: { x: tokenDoc.x, y: tokenDoc.y, elevation: tokenDoc.elevation } + }); + this.#processSyncBatch(); + } + + /** Retrieve size and clear size-sync batch, make updates. */ + #processSyncBatch = foundry.utils.debounce(() => { + const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes; + const entries = this.#sizeSyncBatch + .entries() + .toArray() + .map(([_id, { size, prototypeSize, position }]) => { + const tokenSize = tokenSizes[size]; + const width = size !== CONFIG.DH.ACTOR.tokenSize.custom.id ? tokenSize : prototypeSize.width; + const height = size !== CONFIG.DH.ACTOR.tokenSize.custom.id ? tokenSize : prototypeSize.height; + const updatedPosition = DHToken.getSnappedPositionInSquareGrid(this.grid, position, width, height); + return { + _id, + width, + height, + ...updatedPosition + }; + }); + this.#sizeSyncBatch.clear(); + this.updateEmbeddedDocuments('Token', entries, { animation: { movementSpeed: 1.5 } }); + }, 0); +} diff --git a/module/documents/token.mjs b/module/documents/token.mjs index 6996708b..c3babaa1 100644 --- a/module/documents/token.mjs +++ b/module/documents/token.mjs @@ -1,4 +1,4 @@ -export default class DHToken extends TokenDocument { +export default class DHToken extends CONFIG.Token.documentClass { /** * Inspect the Actor data model and identify the set of attributes which could be used for a Token Bar. * @param {object} attributes The tracked attributes which can be chosen from @@ -100,4 +100,440 @@ export default class DHToken extends TokenDocument { } super.deleteCombatants(tokens, combat ?? {}); } + + /**@inheritdoc */ + static async _preCreateOperation(documents, operation, user) { + const allowed = await super._preCreateOperation(documents, operation, user); + if (allowed === false) return false; + + const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes; + for (const document of documents) { + const actor = document.actor; + if (actor?.system.metadata.usesSize) { + const tokenSize = tokenSizes[actor.system.size]; + if (tokenSize && actor.system.size !== CONFIG.DH.ACTOR.tokenSize.custom.id) { + document.updateSource({ + width: tokenSize, + height: tokenSize + }); + } + } + } + } + + /**@inheritdoc */ + _onRelatedUpdate(update = {}, operation = {}) { + super._onRelatedUpdate(update, operation); + + if (!this.actor?.isOwner) return; + + const updates = Array.isArray(update) ? update : [update]; + const activeGM = game.users.activeGM; // Let the active GM take care of updates if available + for (let update of updates) { + if ( + this.actor.system.metadata.usesSize && + update.system?.size && + activeGM && + game.user.id === activeGM.id + ) { + const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes; + const tokenSize = tokenSizes[update.system.size]; + if (tokenSize !== this.width || tokenSize !== this.height) { + this.parent?.syncTokenDimensions(this, update.system.size); + } + } + } + } + + /**@inheritdoc */ + getSnappedPosition(data = {}) { + const grid = this.parent?.grid ?? BaseScene.defaultGrid; + const x = data.x ?? this.x; + const y = data.y ?? this.y; + let elevation = data.elevation ?? this.elevation; + const unsnapped = { x, y, elevation }; + + // Gridless grid + if (grid.isGridless) return unsnapped; + + // Get position and elevation + elevation = Math.round(elevation / grid.distance) * grid.distance; + + let width = data.width ?? this.width; + let height = data.height ?? this.height; + + if (this.actor?.system.metadata.usesSize) { + const tokenSizes = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).tokenSizes; + const tokenSize = tokenSizes[this.actor.system.size]; + if (tokenSize && this.actor.system.size !== CONFIG.DH.ACTOR.tokenSize.custom.id) { + width = tokenSize ?? width; + height = tokenSize ?? height; + } + } + + // Round width and height to nearest multiple of 0.5 if not small + width = width < 1 ? width : Math.round(width * 2) / 2; + height = height < 1 ? height : Math.round(height * 2) / 2; + const shape = data.shape ?? this.shape; + + // Square grid + let snapped; + if (grid.isSquare) snapped = DHToken.getSnappedPositionInSquareGrid(grid, unsnapped, width, height); + // Hexagonal grid + else snapped = DHToken.getSnappedPositionInHexagonalGrid(grid, unsnapped, width, height, shape); + return { x: snapped.x, y: snapped.y, elevation }; + } + + static getSnappedPositionInSquareGrid(grid, position, width, height) { + const M = CONST.GRID_SNAPPING_MODES; + // Small tokens snap to any vertex of the subgrid with resolution 4 + // where the token is fully contained within the grid space + const isTiny = (width === 0.5 && height <= 1) || (width <= 1 && height === 0.5); + if (isTiny) { + let x = position.x / grid.size; + let y = position.y / grid.size; + if (width === 1) x = Math.round(x); + else { + x = Math.floor(x * 8); + const k = ((x % 8) + 8) % 8; + if (k >= 6) x = Math.ceil(x / 8); + else if (k === 5) x = Math.floor(x / 8) + 0.5; + else x = Math.round(x / 2) / 4; + } + if (height === 1) y = Math.round(y); + else { + y = Math.floor(y * 8); + const k = ((y % 8) + 8) % 8; + if (k >= 6) y = Math.ceil(y / 8); + else if (k === 5) y = Math.floor(y / 8) + 0.5; + else y = Math.round(y / 2) / 4; + } + + x *= grid.size; + y *= grid.size; + + return { x, y }; + } else if (width < 1 && height < 1) { + // isSmall + let xGrid = Math.round(position.x / grid.size); + let yGrid = Math.round(position.y / grid.size); + + const x = xGrid * grid.size + grid.size / 2 - (width * grid.size) / 2; + const y = yGrid * grid.size + grid.size / 2 - (height * grid.size) / 2; + + return { x, y }; + } + + const modeX = Number.isInteger(width) ? M.VERTEX : M.VERTEX | M.EDGE_MIDPOINT | M.CENTER; + const modeY = Number.isInteger(height) ? M.VERTEX : M.VERTEX | M.EDGE_MIDPOINT | M.CENTER; + + if (modeX === modeY) return grid.getSnappedPoint(position, { mode: modeX }); + + return { + x: grid.getSnappedPoint(position, { mode: modeX }).x, + y: grid.getSnappedPoint(position, { mode: modeY }).y + }; + } + + //#region CopyPasta for mean private methods that have to be duplicated + static getSnappedPositionInHexagonalGrid(grid, position, width, height, shape) { + // Hexagonal shape + const hexagonalShape = DHToken.#getHexagonalShape(width, height, shape, grid.columns); + if (hexagonalShape) { + const offsetX = hexagonalShape.anchor.x * grid.sizeX; + const offsetY = hexagonalShape.anchor.y * grid.sizeY; + position = grid.getCenterPoint({ x: position.x + offsetX, y: position.y + offsetY }); + position.x -= offsetX; + position.y -= offsetY; + return position; + } + + // Rectagular shape + const M = CONST.GRID_SNAPPING_MODES; + return grid.getSnappedPoint(position, { mode: M.CENTER | M.VERTEX | M.CORNER | M.SIDE_MIDPOINT }); + } + + /** + * The cache of hexagonal shapes. + * @type {Map>} + */ + static #hexagonalShapes = new Map(); + + static #getHexagonalShape(width, height, shape, columns) { + if (!Number.isInteger(width * 2) || !Number.isInteger(height * 2)) return null; + + // TODO: can we set a max of 2^13 on width and height so that we may use an integer key? + const key = `${width},${height},${shape}${columns ? 'C' : 'R'}`; + let data = DHToken.#hexagonalShapes.get(key); + if (data) return data; + + // Hexagon symmetry + if (columns) { + const rowData = BaseToken.#getHexagonalShape(height, width, shape, false); + if (!rowData) return null; + + // Transpose the offsets/points of the shape in row orientation + const offsets = { even: [], odd: [] }; + for (const { i, j } of rowData.offsets.even) offsets.even.push({ i: j, j: i }); + for (const { i, j } of rowData.offsets.odd) offsets.odd.push({ i: j, j: i }); + offsets.even.sort(({ i: i0, j: j0 }, { i: i1, j: j1 }) => j0 - j1 || i0 - i1); + offsets.odd.sort(({ i: i0, j: j0 }, { i: i1, j: j1 }) => j0 - j1 || i0 - i1); + const points = []; + for (let i = rowData.points.length; i > 0; i -= 2) { + points.push(rowData.points[i - 1], rowData.points[i - 2]); + } + data = { + offsets, + points, + center: { x: rowData.center.y, y: rowData.center.x }, + anchor: { x: rowData.anchor.y, y: rowData.anchor.x } + }; + } + + // Small hexagon + else if (width === 0.5 && height === 0.5) { + data = { + offsets: { even: [{ i: 0, j: 0 }], odd: [{ i: 0, j: 0 }] }, + points: [0.25, 0.0, 0.5, 0.125, 0.5, 0.375, 0.25, 0.5, 0.0, 0.375, 0.0, 0.125], + center: { x: 0.25, y: 0.25 }, + anchor: { x: 0.25, y: 0.25 } + }; + } + + // Normal hexagon + else if (width === 1 && height === 1) { + data = { + offsets: { even: [{ i: 0, j: 0 }], odd: [{ i: 0, j: 0 }] }, + points: [0.5, 0.0, 1.0, 0.25, 1, 0.75, 0.5, 1.0, 0.0, 0.75, 0.0, 0.25], + center: { x: 0.5, y: 0.5 }, + anchor: { x: 0.5, y: 0.5 } + }; + } + + // Hexagonal ellipse or trapezoid + else if (shape <= CONST.TOKEN_SHAPES.TRAPEZOID_2) { + data = DHToken.#createHexagonalEllipseOrTrapezoid(width, height, shape); + } + + // Hexagonal rectangle + else if (shape <= CONST.TOKEN_SHAPES.RECTANGLE_2) { + data = DHToken.#createHexagonalRectangle(width, height, shape); + } + + // Cache the shape + if (data) { + foundry.utils.deepFreeze(data); + DHToken.#hexagonalShapes.set(key, data); + } + + return data; + } + + static #createHexagonalEllipseOrTrapezoid(width, height, shape) { + if (!Number.isInteger(width) || !Number.isInteger(height)) return null; + const points = []; + let top; + let bottom; + switch (shape) { + case CONST.TOKEN_SHAPES.ELLIPSE_1: + if (height >= 2 * width) return null; + top = Math.floor(height / 2); + bottom = Math.floor((height - 1) / 2); + break; + case CONST.TOKEN_SHAPES.ELLIPSE_2: + if (height >= 2 * width) return null; + top = Math.floor((height - 1) / 2); + bottom = Math.floor(height / 2); + break; + case CONST.TOKEN_SHAPES.TRAPEZOID_1: + if (height > width) return null; + top = height - 1; + bottom = 0; + break; + case CONST.TOKEN_SHAPES.TRAPEZOID_2: + if (height > width) return null; + top = 0; + bottom = height - 1; + break; + } + const offsets = { even: [], odd: [] }; + for (let i = bottom; i > 0; i--) { + for (let j = 0; j < width - i; j++) { + offsets.even.push({ i: bottom - i, j: j + (((bottom & 1) + i + 1) >> 1) }); + offsets.odd.push({ i: bottom - i, j: j + (((bottom & 1) + i) >> 1) }); + } + } + for (let i = 0; i <= top; i++) { + for (let j = 0; j < width - i; j++) { + offsets.even.push({ i: bottom + i, j: j + (((bottom & 1) + i + 1) >> 1) }); + offsets.odd.push({ i: bottom + i, j: j + (((bottom & 1) + i) >> 1) }); + } + } + let x = 0.5 * bottom; + let y = 0.25; + for (let k = width - bottom; k--; ) { + points.push(x, y); + x += 0.5; + y -= 0.25; + points.push(x, y); + x += 0.5; + y += 0.25; + } + points.push(x, y); + for (let k = bottom; k--; ) { + y += 0.5; + points.push(x, y); + x += 0.5; + y += 0.25; + points.push(x, y); + } + y += 0.5; + for (let k = top; k--; ) { + points.push(x, y); + x -= 0.5; + y += 0.25; + points.push(x, y); + y += 0.5; + } + for (let k = width - top; k--; ) { + points.push(x, y); + x -= 0.5; + y += 0.25; + points.push(x, y); + x -= 0.5; + y -= 0.25; + } + points.push(x, y); + for (let k = top; k--; ) { + y -= 0.5; + points.push(x, y); + x -= 0.5; + y -= 0.25; + points.push(x, y); + } + y -= 0.5; + for (let k = bottom; k--; ) { + points.push(x, y); + x += 0.5; + y -= 0.25; + points.push(x, y); + y -= 0.5; + } + return { + offsets, + points, + // We use the centroid of the polygon for ellipse and trapzoid shapes + center: foundry.utils.polygonCentroid(points), + anchor: bottom % 2 ? { x: 0.0, y: 0.5 } : { x: 0.5, y: 0.5 } + }; + } + + /** + * Create the row-based hexagonal rectangle given the type, width, and height. + * @param {number} width The width of the Token (positive) + * @param {number} height The height of the Token (positive) + * @param {TokenShapeType} shape The shape type (must be RECTANGLE_1 or RECTANGLE_2) + * @returns {TokenHexagonalShapeData|null} The hexagonal shape or null if there is no shape + * for the given combination of arguments + */ + static #createHexagonalRectangle(width, height, shape) { + if (width < 1 || !Number.isInteger(height)) return null; + if (width === 1 && height > 1) return null; + if (!Number.isInteger(width) && height === 1) return null; + + const even = shape === CONST.TOKEN_SHAPES.RECTANGLE_1 || height === 1; + const offsets = { even: [], odd: [] }; + for (let i = 0; i < height; i++) { + const j0 = even ? 0 : (i + 1) & 1; + const j1 = ((width + (i & 1) * 0.5) | 0) - (even ? i & 1 : 0); + for (let j = j0; j < j1; j++) { + offsets.even.push({ i, j: j + (i & 1) }); + offsets.odd.push({ i, j }); + } + } + let x = even ? 0.0 : 0.5; + let y = 0.25; + const points = [x, y]; + while (x + 1 <= width) { + x += 0.5; + y -= 0.25; + points.push(x, y); + x += 0.5; + y += 0.25; + points.push(x, y); + } + if (x !== width) { + y += 0.5; + points.push(x, y); + x += 0.5; + y += 0.25; + points.push(x, y); + } + while (y + 1.5 <= 0.75 * height) { + y += 0.5; + points.push(x, y); + x -= 0.5; + y += 0.25; + points.push(x, y); + y += 0.5; + points.push(x, y); + x += 0.5; + y += 0.25; + points.push(x, y); + } + if (y + 0.75 < 0.75 * height) { + y += 0.5; + points.push(x, y); + x -= 0.5; + y += 0.25; + points.push(x, y); + } + y += 0.5; + points.push(x, y); + while (x - 1 >= 0) { + x -= 0.5; + y += 0.25; + points.push(x, y); + x -= 0.5; + y -= 0.25; + points.push(x, y); + } + if (x !== 0) { + y -= 0.5; + points.push(x, y); + x -= 0.5; + y -= 0.25; + points.push(x, y); + } + while (y - 1.5 > 0) { + y -= 0.5; + points.push(x, y); + x += 0.5; + y -= 0.25; + points.push(x, y); + y -= 0.5; + points.push(x, y); + x -= 0.5; + y -= 0.25; + points.push(x, y); + } + if (y - 0.75 > 0) { + y -= 0.5; + points.push(x, y); + x += 0.5; + y -= 0.25; + points.push(x, y); + } + return { + offsets, + points, + // We use center of the rectangle (and not the centroid of the polygon) for the rectangle shapes + center: { + x: width / 2, + y: (0.75 * Math.floor(height) + 0.5 * (height % 1) + 0.25) / 2 + }, + anchor: even ? { x: 0.5, y: 0.5 } : { x: 0.0, y: 0.5 } + }; + } + //#endregion } diff --git a/src/packs/adversaries/adversary_Acid_Burrower_89yAh30vaNQOALlz.json b/src/packs/adversaries/adversary_Acid_Burrower_89yAh30vaNQOALlz.json index 1d4cf11a..e93017f9 100644 --- a/src/packs/adversaries/adversary_Acid_Burrower_89yAh30vaNQOALlz.json +++ b/src/packs/adversaries/adversary_Acid_Burrower_89yAh30vaNQOALlz.json @@ -40,7 +40,8 @@ "experiences": { "pe7OIoJsqlpMXEvs": { "name": "Tremor Sense", - "value": 2 + "value": 2, + "description": "" } }, "bonuses": { @@ -148,7 +149,8 @@ "source": "Daggerheart SRD", "page": 75, "artist": "" - } + }, + "size": "large" }, "flags": {}, "ownership": { diff --git a/src/packs/adversaries/adversary_Adult_Flickerfly_G7jiltRjgvVhZewm.json b/src/packs/adversaries/adversary_Adult_Flickerfly_G7jiltRjgvVhZewm.json index 3d1404a7..be14ae49 100644 --- a/src/packs/adversaries/adversary_Adult_Flickerfly_G7jiltRjgvVhZewm.json +++ b/src/packs/adversaries/adversary_Adult_Flickerfly_G7jiltRjgvVhZewm.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 91, "artist": "" - } + }, + "size": "gargantuan" }, "flags": {}, "_id": "G7jiltRjgvVhZewm", diff --git a/src/packs/adversaries/adversary_Apprentice_Assassin_vNIbYQ4YSzNf0WPE.json b/src/packs/adversaries/adversary_Apprentice_Assassin_vNIbYQ4YSzNf0WPE.json index fbf53d80..41bd6fca 100644 --- a/src/packs/adversaries/adversary_Apprentice_Assassin_vNIbYQ4YSzNf0WPE.json +++ b/src/packs/adversaries/adversary_Apprentice_Assassin_vNIbYQ4YSzNf0WPE.json @@ -110,7 +110,8 @@ "source": "Daggerheart SRD", "page": 84, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "vNIbYQ4YSzNf0WPE", diff --git a/src/packs/adversaries/adversary_Arch_Necromancer_WPEOIGfclNJxWb87.json b/src/packs/adversaries/adversary_Arch_Necromancer_WPEOIGfclNJxWb87.json index 2962b84c..d2fb5183 100644 --- a/src/packs/adversaries/adversary_Arch_Necromancer_WPEOIGfclNJxWb87.json +++ b/src/packs/adversaries/adversary_Arch_Necromancer_WPEOIGfclNJxWb87.json @@ -122,7 +122,8 @@ "source": "Daggerheart SRD", "page": 97, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "WPEOIGfclNJxWb87", diff --git a/src/packs/adversaries/adversary_Archer_Guard_JRhrrEg5UroURiAD.json b/src/packs/adversaries/adversary_Archer_Guard_JRhrrEg5UroURiAD.json index bfdee207..034905aa 100644 --- a/src/packs/adversaries/adversary_Archer_Guard_JRhrrEg5UroURiAD.json +++ b/src/packs/adversaries/adversary_Archer_Guard_JRhrrEg5UroURiAD.json @@ -39,7 +39,8 @@ "experiences": { "Gtr9I2G39GcXT2Si": { "name": "Local Knowledge", - "value": 3 + "value": 3, + "description": "" } }, "bonuses": { @@ -116,7 +117,8 @@ "source": "Daggerheart SRD", "page": 77, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "JRhrrEg5UroURiAD", diff --git a/src/packs/adversaries/adversary_Archer_Squadron_0ts6CGd93lLqGZI5.json b/src/packs/adversaries/adversary_Archer_Squadron_0ts6CGd93lLqGZI5.json index 88d63721..1b2c8cad 100644 --- a/src/packs/adversaries/adversary_Archer_Squadron_0ts6CGd93lLqGZI5.json +++ b/src/packs/adversaries/adversary_Archer_Squadron_0ts6CGd93lLqGZI5.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 84, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "0ts6CGd93lLqGZI5", diff --git a/src/packs/adversaries/adversary_Assassin_Poisoner_h5RuhzGL17dW5FBT.json b/src/packs/adversaries/adversary_Assassin_Poisoner_h5RuhzGL17dW5FBT.json index b962fe78..cae27b60 100644 --- a/src/packs/adversaries/adversary_Assassin_Poisoner_h5RuhzGL17dW5FBT.json +++ b/src/packs/adversaries/adversary_Assassin_Poisoner_h5RuhzGL17dW5FBT.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 84, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "h5RuhzGL17dW5FBT", diff --git a/src/packs/adversaries/adversary_Battle_Box_dgH3fW9FTYLaIDvS.json b/src/packs/adversaries/adversary_Battle_Box_dgH3fW9FTYLaIDvS.json index b172b646..14b5c0f3 100644 --- a/src/packs/adversaries/adversary_Battle_Box_dgH3fW9FTYLaIDvS.json +++ b/src/packs/adversaries/adversary_Battle_Box_dgH3fW9FTYLaIDvS.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 85, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "dgH3fW9FTYLaIDvS", diff --git a/src/packs/adversaries/adversary_Bear_71qKDLKO3CsrNkdy.json b/src/packs/adversaries/adversary_Bear_71qKDLKO3CsrNkdy.json index f804c06e..2e4da586 100644 --- a/src/packs/adversaries/adversary_Bear_71qKDLKO3CsrNkdy.json +++ b/src/packs/adversaries/adversary_Bear_71qKDLKO3CsrNkdy.json @@ -122,7 +122,8 @@ "source": "Daggerheart SRD", "page": 75, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "71qKDLKO3CsrNkdy", diff --git a/src/packs/adversaries/adversary_Bladed_Guard_B4LZcGuBAHzyVdzy.json b/src/packs/adversaries/adversary_Bladed_Guard_B4LZcGuBAHzyVdzy.json index ecc547f8..f4227a91 100644 --- a/src/packs/adversaries/adversary_Bladed_Guard_B4LZcGuBAHzyVdzy.json +++ b/src/packs/adversaries/adversary_Bladed_Guard_B4LZcGuBAHzyVdzy.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 77, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "B4LZcGuBAHzyVdzy", diff --git a/src/packs/adversaries/adversary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json b/src/packs/adversaries/adversary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json index 96e00139..d522e737 100644 --- a/src/packs/adversaries/adversary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json +++ b/src/packs/adversaries/adversary_Brawny_Zombie_2UeZ0tEe7AzgSJNd.json @@ -120,7 +120,8 @@ "source": "Daggerheart SRD", "page": 83, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "2UeZ0tEe7AzgSJNd", diff --git a/src/packs/adversaries/adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json b/src/packs/adversaries/adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json index 91ba0045..a85d9bf2 100644 --- a/src/packs/adversaries/adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json +++ b/src/packs/adversaries/adversary_Cave_Ogre_8Zkqk1jU09nKL2fy.json @@ -118,7 +118,8 @@ "source": "Daggerheart SRD", "page": 75, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "8Zkqk1jU09nKL2fy", diff --git a/src/packs/adversaries/adversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json b/src/packs/adversaries/adversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json index cf2be503..fabb0a14 100644 --- a/src/packs/adversaries/adversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json +++ b/src/packs/adversaries/adversary_Chaos_Skull_jDmHqGvzg5wjgmxE.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 85, "artist": "" - } + }, + "size": "tiny" }, "flags": {}, "_id": "jDmHqGvzg5wjgmxE", diff --git a/src/packs/adversaries/adversary_Conscript_99TqczuQipBmaB8i.json b/src/packs/adversaries/adversary_Conscript_99TqczuQipBmaB8i.json index d79aed6c..9503a299 100644 --- a/src/packs/adversaries/adversary_Conscript_99TqczuQipBmaB8i.json +++ b/src/packs/adversaries/adversary_Conscript_99TqczuQipBmaB8i.json @@ -104,7 +104,8 @@ "source": "Daggerheart SRD", "page": 85, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "99TqczuQipBmaB8i", diff --git a/src/packs/adversaries/adversary_Construct_uOP5oT9QzXPlnf3p.json b/src/packs/adversaries/adversary_Construct_uOP5oT9QzXPlnf3p.json index 964b1354..428e2def 100644 --- a/src/packs/adversaries/adversary_Construct_uOP5oT9QzXPlnf3p.json +++ b/src/packs/adversaries/adversary_Construct_uOP5oT9QzXPlnf3p.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 75, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "uOP5oT9QzXPlnf3p", diff --git a/src/packs/adversaries/adversary_Courtesan_ZxWaWPdzFIUPNC62.json b/src/packs/adversaries/adversary_Courtesan_ZxWaWPdzFIUPNC62.json index 571d8cf1..470dc140 100644 --- a/src/packs/adversaries/adversary_Courtesan_ZxWaWPdzFIUPNC62.json +++ b/src/packs/adversaries/adversary_Courtesan_ZxWaWPdzFIUPNC62.json @@ -122,7 +122,8 @@ "source": "Daggerheart SRD", "page": 85, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "ZxWaWPdzFIUPNC62", diff --git a/src/packs/adversaries/adversary_Courtier_CBBuEXAlLKFMJdjg.json b/src/packs/adversaries/adversary_Courtier_CBBuEXAlLKFMJdjg.json index c22a8130..eabd803e 100644 --- a/src/packs/adversaries/adversary_Courtier_CBBuEXAlLKFMJdjg.json +++ b/src/packs/adversaries/adversary_Courtier_CBBuEXAlLKFMJdjg.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 76, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "CBBuEXAlLKFMJdjg", diff --git a/src/packs/adversaries/adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json b/src/packs/adversaries/adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json index 8e4f477e..587d980c 100644 --- a/src/packs/adversaries/adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json +++ b/src/packs/adversaries/adversary_Cult_Adept_0NxCSugvKQ4W8OYZ.json @@ -122,7 +122,8 @@ "source": "Daggerheart SRD", "page": 85, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "0NxCSugvKQ4W8OYZ", diff --git a/src/packs/adversaries/adversary_Cult_Fang_tyBOpLfigAhI9bU3.json b/src/packs/adversaries/adversary_Cult_Fang_tyBOpLfigAhI9bU3.json index 5b167356..2dfb331d 100644 --- a/src/packs/adversaries/adversary_Cult_Fang_tyBOpLfigAhI9bU3.json +++ b/src/packs/adversaries/adversary_Cult_Fang_tyBOpLfigAhI9bU3.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 86, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "tyBOpLfigAhI9bU3", diff --git a/src/packs/adversaries/adversary_Cult_Initiate_zx99sOGTXicP4SSD.json b/src/packs/adversaries/adversary_Cult_Initiate_zx99sOGTXicP4SSD.json index 0aa5c326..6078e25c 100644 --- a/src/packs/adversaries/adversary_Cult_Initiate_zx99sOGTXicP4SSD.json +++ b/src/packs/adversaries/adversary_Cult_Initiate_zx99sOGTXicP4SSD.json @@ -104,7 +104,8 @@ "source": "Daggerheart SRD", "page": 86, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "zx99sOGTXicP4SSD", diff --git a/src/packs/adversaries/adversary_Deeproot_Defender_9x2xY9zwc3xzbXo5.json b/src/packs/adversaries/adversary_Deeproot_Defender_9x2xY9zwc3xzbXo5.json index 19d0fd4d..4fab7cb6 100644 --- a/src/packs/adversaries/adversary_Deeproot_Defender_9x2xY9zwc3xzbXo5.json +++ b/src/packs/adversaries/adversary_Deeproot_Defender_9x2xY9zwc3xzbXo5.json @@ -116,7 +116,8 @@ "source": "Daggerheart SRD", "page": 76, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "9x2xY9zwc3xzbXo5", diff --git a/src/packs/adversaries/adversary_Demon_of_Avarice_pnyjIGxxvurcWmTv.json b/src/packs/adversaries/adversary_Demon_of_Avarice_pnyjIGxxvurcWmTv.json index fa925b38..38b5a23c 100644 --- a/src/packs/adversaries/adversary_Demon_of_Avarice_pnyjIGxxvurcWmTv.json +++ b/src/packs/adversaries/adversary_Demon_of_Avarice_pnyjIGxxvurcWmTv.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 91, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "pnyjIGxxvurcWmTv", diff --git a/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json b/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json index cc792029..c9e9579a 100644 --- a/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json +++ b/src/packs/adversaries/adversary_Demon_of_Despair_kE4dfhqmIQpNd44e.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 92, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "kE4dfhqmIQpNd44e", diff --git a/src/packs/adversaries/adversary_Demon_of_Hubris_2VN3BftageoTTIzu.json b/src/packs/adversaries/adversary_Demon_of_Hubris_2VN3BftageoTTIzu.json index 04f6a778..be8f3eab 100644 --- a/src/packs/adversaries/adversary_Demon_of_Hubris_2VN3BftageoTTIzu.json +++ b/src/packs/adversaries/adversary_Demon_of_Hubris_2VN3BftageoTTIzu.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 92, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "2VN3BftageoTTIzu", diff --git a/src/packs/adversaries/adversary_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json b/src/packs/adversaries/adversary_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json index e79eef29..7e3b5c6d 100644 --- a/src/packs/adversaries/adversary_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json +++ b/src/packs/adversaries/adversary_Demon_of_Jealousy_SxSOkM4bcVOFyjbo.json @@ -118,7 +118,8 @@ "source": "Daggerheart SRD", "page": 92, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "SxSOkM4bcVOFyjbo", diff --git a/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json b/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json index cfe301f5..538c0d0a 100644 --- a/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json +++ b/src/packs/adversaries/adversary_Demon_of_Wrath_5lphJAgzoqZI3VoG.json @@ -118,7 +118,8 @@ "source": "Daggerheart SRD", "page": 92, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "5lphJAgzoqZI3VoG", diff --git a/src/packs/adversaries/adversary_Demonic_Hound_Pack_NoRZ1PqB8N5wcIw0.json b/src/packs/adversaries/adversary_Demonic_Hound_Pack_NoRZ1PqB8N5wcIw0.json index d407949e..cf982cda 100644 --- a/src/packs/adversaries/adversary_Demonic_Hound_Pack_NoRZ1PqB8N5wcIw0.json +++ b/src/packs/adversaries/adversary_Demonic_Hound_Pack_NoRZ1PqB8N5wcIw0.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 86, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "NoRZ1PqB8N5wcIw0", diff --git a/src/packs/adversaries/adversary_Dire_Bat_tBWHW00epmMnkawe.json b/src/packs/adversaries/adversary_Dire_Bat_tBWHW00epmMnkawe.json index 9c367879..91f4d795 100644 --- a/src/packs/adversaries/adversary_Dire_Bat_tBWHW00epmMnkawe.json +++ b/src/packs/adversaries/adversary_Dire_Bat_tBWHW00epmMnkawe.json @@ -116,7 +116,8 @@ "source": "Daggerheart SRD", "page": 93, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "tBWHW00epmMnkawe", diff --git a/src/packs/adversaries/adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json b/src/packs/adversaries/adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json index f40c2310..5028e88c 100644 --- a/src/packs/adversaries/adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json +++ b/src/packs/adversaries/adversary_Dire_Wolf_wNzeuQLfLUMvgHlQ.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 76, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "wNzeuQLfLUMvgHlQ", diff --git a/src/packs/adversaries/adversary_Dryad_wR7cFKrHvRzbzhBT.json b/src/packs/adversaries/adversary_Dryad_wR7cFKrHvRzbzhBT.json index 0bd8939e..2b1596da 100644 --- a/src/packs/adversaries/adversary_Dryad_wR7cFKrHvRzbzhBT.json +++ b/src/packs/adversaries/adversary_Dryad_wR7cFKrHvRzbzhBT.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 93, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "wR7cFKrHvRzbzhBT", diff --git a/src/packs/adversaries/adversary_Electric_Eels_TLzY1nDw0Bu9Ud40.json b/src/packs/adversaries/adversary_Electric_Eels_TLzY1nDw0Bu9Ud40.json index 0354d820..73074ca1 100644 --- a/src/packs/adversaries/adversary_Electric_Eels_TLzY1nDw0Bu9Ud40.json +++ b/src/packs/adversaries/adversary_Electric_Eels_TLzY1nDw0Bu9Ud40.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 86, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "TLzY1nDw0Bu9Ud40", diff --git a/src/packs/adversaries/adversary_Elemental_Spark_P7h54ZePFPHpYwvB.json b/src/packs/adversaries/adversary_Elemental_Spark_P7h54ZePFPHpYwvB.json index 9713e7ba..1a265528 100644 --- a/src/packs/adversaries/adversary_Elemental_Spark_P7h54ZePFPHpYwvB.json +++ b/src/packs/adversaries/adversary_Elemental_Spark_P7h54ZePFPHpYwvB.json @@ -104,7 +104,8 @@ "source": "Daggerheart SRD", "page": 93, "artist": "" - } + }, + "size": "tiny" }, "flags": {}, "_id": "P7h54ZePFPHpYwvB", diff --git a/src/packs/adversaries/adversary_Elite_Soldier_bfhVWMBUh61b9J6n.json b/src/packs/adversaries/adversary_Elite_Soldier_bfhVWMBUh61b9J6n.json index 18dc586b..cc98f31d 100644 --- a/src/packs/adversaries/adversary_Elite_Soldier_bfhVWMBUh61b9J6n.json +++ b/src/packs/adversaries/adversary_Elite_Soldier_bfhVWMBUh61b9J6n.json @@ -143,7 +143,8 @@ "source": "Daggerheart SRD", "page": 86, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "ownership": { diff --git a/src/packs/adversaries/adversary_Failed_Experiment_ChwwVqowFw8hJQwT.json b/src/packs/adversaries/adversary_Failed_Experiment_ChwwVqowFw8hJQwT.json index 7e97c5b1..89c922f4 100644 --- a/src/packs/adversaries/adversary_Failed_Experiment_ChwwVqowFw8hJQwT.json +++ b/src/packs/adversaries/adversary_Failed_Experiment_ChwwVqowFw8hJQwT.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 86, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "ChwwVqowFw8hJQwT", diff --git a/src/packs/adversaries/adversary_Fallen_Shock_Troop_OsLG2BjaEdTZUJU9.json b/src/packs/adversaries/adversary_Fallen_Shock_Troop_OsLG2BjaEdTZUJU9.json index b8b054c8..9833a495 100644 --- a/src/packs/adversaries/adversary_Fallen_Shock_Troop_OsLG2BjaEdTZUJU9.json +++ b/src/packs/adversaries/adversary_Fallen_Shock_Troop_OsLG2BjaEdTZUJU9.json @@ -104,7 +104,8 @@ "source": "Daggerheart SRD", "page": 97, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "OsLG2BjaEdTZUJU9", diff --git a/src/packs/adversaries/adversary_Fallen_Sorcerer_PELRry1vqjBzSAlr.json b/src/packs/adversaries/adversary_Fallen_Sorcerer_PELRry1vqjBzSAlr.json index 8b690bfd..9c63042e 100644 --- a/src/packs/adversaries/adversary_Fallen_Sorcerer_PELRry1vqjBzSAlr.json +++ b/src/packs/adversaries/adversary_Fallen_Sorcerer_PELRry1vqjBzSAlr.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 97, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "PELRry1vqjBzSAlr", diff --git a/src/packs/adversaries/adversary_Fallen_Warlord__Realm_Breaker_hxZ0sgoFJubh5aj6.json b/src/packs/adversaries/adversary_Fallen_Warlord__Realm_Breaker_hxZ0sgoFJubh5aj6.json index 8d75dd9e..8b0d912d 100644 --- a/src/packs/adversaries/adversary_Fallen_Warlord__Realm_Breaker_hxZ0sgoFJubh5aj6.json +++ b/src/packs/adversaries/adversary_Fallen_Warlord__Realm_Breaker_hxZ0sgoFJubh5aj6.json @@ -160,7 +160,8 @@ "source": "Daggerheart SRD", "page": 97, "artist": "" - } + }, + "size": "medium" }, "prototypeToken": { "name": "Fallen Warlord: Realm Breaker", diff --git a/src/packs/adversaries/adversary_Fallen_Warlord__Undefeated_Champion_RXkZTwBRi4dJ3JE5.json b/src/packs/adversaries/adversary_Fallen_Warlord__Undefeated_Champion_RXkZTwBRi4dJ3JE5.json index 061abed8..bc5ceee1 100644 --- a/src/packs/adversaries/adversary_Fallen_Warlord__Undefeated_Champion_RXkZTwBRi4dJ3JE5.json +++ b/src/packs/adversaries/adversary_Fallen_Warlord__Undefeated_Champion_RXkZTwBRi4dJ3JE5.json @@ -161,7 +161,8 @@ "source": "Daggerheart SRD", "page": 98, "artist": "" - } + }, + "size": "medium" }, "prototypeToken": { "name": "Fallen Warlord: Undefeated Champion", diff --git a/src/packs/adversaries/adversary_Giant_Beastmaster_8VZIgU12cB3cvlyH.json b/src/packs/adversaries/adversary_Giant_Beastmaster_8VZIgU12cB3cvlyH.json index e82d30d8..52e27c88 100644 --- a/src/packs/adversaries/adversary_Giant_Beastmaster_8VZIgU12cB3cvlyH.json +++ b/src/packs/adversaries/adversary_Giant_Beastmaster_8VZIgU12cB3cvlyH.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 87, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "8VZIgU12cB3cvlyH", diff --git a/src/packs/adversaries/adversary_Giant_Brawler_YnObCleGjPT7yqEc.json b/src/packs/adversaries/adversary_Giant_Brawler_YnObCleGjPT7yqEc.json index a51abc03..def13ed1 100644 --- a/src/packs/adversaries/adversary_Giant_Brawler_YnObCleGjPT7yqEc.json +++ b/src/packs/adversaries/adversary_Giant_Brawler_YnObCleGjPT7yqEc.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 87, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "YnObCleGjPT7yqEc", diff --git a/src/packs/adversaries/adversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json b/src/packs/adversaries/adversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json index dc21e5aa..3b877a09 100644 --- a/src/packs/adversaries/adversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json +++ b/src/packs/adversaries/adversary_Giant_Eagle_OMQ0v6PE8s1mSU0K.json @@ -143,7 +143,8 @@ "source": "Daggerheart SRD", "page": 87, "artist": "" - } + }, + "size": "large" }, "flags": {}, "ownership": { diff --git a/src/packs/adversaries/adversary_Giant_Mosquitoes_IIWV4ysJPFPnTP7W.json b/src/packs/adversaries/adversary_Giant_Mosquitoes_IIWV4ysJPFPnTP7W.json index 0db2613f..842f4adf 100644 --- a/src/packs/adversaries/adversary_Giant_Mosquitoes_IIWV4ysJPFPnTP7W.json +++ b/src/packs/adversaries/adversary_Giant_Mosquitoes_IIWV4ysJPFPnTP7W.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 76, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "IIWV4ysJPFPnTP7W", diff --git a/src/packs/adversaries/adversary_Giant_Rat_4PfLnaCrOcMdb4dK.json b/src/packs/adversaries/adversary_Giant_Rat_4PfLnaCrOcMdb4dK.json index 7da2eabd..26b5b232 100644 --- a/src/packs/adversaries/adversary_Giant_Rat_4PfLnaCrOcMdb4dK.json +++ b/src/packs/adversaries/adversary_Giant_Rat_4PfLnaCrOcMdb4dK.json @@ -110,7 +110,8 @@ "source": "Daggerheart SRD", "page": 76, "artist": "" - } + }, + "size": "small" }, "flags": {}, "_id": "4PfLnaCrOcMdb4dK", diff --git a/src/packs/adversaries/adversary_Giant_Recruit_5s8wSvpyC5rxY5aD.json b/src/packs/adversaries/adversary_Giant_Recruit_5s8wSvpyC5rxY5aD.json index 0ef9eb18..f926bd4b 100644 --- a/src/packs/adversaries/adversary_Giant_Recruit_5s8wSvpyC5rxY5aD.json +++ b/src/packs/adversaries/adversary_Giant_Recruit_5s8wSvpyC5rxY5aD.json @@ -104,7 +104,8 @@ "source": "Daggerheart SRD", "page": 87, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "5s8wSvpyC5rxY5aD", diff --git a/src/packs/adversaries/adversary_Giant_Scorpion_fmfntuJ8mHRCAktP.json b/src/packs/adversaries/adversary_Giant_Scorpion_fmfntuJ8mHRCAktP.json index b65a27ba..cebcaced 100644 --- a/src/packs/adversaries/adversary_Giant_Scorpion_fmfntuJ8mHRCAktP.json +++ b/src/packs/adversaries/adversary_Giant_Scorpion_fmfntuJ8mHRCAktP.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 76, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "fmfntuJ8mHRCAktP", diff --git a/src/packs/adversaries/adversary_Glass_Snake_8KWVLWXFhlY2kYx0.json b/src/packs/adversaries/adversary_Glass_Snake_8KWVLWXFhlY2kYx0.json index 67d9a7d7..b730dc57 100644 --- a/src/packs/adversaries/adversary_Glass_Snake_8KWVLWXFhlY2kYx0.json +++ b/src/packs/adversaries/adversary_Glass_Snake_8KWVLWXFhlY2kYx0.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 77, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "8KWVLWXFhlY2kYx0", diff --git a/src/packs/adversaries/adversary_Gorgon_8mJYMpbLTb8qIOrr.json b/src/packs/adversaries/adversary_Gorgon_8mJYMpbLTb8qIOrr.json index 98080be6..b8e1012b 100644 --- a/src/packs/adversaries/adversary_Gorgon_8mJYMpbLTb8qIOrr.json +++ b/src/packs/adversaries/adversary_Gorgon_8mJYMpbLTb8qIOrr.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 88, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "8mJYMpbLTb8qIOrr", diff --git a/src/packs/adversaries/adversary_Greater_Earth_Elemental_dsfB3YhoL5SudvS2.json b/src/packs/adversaries/adversary_Greater_Earth_Elemental_dsfB3YhoL5SudvS2.json index e8bc6601..ebb104f6 100644 --- a/src/packs/adversaries/adversary_Greater_Earth_Elemental_dsfB3YhoL5SudvS2.json +++ b/src/packs/adversaries/adversary_Greater_Earth_Elemental_dsfB3YhoL5SudvS2.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 93, "artist": "" - } + }, + "size": "gargantuan" }, "flags": {}, "_id": "dsfB3YhoL5SudvS2", diff --git a/src/packs/adversaries/adversary_Greater_Water_Elemental_xIICT6tEdnA7dKDV.json b/src/packs/adversaries/adversary_Greater_Water_Elemental_xIICT6tEdnA7dKDV.json index 73b702fb..1ce86201 100644 --- a/src/packs/adversaries/adversary_Greater_Water_Elemental_xIICT6tEdnA7dKDV.json +++ b/src/packs/adversaries/adversary_Greater_Water_Elemental_xIICT6tEdnA7dKDV.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 93, "artist": "" - } + }, + "size": "gargantuan" }, "flags": {}, "_id": "xIICT6tEdnA7dKDV", diff --git a/src/packs/adversaries/adversary_Green_Ooze_SHXedd9zZPVfUgUa.json b/src/packs/adversaries/adversary_Green_Ooze_SHXedd9zZPVfUgUa.json index 5746f57b..eaaecf2f 100644 --- a/src/packs/adversaries/adversary_Green_Ooze_SHXedd9zZPVfUgUa.json +++ b/src/packs/adversaries/adversary_Green_Ooze_SHXedd9zZPVfUgUa.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 80, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "SHXedd9zZPVfUgUa", diff --git a/src/packs/adversaries/adversary_Hallowed_Archer_kabueAo6BALApWqp.json b/src/packs/adversaries/adversary_Hallowed_Archer_kabueAo6BALApWqp.json index 6ad8d177..e9a1a19f 100644 --- a/src/packs/adversaries/adversary_Hallowed_Archer_kabueAo6BALApWqp.json +++ b/src/packs/adversaries/adversary_Hallowed_Archer_kabueAo6BALApWqp.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 98, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "kabueAo6BALApWqp", diff --git a/src/packs/adversaries/adversary_Hallowed_Soldier_VENwg7xEFcYObjmT.json b/src/packs/adversaries/adversary_Hallowed_Soldier_VENwg7xEFcYObjmT.json index 5a1ccc65..f84daf3c 100644 --- a/src/packs/adversaries/adversary_Hallowed_Soldier_VENwg7xEFcYObjmT.json +++ b/src/packs/adversaries/adversary_Hallowed_Soldier_VENwg7xEFcYObjmT.json @@ -104,7 +104,8 @@ "source": "Daggerheart SRD", "page": 98, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "VENwg7xEFcYObjmT", diff --git a/src/packs/adversaries/adversary_Harrier_uRtghKE9mHlII4rs.json b/src/packs/adversaries/adversary_Harrier_uRtghKE9mHlII4rs.json index d5ce14ff..105c5afd 100644 --- a/src/packs/adversaries/adversary_Harrier_uRtghKE9mHlII4rs.json +++ b/src/packs/adversaries/adversary_Harrier_uRtghKE9mHlII4rs.json @@ -116,7 +116,8 @@ "source": "Daggerheart SRD", "page": 77, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "uRtghKE9mHlII4rs", diff --git a/src/packs/adversaries/adversary_Head_Guard_mK3A5FTx6k8iPU3F.json b/src/packs/adversaries/adversary_Head_Guard_mK3A5FTx6k8iPU3F.json index d9f6e8b9..48ff14a8 100644 --- a/src/packs/adversaries/adversary_Head_Guard_mK3A5FTx6k8iPU3F.json +++ b/src/packs/adversaries/adversary_Head_Guard_mK3A5FTx6k8iPU3F.json @@ -122,7 +122,8 @@ "source": "Daggerheart SRD", "page": 77, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "mK3A5FTx6k8iPU3F", diff --git a/src/packs/adversaries/adversary_Head_Vampire_i2UNbRvgyoSs07M6.json b/src/packs/adversaries/adversary_Head_Vampire_i2UNbRvgyoSs07M6.json index d80504a7..d010ee34 100644 --- a/src/packs/adversaries/adversary_Head_Vampire_i2UNbRvgyoSs07M6.json +++ b/src/packs/adversaries/adversary_Head_Vampire_i2UNbRvgyoSs07M6.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 95, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "i2UNbRvgyoSs07M6", diff --git a/src/packs/adversaries/adversary_High_Seraph_r1mbfSSwKWdcFdAU.json b/src/packs/adversaries/adversary_High_Seraph_r1mbfSSwKWdcFdAU.json index 58b26f24..a2734e0d 100644 --- a/src/packs/adversaries/adversary_High_Seraph_r1mbfSSwKWdcFdAU.json +++ b/src/packs/adversaries/adversary_High_Seraph_r1mbfSSwKWdcFdAU.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 98, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "r1mbfSSwKWdcFdAU", diff --git a/src/packs/adversaries/adversary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json b/src/packs/adversaries/adversary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json index d291f805..6e5c45f9 100644 --- a/src/packs/adversaries/adversary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json +++ b/src/packs/adversaries/adversary_Huge_Green_Ooze_6hbqmxDXFOzZJDk4.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 94, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "6hbqmxDXFOzZJDk4", diff --git a/src/packs/adversaries/adversary_Hydra_MI126iMOOobQ1Obn.json b/src/packs/adversaries/adversary_Hydra_MI126iMOOobQ1Obn.json index 3c39550c..592d0da1 100644 --- a/src/packs/adversaries/adversary_Hydra_MI126iMOOobQ1Obn.json +++ b/src/packs/adversaries/adversary_Hydra_MI126iMOOobQ1Obn.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 94, "artist": "" - } + }, + "size": "huge" }, "flags": {}, "_id": "MI126iMOOobQ1Obn", diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Bandit_5Lh1T0zaT8Pkr2U2.json b/src/packs/adversaries/adversary_Jagged_Knife_Bandit_5Lh1T0zaT8Pkr2U2.json index 8828c612..7a95c097 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Bandit_5Lh1T0zaT8Pkr2U2.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Bandit_5Lh1T0zaT8Pkr2U2.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 77, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "5Lh1T0zaT8Pkr2U2", diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Hexer_MbBPIOxaxXYNApXz.json b/src/packs/adversaries/adversary_Jagged_Knife_Hexer_MbBPIOxaxXYNApXz.json index 26d83e78..200ed9b1 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Hexer_MbBPIOxaxXYNApXz.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Hexer_MbBPIOxaxXYNApXz.json @@ -116,7 +116,8 @@ "source": "Daggerheart SRD", "page": 78, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "MbBPIOxaxXYNApXz", diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Kneebreaker_CBKixLH3yhivZZuL.json b/src/packs/adversaries/adversary_Jagged_Knife_Kneebreaker_CBKixLH3yhivZZuL.json index 698ef485..48edab51 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Kneebreaker_CBKixLH3yhivZZuL.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Kneebreaker_CBKixLH3yhivZZuL.json @@ -122,7 +122,8 @@ "source": "Daggerheart SRD", "page": 78, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "CBKixLH3yhivZZuL", diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Lackey_C0OMQqV7pN6t7ouR.json b/src/packs/adversaries/adversary_Jagged_Knife_Lackey_C0OMQqV7pN6t7ouR.json index 668852a8..65c41639 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Lackey_C0OMQqV7pN6t7ouR.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Lackey_C0OMQqV7pN6t7ouR.json @@ -110,7 +110,8 @@ "source": "Daggerheart SRD", "page": 78, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "C0OMQqV7pN6t7ouR", diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Lieutenant_aTljstqteGoLpCBq.json b/src/packs/adversaries/adversary_Jagged_Knife_Lieutenant_aTljstqteGoLpCBq.json index 6f4b54a5..004c740a 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Lieutenant_aTljstqteGoLpCBq.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Lieutenant_aTljstqteGoLpCBq.json @@ -116,7 +116,8 @@ "source": "Daggerheart SRD", "page": 78, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "aTljstqteGoLpCBq", diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Shadow_XF4tYTq9nPJAy2ox.json b/src/packs/adversaries/adversary_Jagged_Knife_Shadow_XF4tYTq9nPJAy2ox.json index ad53f212..96c65c8c 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Shadow_XF4tYTq9nPJAy2ox.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Shadow_XF4tYTq9nPJAy2ox.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 78, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "XF4tYTq9nPJAy2ox", diff --git a/src/packs/adversaries/adversary_Jagged_Knife_Sniper_1zuyof1XuIfi3aMG.json b/src/packs/adversaries/adversary_Jagged_Knife_Sniper_1zuyof1XuIfi3aMG.json index 968e227a..1ef7070c 100644 --- a/src/packs/adversaries/adversary_Jagged_Knife_Sniper_1zuyof1XuIfi3aMG.json +++ b/src/packs/adversaries/adversary_Jagged_Knife_Sniper_1zuyof1XuIfi3aMG.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 78, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "1zuyof1XuIfi3aMG", diff --git a/src/packs/adversaries/adversary_Juvenile_Flickerfly_MYXmTx2FHcIjdfYZ.json b/src/packs/adversaries/adversary_Juvenile_Flickerfly_MYXmTx2FHcIjdfYZ.json index fc30a072..242bedcb 100644 --- a/src/packs/adversaries/adversary_Juvenile_Flickerfly_MYXmTx2FHcIjdfYZ.json +++ b/src/packs/adversaries/adversary_Juvenile_Flickerfly_MYXmTx2FHcIjdfYZ.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 88, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "MYXmTx2FHcIjdfYZ", diff --git a/src/packs/adversaries/adversary_Knight_of_the_Realm_7ai2opemrclQe3VF.json b/src/packs/adversaries/adversary_Knight_of_the_Realm_7ai2opemrclQe3VF.json index 51e7979d..dca27ce3 100644 --- a/src/packs/adversaries/adversary_Knight_of_the_Realm_7ai2opemrclQe3VF.json +++ b/src/packs/adversaries/adversary_Knight_of_the_Realm_7ai2opemrclQe3VF.json @@ -127,7 +127,8 @@ "source": "Daggerheart SRD", "page": 88, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "7ai2opemrclQe3VF", diff --git a/src/packs/adversaries/adversary_Kraken_4nqv3ZwJGjnmic8j.json b/src/packs/adversaries/adversary_Kraken_4nqv3ZwJGjnmic8j.json index 62d443c9..58169e89 100644 --- a/src/packs/adversaries/adversary_Kraken_4nqv3ZwJGjnmic8j.json +++ b/src/packs/adversaries/adversary_Kraken_4nqv3ZwJGjnmic8j.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 99, "artist": "" - } + }, + "size": "gargantuan" }, "flags": {}, "_id": "4nqv3ZwJGjnmic8j", diff --git a/src/packs/adversaries/adversary_Masked_Thief_niBpVU7yeo5ccskE.json b/src/packs/adversaries/adversary_Masked_Thief_niBpVU7yeo5ccskE.json index 5af8b388..500d1211 100644 --- a/src/packs/adversaries/adversary_Masked_Thief_niBpVU7yeo5ccskE.json +++ b/src/packs/adversaries/adversary_Masked_Thief_niBpVU7yeo5ccskE.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 88, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "niBpVU7yeo5ccskE", diff --git a/src/packs/adversaries/adversary_Master_Assassin_dNta0cUzr96xcFhf.json b/src/packs/adversaries/adversary_Master_Assassin_dNta0cUzr96xcFhf.json index 5ac80827..f654773a 100644 --- a/src/packs/adversaries/adversary_Master_Assassin_dNta0cUzr96xcFhf.json +++ b/src/packs/adversaries/adversary_Master_Assassin_dNta0cUzr96xcFhf.json @@ -122,7 +122,8 @@ "source": "Daggerheart SRD", "page": 84, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "dNta0cUzr96xcFhf", diff --git a/src/packs/adversaries/adversary_Merchant_Al3w2CgjfdT3p9ma.json b/src/packs/adversaries/adversary_Merchant_Al3w2CgjfdT3p9ma.json index 43135e6f..15197d52 100644 --- a/src/packs/adversaries/adversary_Merchant_Al3w2CgjfdT3p9ma.json +++ b/src/packs/adversaries/adversary_Merchant_Al3w2CgjfdT3p9ma.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 79, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "Al3w2CgjfdT3p9ma", diff --git a/src/packs/adversaries/adversary_Merchant_Baron_Vy02IhGhkJLuezu4.json b/src/packs/adversaries/adversary_Merchant_Baron_Vy02IhGhkJLuezu4.json index 0dea7b8e..2d392f8c 100644 --- a/src/packs/adversaries/adversary_Merchant_Baron_Vy02IhGhkJLuezu4.json +++ b/src/packs/adversaries/adversary_Merchant_Baron_Vy02IhGhkJLuezu4.json @@ -122,7 +122,8 @@ "source": "Daggerheart SRD", "page": 88, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "Vy02IhGhkJLuezu4", diff --git a/src/packs/adversaries/adversary_Minor_Chaos_Elemental_sRn4bqerfARvhgSV.json b/src/packs/adversaries/adversary_Minor_Chaos_Elemental_sRn4bqerfARvhgSV.json index 8d7c1888..5a9cd4c1 100644 --- a/src/packs/adversaries/adversary_Minor_Chaos_Elemental_sRn4bqerfARvhgSV.json +++ b/src/packs/adversaries/adversary_Minor_Chaos_Elemental_sRn4bqerfARvhgSV.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 79, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "sRn4bqerfARvhgSV", diff --git a/src/packs/adversaries/adversary_Minor_Demon_3tqCjDwJAQ7JKqMb.json b/src/packs/adversaries/adversary_Minor_Demon_3tqCjDwJAQ7JKqMb.json index 813af3c3..9f47ce8b 100644 --- a/src/packs/adversaries/adversary_Minor_Demon_3tqCjDwJAQ7JKqMb.json +++ b/src/packs/adversaries/adversary_Minor_Demon_3tqCjDwJAQ7JKqMb.json @@ -110,7 +110,8 @@ "source": "Daggerheart SRD", "page": 79, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "3tqCjDwJAQ7JKqMb", diff --git a/src/packs/adversaries/adversary_Minor_Fire_Elemental_DscWkNVoHak6P4hh.json b/src/packs/adversaries/adversary_Minor_Fire_Elemental_DscWkNVoHak6P4hh.json index f57abdd9..24f6da13 100644 --- a/src/packs/adversaries/adversary_Minor_Fire_Elemental_DscWkNVoHak6P4hh.json +++ b/src/packs/adversaries/adversary_Minor_Fire_Elemental_DscWkNVoHak6P4hh.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 79, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "DscWkNVoHak6P4hh", diff --git a/src/packs/adversaries/adversary_Minor_Treant_G62k4oSkhkoXEs2D.json b/src/packs/adversaries/adversary_Minor_Treant_G62k4oSkhkoXEs2D.json index c16b2c36..e1f388cf 100644 --- a/src/packs/adversaries/adversary_Minor_Treant_G62k4oSkhkoXEs2D.json +++ b/src/packs/adversaries/adversary_Minor_Treant_G62k4oSkhkoXEs2D.json @@ -104,7 +104,8 @@ "source": "Daggerheart SRD", "page": 80, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "G62k4oSkhkoXEs2D", diff --git a/src/packs/adversaries/adversary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json b/src/packs/adversaries/adversary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json index 9ac0caa9..15889935 100644 --- a/src/packs/adversaries/adversary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json +++ b/src/packs/adversaries/adversary_Minotaur_Wrecker_rM9qCIYeWg9I0B4l.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 89, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "rM9qCIYeWg9I0B4l", diff --git a/src/packs/adversaries/adversary_Monarch_yx0vK2yfNVZKWUUi.json b/src/packs/adversaries/adversary_Monarch_yx0vK2yfNVZKWUUi.json index 8ec7b09d..a0d7a81c 100644 --- a/src/packs/adversaries/adversary_Monarch_yx0vK2yfNVZKWUUi.json +++ b/src/packs/adversaries/adversary_Monarch_yx0vK2yfNVZKWUUi.json @@ -122,7 +122,8 @@ "source": "Daggerheart SRD", "page": 94, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "yx0vK2yfNVZKWUUi", diff --git a/src/packs/adversaries/adversary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json b/src/packs/adversaries/adversary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json index febdc8e7..5a7b3aac 100644 --- a/src/packs/adversaries/adversary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json +++ b/src/packs/adversaries/adversary_Mortal_Hunter_mVV7a7KQAORoPMgZ.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 89, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "mVV7a7KQAORoPMgZ", diff --git a/src/packs/adversaries/adversary_Oak_Treant_XK78QUfY8c8Go8Uv.json b/src/packs/adversaries/adversary_Oak_Treant_XK78QUfY8c8Go8Uv.json index 977792ea..d35547bd 100644 --- a/src/packs/adversaries/adversary_Oak_Treant_XK78QUfY8c8Go8Uv.json +++ b/src/packs/adversaries/adversary_Oak_Treant_XK78QUfY8c8Go8Uv.json @@ -111,7 +111,8 @@ "page": 95, "artist": "" }, - "motivesAndTactics": "Hide in plain sight, preserve the forest, root down, swing branches" + "motivesAndTactics": "Hide in plain sight, preserve the forest, root down, swing branches", + "size": "large" }, "flags": {}, "_id": "XK78QUfY8c8Go8Uv", diff --git a/src/packs/adversaries/adversary_Oracle_of_Doom_befIqd5IYKg6eUz2.json b/src/packs/adversaries/adversary_Oracle_of_Doom_befIqd5IYKg6eUz2.json index be97acf2..b225cf7b 100644 --- a/src/packs/adversaries/adversary_Oracle_of_Doom_befIqd5IYKg6eUz2.json +++ b/src/packs/adversaries/adversary_Oracle_of_Doom_befIqd5IYKg6eUz2.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 99, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "befIqd5IYKg6eUz2", diff --git a/src/packs/adversaries/adversary_Outer_Realms_Abomination_A0SeeDzwjvqOsyof.json b/src/packs/adversaries/adversary_Outer_Realms_Abomination_A0SeeDzwjvqOsyof.json index d4b37075..b10f611b 100644 --- a/src/packs/adversaries/adversary_Outer_Realms_Abomination_A0SeeDzwjvqOsyof.json +++ b/src/packs/adversaries/adversary_Outer_Realms_Abomination_A0SeeDzwjvqOsyof.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 99, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "A0SeeDzwjvqOsyof", diff --git a/src/packs/adversaries/adversary_Outer_Realms_Corrupter_ms6nuOl3NFkhPj1k.json b/src/packs/adversaries/adversary_Outer_Realms_Corrupter_ms6nuOl3NFkhPj1k.json index f84bc04d..43d029ca 100644 --- a/src/packs/adversaries/adversary_Outer_Realms_Corrupter_ms6nuOl3NFkhPj1k.json +++ b/src/packs/adversaries/adversary_Outer_Realms_Corrupter_ms6nuOl3NFkhPj1k.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 99, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "ms6nuOl3NFkhPj1k", diff --git a/src/packs/adversaries/adversary_Outer_Realms_Thrall_moJhHgKqTKPS2WYS.json b/src/packs/adversaries/adversary_Outer_Realms_Thrall_moJhHgKqTKPS2WYS.json index 38ed9db0..387e4006 100644 --- a/src/packs/adversaries/adversary_Outer_Realms_Thrall_moJhHgKqTKPS2WYS.json +++ b/src/packs/adversaries/adversary_Outer_Realms_Thrall_moJhHgKqTKPS2WYS.json @@ -104,7 +104,8 @@ "source": "Daggerheart SRD", "page": 99, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "moJhHgKqTKPS2WYS", diff --git a/src/packs/adversaries/adversary_Patchwork_Zombie_Hulk_EQTOAOUrkIvS2z88.json b/src/packs/adversaries/adversary_Patchwork_Zombie_Hulk_EQTOAOUrkIvS2z88.json index 1575bbf8..4aca5200 100644 --- a/src/packs/adversaries/adversary_Patchwork_Zombie_Hulk_EQTOAOUrkIvS2z88.json +++ b/src/packs/adversaries/adversary_Patchwork_Zombie_Hulk_EQTOAOUrkIvS2z88.json @@ -40,11 +40,13 @@ "experiences": { "rLPEhboQmaD7QV7T": { "name": "Intimidation", - "value": 2 + "value": 2, + "description": "" }, "ejtjcqd5oW6eKnav": { "name": "Tear Things Apart", - "value": 2 + "value": 2, + "description": "" } }, "bonuses": { @@ -120,7 +122,8 @@ "source": "Daggerheart SRD", "page": 83, "artist": "" - } + }, + "size": "huge" }, "flags": {}, "_id": "EQTOAOUrkIvS2z88", diff --git a/src/packs/adversaries/adversary_Perfected_Zombie_CP6iRfHdyFWniTHY.json b/src/packs/adversaries/adversary_Perfected_Zombie_CP6iRfHdyFWniTHY.json index 3a7af054..b7844a11 100644 --- a/src/packs/adversaries/adversary_Perfected_Zombie_CP6iRfHdyFWniTHY.json +++ b/src/packs/adversaries/adversary_Perfected_Zombie_CP6iRfHdyFWniTHY.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 101, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "CP6iRfHdyFWniTHY", diff --git a/src/packs/adversaries/adversary_Petty_Noble_wycLpvebWdUqRhpP.json b/src/packs/adversaries/adversary_Petty_Noble_wycLpvebWdUqRhpP.json index 6e3c052c..80235a50 100644 --- a/src/packs/adversaries/adversary_Petty_Noble_wycLpvebWdUqRhpP.json +++ b/src/packs/adversaries/adversary_Petty_Noble_wycLpvebWdUqRhpP.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 80, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "wycLpvebWdUqRhpP", diff --git a/src/packs/adversaries/adversary_Pirate_Captain_OROJbjsqagVh7ECV.json b/src/packs/adversaries/adversary_Pirate_Captain_OROJbjsqagVh7ECV.json index a1c05eab..ac414c0a 100644 --- a/src/packs/adversaries/adversary_Pirate_Captain_OROJbjsqagVh7ECV.json +++ b/src/packs/adversaries/adversary_Pirate_Captain_OROJbjsqagVh7ECV.json @@ -122,7 +122,8 @@ "source": "Daggerheart SRD", "page": 81, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "OROJbjsqagVh7ECV", diff --git a/src/packs/adversaries/adversary_Pirate_Raiders_5YgEajn0wa4i85kC.json b/src/packs/adversaries/adversary_Pirate_Raiders_5YgEajn0wa4i85kC.json index dd69529d..baac89b1 100644 --- a/src/packs/adversaries/adversary_Pirate_Raiders_5YgEajn0wa4i85kC.json +++ b/src/packs/adversaries/adversary_Pirate_Raiders_5YgEajn0wa4i85kC.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 81, "artist": "" - } + }, + "size": "huge" }, "flags": {}, "_id": "5YgEajn0wa4i85kC", diff --git a/src/packs/adversaries/adversary_Pirate_Tough_mhcVkVFrzIJ18FDm.json b/src/packs/adversaries/adversary_Pirate_Tough_mhcVkVFrzIJ18FDm.json index 6d15f7da..db91bdc1 100644 --- a/src/packs/adversaries/adversary_Pirate_Tough_mhcVkVFrzIJ18FDm.json +++ b/src/packs/adversaries/adversary_Pirate_Tough_mhcVkVFrzIJ18FDm.json @@ -150,7 +150,8 @@ "source": "Daggerheart SRD", "page": 81, "artist": "" - } + }, + "size": "medium" }, "prototypeToken": { "name": "Pirate Tough", diff --git a/src/packs/adversaries/adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json b/src/packs/adversaries/adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json index dc5b66f4..3535a53f 100644 --- a/src/packs/adversaries/adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json +++ b/src/packs/adversaries/adversary_Red_Ooze_9rVlbJVrDNn1x7PS.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 80, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "9rVlbJVrDNn1x7PS", diff --git a/src/packs/adversaries/adversary_Rotted_Zombie_gP3fWTLzSFnpA8EJ.json b/src/packs/adversaries/adversary_Rotted_Zombie_gP3fWTLzSFnpA8EJ.json index 6a7ae3ff..eb49897a 100644 --- a/src/packs/adversaries/adversary_Rotted_Zombie_gP3fWTLzSFnpA8EJ.json +++ b/src/packs/adversaries/adversary_Rotted_Zombie_gP3fWTLzSFnpA8EJ.json @@ -104,7 +104,8 @@ "source": "Daggerheart SRD", "page": 83, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "gP3fWTLzSFnpA8EJ", diff --git a/src/packs/adversaries/adversary_Royal_Advisor_EtLJiTsilPPZvLUX.json b/src/packs/adversaries/adversary_Royal_Advisor_EtLJiTsilPPZvLUX.json index ef295cb0..7d6c966d 100644 --- a/src/packs/adversaries/adversary_Royal_Advisor_EtLJiTsilPPZvLUX.json +++ b/src/packs/adversaries/adversary_Royal_Advisor_EtLJiTsilPPZvLUX.json @@ -122,7 +122,8 @@ "source": "Daggerheart SRD", "page": 89, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "EtLJiTsilPPZvLUX", diff --git a/src/packs/adversaries/adversary_Secret_Keeper_sLAccjvCWfeedbpI.json b/src/packs/adversaries/adversary_Secret_Keeper_sLAccjvCWfeedbpI.json index 9c158011..064f2e9b 100644 --- a/src/packs/adversaries/adversary_Secret_Keeper_sLAccjvCWfeedbpI.json +++ b/src/packs/adversaries/adversary_Secret_Keeper_sLAccjvCWfeedbpI.json @@ -122,7 +122,8 @@ "source": "Daggerheart SRD", "page": 89, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "sLAccjvCWfeedbpI", diff --git a/src/packs/adversaries/adversary_Sellsword_bgreCaQ6ap2DVpCr.json b/src/packs/adversaries/adversary_Sellsword_bgreCaQ6ap2DVpCr.json index d5da4bca..5d6d92cc 100644 --- a/src/packs/adversaries/adversary_Sellsword_bgreCaQ6ap2DVpCr.json +++ b/src/packs/adversaries/adversary_Sellsword_bgreCaQ6ap2DVpCr.json @@ -104,7 +104,8 @@ "source": "Daggerheart SRD", "page": 81, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "bgreCaQ6ap2DVpCr", diff --git a/src/packs/adversaries/adversary_Shambling_Zombie_2nXz4ilAY4xuhKLm.json b/src/packs/adversaries/adversary_Shambling_Zombie_2nXz4ilAY4xuhKLm.json index 2e6d7fd2..4c27ae4a 100644 --- a/src/packs/adversaries/adversary_Shambling_Zombie_2nXz4ilAY4xuhKLm.json +++ b/src/packs/adversaries/adversary_Shambling_Zombie_2nXz4ilAY4xuhKLm.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 84, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "2nXz4ilAY4xuhKLm", diff --git a/src/packs/adversaries/adversary_Shark_YmVAkdNsyuXWTtYp.json b/src/packs/adversaries/adversary_Shark_YmVAkdNsyuXWTtYp.json index dce37d5a..aeb3c752 100644 --- a/src/packs/adversaries/adversary_Shark_YmVAkdNsyuXWTtYp.json +++ b/src/packs/adversaries/adversary_Shark_YmVAkdNsyuXWTtYp.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 90, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "YmVAkdNsyuXWTtYp", diff --git a/src/packs/adversaries/adversary_Siren_BK4jwyXSRx7IOQiO.json b/src/packs/adversaries/adversary_Siren_BK4jwyXSRx7IOQiO.json index e6700b73..412fc519 100644 --- a/src/packs/adversaries/adversary_Siren_BK4jwyXSRx7IOQiO.json +++ b/src/packs/adversaries/adversary_Siren_BK4jwyXSRx7IOQiO.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 90, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "BK4jwyXSRx7IOQiO", diff --git a/src/packs/adversaries/adversary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json b/src/packs/adversaries/adversary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json index 845bd708..bd47f587 100644 --- a/src/packs/adversaries/adversary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json +++ b/src/packs/adversaries/adversary_Skeleton_Archer_7X5q7a6ueeHs5oA9.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 81, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "7X5q7a6ueeHs5oA9", diff --git a/src/packs/adversaries/adversary_Skeleton_Dredge_6l1a3Fazq8BoKIcc.json b/src/packs/adversaries/adversary_Skeleton_Dredge_6l1a3Fazq8BoKIcc.json index e5daed4f..b1a83ac1 100644 --- a/src/packs/adversaries/adversary_Skeleton_Dredge_6l1a3Fazq8BoKIcc.json +++ b/src/packs/adversaries/adversary_Skeleton_Dredge_6l1a3Fazq8BoKIcc.json @@ -104,7 +104,8 @@ "source": "Daggerheart SRD", "page": 81, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "6l1a3Fazq8BoKIcc", diff --git a/src/packs/adversaries/adversary_Skeleton_Knight_Q9LaVTyXF9NF12C7.json b/src/packs/adversaries/adversary_Skeleton_Knight_Q9LaVTyXF9NF12C7.json index b4a349b5..769302b2 100644 --- a/src/packs/adversaries/adversary_Skeleton_Knight_Q9LaVTyXF9NF12C7.json +++ b/src/packs/adversaries/adversary_Skeleton_Knight_Q9LaVTyXF9NF12C7.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 82, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "Q9LaVTyXF9NF12C7", diff --git a/src/packs/adversaries/adversary_Skeleton_Warrior_10YIQl0lvCJXZLfX.json b/src/packs/adversaries/adversary_Skeleton_Warrior_10YIQl0lvCJXZLfX.json index dbf39bed..e9a5d149 100644 --- a/src/packs/adversaries/adversary_Skeleton_Warrior_10YIQl0lvCJXZLfX.json +++ b/src/packs/adversaries/adversary_Skeleton_Warrior_10YIQl0lvCJXZLfX.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 82, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "10YIQl0lvCJXZLfX", diff --git a/src/packs/adversaries/adversary_Spectral_Archer_5tCkhnBByUIN5UdG.json b/src/packs/adversaries/adversary_Spectral_Archer_5tCkhnBByUIN5UdG.json index 7dfe0c09..37398954 100644 --- a/src/packs/adversaries/adversary_Spectral_Archer_5tCkhnBByUIN5UdG.json +++ b/src/packs/adversaries/adversary_Spectral_Archer_5tCkhnBByUIN5UdG.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 90, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "5tCkhnBByUIN5UdG", diff --git a/src/packs/adversaries/adversary_Spectral_Captain_65cSO3EQEh6ZH6Xk.json b/src/packs/adversaries/adversary_Spectral_Captain_65cSO3EQEh6ZH6Xk.json index dd044b50..c4da2d97 100644 --- a/src/packs/adversaries/adversary_Spectral_Captain_65cSO3EQEh6ZH6Xk.json +++ b/src/packs/adversaries/adversary_Spectral_Captain_65cSO3EQEh6ZH6Xk.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 90, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "65cSO3EQEh6ZH6Xk", diff --git a/src/packs/adversaries/adversary_Spectral_Guardian_UFVGl1osOsJTneLf.json b/src/packs/adversaries/adversary_Spectral_Guardian_UFVGl1osOsJTneLf.json index 6dcd83c4..b41573f4 100644 --- a/src/packs/adversaries/adversary_Spectral_Guardian_UFVGl1osOsJTneLf.json +++ b/src/packs/adversaries/adversary_Spectral_Guardian_UFVGl1osOsJTneLf.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 90, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "UFVGl1osOsJTneLf", diff --git a/src/packs/adversaries/adversary_Spellblade_ldbWEL7uZs84vyrR.json b/src/packs/adversaries/adversary_Spellblade_ldbWEL7uZs84vyrR.json index d9b3dbf3..2d9f2374 100644 --- a/src/packs/adversaries/adversary_Spellblade_ldbWEL7uZs84vyrR.json +++ b/src/packs/adversaries/adversary_Spellblade_ldbWEL7uZs84vyrR.json @@ -118,7 +118,8 @@ "source": "Daggerheart SRD", "page": 82, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "ldbWEL7uZs84vyrR", diff --git a/src/packs/adversaries/adversary_Spy_8zlynOhnVA59KpKT.json b/src/packs/adversaries/adversary_Spy_8zlynOhnVA59KpKT.json index ffc4dfe7..1ebe23ff 100644 --- a/src/packs/adversaries/adversary_Spy_8zlynOhnVA59KpKT.json +++ b/src/packs/adversaries/adversary_Spy_8zlynOhnVA59KpKT.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 90, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "8zlynOhnVA59KpKT", diff --git a/src/packs/adversaries/adversary_Stag_Knight_KGVwnLq85ywP9xvB.json b/src/packs/adversaries/adversary_Stag_Knight_KGVwnLq85ywP9xvB.json index 2fb0c531..3785ea48 100644 --- a/src/packs/adversaries/adversary_Stag_Knight_KGVwnLq85ywP9xvB.json +++ b/src/packs/adversaries/adversary_Stag_Knight_KGVwnLq85ywP9xvB.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 94, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "KGVwnLq85ywP9xvB", diff --git a/src/packs/adversaries/adversary_Stonewraith_3aAS2Qm3R6cgaYfE.json b/src/packs/adversaries/adversary_Stonewraith_3aAS2Qm3R6cgaYfE.json index 807d6675..1c4f6b11 100644 --- a/src/packs/adversaries/adversary_Stonewraith_3aAS2Qm3R6cgaYfE.json +++ b/src/packs/adversaries/adversary_Stonewraith_3aAS2Qm3R6cgaYfE.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 91, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "3aAS2Qm3R6cgaYfE", diff --git a/src/packs/adversaries/adversary_Swarm_of_Rats_qNgs3AbLyJrY19nt.json b/src/packs/adversaries/adversary_Swarm_of_Rats_qNgs3AbLyJrY19nt.json index 1db0df10..500744e2 100644 --- a/src/packs/adversaries/adversary_Swarm_of_Rats_qNgs3AbLyJrY19nt.json +++ b/src/packs/adversaries/adversary_Swarm_of_Rats_qNgs3AbLyJrY19nt.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 82, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "qNgs3AbLyJrY19nt", diff --git a/src/packs/adversaries/adversary_Sylvan_Soldier_VtFBt9XBE0WrGGxP.json b/src/packs/adversaries/adversary_Sylvan_Soldier_VtFBt9XBE0WrGGxP.json index af64867f..182afa6a 100644 --- a/src/packs/adversaries/adversary_Sylvan_Soldier_VtFBt9XBE0WrGGxP.json +++ b/src/packs/adversaries/adversary_Sylvan_Soldier_VtFBt9XBE0WrGGxP.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 82, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "VtFBt9XBE0WrGGxP", diff --git a/src/packs/adversaries/adversary_Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json b/src/packs/adversaries/adversary_Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json index 1d686445..e914cba5 100644 --- a/src/packs/adversaries/adversary_Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json +++ b/src/packs/adversaries/adversary_Tangle_Bramble_Swarm_PKSXFuaIHUCoH63A.json @@ -148,7 +148,8 @@ "source": "Daggerheart SRD", "page": 82, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "ownership": { diff --git a/src/packs/adversaries/adversary_Tangle_Bramble_XcAGOSmtCFLT1unN.json b/src/packs/adversaries/adversary_Tangle_Bramble_XcAGOSmtCFLT1unN.json index 74b228f5..18baa82c 100644 --- a/src/packs/adversaries/adversary_Tangle_Bramble_XcAGOSmtCFLT1unN.json +++ b/src/packs/adversaries/adversary_Tangle_Bramble_XcAGOSmtCFLT1unN.json @@ -144,7 +144,8 @@ "source": "Daggerheart SRD", "page": 83, "artist": "" - } + }, + "size": "tiny" }, "flags": {}, "ownership": { diff --git a/src/packs/adversaries/adversary_Tiny_Green_Ooze_aLkLFuVoKz2NLoBK.json b/src/packs/adversaries/adversary_Tiny_Green_Ooze_aLkLFuVoKz2NLoBK.json index 8864c47c..5371aa70 100644 --- a/src/packs/adversaries/adversary_Tiny_Green_Ooze_aLkLFuVoKz2NLoBK.json +++ b/src/packs/adversaries/adversary_Tiny_Green_Ooze_aLkLFuVoKz2NLoBK.json @@ -107,7 +107,8 @@ "source": "Daggerheart SRD", "page": 80, "artist": "" - } + }, + "size": "tiny" }, "flags": {}, "_id": "aLkLFuVoKz2NLoBK", diff --git a/src/packs/adversaries/adversary_Tiny_Red_Ooze_1fkLQXVtmILqfJ44.json b/src/packs/adversaries/adversary_Tiny_Red_Ooze_1fkLQXVtmILqfJ44.json index 7c3da937..a8d1efb7 100644 --- a/src/packs/adversaries/adversary_Tiny_Red_Ooze_1fkLQXVtmILqfJ44.json +++ b/src/packs/adversaries/adversary_Tiny_Red_Ooze_1fkLQXVtmILqfJ44.json @@ -107,7 +107,8 @@ "source": "Daggerheart SRD", "page": 80, "artist": "" - } + }, + "size": "tiny" }, "flags": {}, "_id": "1fkLQXVtmILqfJ44", diff --git a/src/packs/adversaries/adversary_Treant_Sapling_o63nS0k3wHu6EgKP.json b/src/packs/adversaries/adversary_Treant_Sapling_o63nS0k3wHu6EgKP.json index 0ff01c70..7c734bf2 100644 --- a/src/packs/adversaries/adversary_Treant_Sapling_o63nS0k3wHu6EgKP.json +++ b/src/packs/adversaries/adversary_Treant_Sapling_o63nS0k3wHu6EgKP.json @@ -97,13 +97,15 @@ ] }, "type": "attack", - "chatDisplay": false + "chatDisplay": false, + "range": "" }, "attribution": { "source": "Daggerheart SRD", "page": 95, "artist": "" - } + }, + "size": "small" }, "flags": {}, "_id": "o63nS0k3wHu6EgKP", diff --git a/src/packs/adversaries/adversary_Vampire_WWyUp6Mxl1S3KYUG.json b/src/packs/adversaries/adversary_Vampire_WWyUp6Mxl1S3KYUG.json index 59bdb150..0ec631f1 100644 --- a/src/packs/adversaries/adversary_Vampire_WWyUp6Mxl1S3KYUG.json +++ b/src/packs/adversaries/adversary_Vampire_WWyUp6Mxl1S3KYUG.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 95, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "WWyUp6Mxl1S3KYUG", diff --git a/src/packs/adversaries/adversary_Vault_Guardian_Gaoler_JqYraOqNmmhHk4Yy.json b/src/packs/adversaries/adversary_Vault_Guardian_Gaoler_JqYraOqNmmhHk4Yy.json index 575d88ee..248ff278 100644 --- a/src/packs/adversaries/adversary_Vault_Guardian_Gaoler_JqYraOqNmmhHk4Yy.json +++ b/src/packs/adversaries/adversary_Vault_Guardian_Gaoler_JqYraOqNmmhHk4Yy.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 95, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "JqYraOqNmmhHk4Yy", diff --git a/src/packs/adversaries/adversary_Vault_Guardian_Sentinel_FVgYb28fhxlVcGwA.json b/src/packs/adversaries/adversary_Vault_Guardian_Sentinel_FVgYb28fhxlVcGwA.json index e0776c8c..bf525d9e 100644 --- a/src/packs/adversaries/adversary_Vault_Guardian_Sentinel_FVgYb28fhxlVcGwA.json +++ b/src/packs/adversaries/adversary_Vault_Guardian_Sentinel_FVgYb28fhxlVcGwA.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 96, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "FVgYb28fhxlVcGwA", diff --git a/src/packs/adversaries/adversary_Vault_Guardian_Turret_c5hGdvY5UnSjlHws.json b/src/packs/adversaries/adversary_Vault_Guardian_Turret_c5hGdvY5UnSjlHws.json index a11bef82..cf259cdb 100644 --- a/src/packs/adversaries/adversary_Vault_Guardian_Turret_c5hGdvY5UnSjlHws.json +++ b/src/packs/adversaries/adversary_Vault_Guardian_Turret_c5hGdvY5UnSjlHws.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 96, "artist": "" - } + }, + "size": "large" }, "flags": {}, "_id": "c5hGdvY5UnSjlHws", diff --git a/src/packs/adversaries/adversary_Volcanic_Dragon__Ashen_Tyrant_pMuXGCSOQaxpi5tb.json b/src/packs/adversaries/adversary_Volcanic_Dragon__Ashen_Tyrant_pMuXGCSOQaxpi5tb.json index 6f3d436e..25bc361c 100644 --- a/src/packs/adversaries/adversary_Volcanic_Dragon__Ashen_Tyrant_pMuXGCSOQaxpi5tb.json +++ b/src/packs/adversaries/adversary_Volcanic_Dragon__Ashen_Tyrant_pMuXGCSOQaxpi5tb.json @@ -150,7 +150,8 @@ "source": "Daggerheart SRD", "page": 101, "artist": "" - } + }, + "size": "gargantuan" }, "prototypeToken": { "name": "Volcanic Dragon: Ashen Tyrant", diff --git a/src/packs/adversaries/adversary_Volcanic_Dragon__Molten_Scourge_eArAPuB38CNR0ZIM.json b/src/packs/adversaries/adversary_Volcanic_Dragon__Molten_Scourge_eArAPuB38CNR0ZIM.json index 2fcc4ada..befbca6e 100644 --- a/src/packs/adversaries/adversary_Volcanic_Dragon__Molten_Scourge_eArAPuB38CNR0ZIM.json +++ b/src/packs/adversaries/adversary_Volcanic_Dragon__Molten_Scourge_eArAPuB38CNR0ZIM.json @@ -150,7 +150,8 @@ "source": "Daggerheart SRD", "page": 100, "artist": "" - } + }, + "size": "gargantuan" }, "prototypeToken": { "name": "Volcanic Dragon: Molten Scourge", diff --git a/src/packs/adversaries/adversary_Volcanic_Dragon__Obsidian_Predator_ladm7wykhZczYzrQ.json b/src/packs/adversaries/adversary_Volcanic_Dragon__Obsidian_Predator_ladm7wykhZczYzrQ.json index 1eb81b18..be007f4e 100644 --- a/src/packs/adversaries/adversary_Volcanic_Dragon__Obsidian_Predator_ladm7wykhZczYzrQ.json +++ b/src/packs/adversaries/adversary_Volcanic_Dragon__Obsidian_Predator_ladm7wykhZczYzrQ.json @@ -150,7 +150,8 @@ "source": "Daggerheart SRD", "page": 100, "artist": "" - } + }, + "size": "gargantuan" }, "prototypeToken": { "name": "Volcanic Dragon: Obsidian Predator", diff --git a/src/packs/adversaries/adversary_War_Wizard_noDdT0tsN6FXSmC8.json b/src/packs/adversaries/adversary_War_Wizard_noDdT0tsN6FXSmC8.json index efe20210..0bcb8e25 100644 --- a/src/packs/adversaries/adversary_War_Wizard_noDdT0tsN6FXSmC8.json +++ b/src/packs/adversaries/adversary_War_Wizard_noDdT0tsN6FXSmC8.json @@ -122,7 +122,8 @@ "source": "Daggerheart SRD", "page": 91, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "noDdT0tsN6FXSmC8", diff --git a/src/packs/adversaries/adversary_Weaponmaster_ZNbQ2jg35LG4t9eH.json b/src/packs/adversaries/adversary_Weaponmaster_ZNbQ2jg35LG4t9eH.json index 6319c895..01d1758b 100644 --- a/src/packs/adversaries/adversary_Weaponmaster_ZNbQ2jg35LG4t9eH.json +++ b/src/packs/adversaries/adversary_Weaponmaster_ZNbQ2jg35LG4t9eH.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 83, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "ZNbQ2jg35LG4t9eH", diff --git a/src/packs/adversaries/adversary_Young_Dryad_8yUj2Mzvnifhxegm.json b/src/packs/adversaries/adversary_Young_Dryad_8yUj2Mzvnifhxegm.json index 9cfb1884..fd978c58 100644 --- a/src/packs/adversaries/adversary_Young_Dryad_8yUj2Mzvnifhxegm.json +++ b/src/packs/adversaries/adversary_Young_Dryad_8yUj2Mzvnifhxegm.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 83, "artist": "" - } + }, + "size": "medium" }, "flags": {}, "_id": "8yUj2Mzvnifhxegm", diff --git a/src/packs/adversaries/adversary_Young_Ice_Dragon_UGPiPLJsPvMTSKEF.json b/src/packs/adversaries/adversary_Young_Ice_Dragon_UGPiPLJsPvMTSKEF.json index f025f45f..d42bda4e 100644 --- a/src/packs/adversaries/adversary_Young_Ice_Dragon_UGPiPLJsPvMTSKEF.json +++ b/src/packs/adversaries/adversary_Young_Ice_Dragon_UGPiPLJsPvMTSKEF.json @@ -117,7 +117,8 @@ "source": "Daggerheart SRD", "page": 96, "artist": "" - } + }, + "size": "huge" }, "flags": {}, "_id": "UGPiPLJsPvMTSKEF", diff --git a/src/packs/adversaries/adversary_Zombie_Legion_YhJrP7rTBiRdX5Fp.json b/src/packs/adversaries/adversary_Zombie_Legion_YhJrP7rTBiRdX5Fp.json index 0650319b..f93a0993 100644 --- a/src/packs/adversaries/adversary_Zombie_Legion_YhJrP7rTBiRdX5Fp.json +++ b/src/packs/adversaries/adversary_Zombie_Legion_YhJrP7rTBiRdX5Fp.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 101, "artist": "" - } + }, + "size": "huge" }, "flags": {}, "_id": "YhJrP7rTBiRdX5Fp", diff --git a/src/packs/adversaries/adversary_Zombie_Pack_Nf0v43rtflV56V2T.json b/src/packs/adversaries/adversary_Zombie_Pack_Nf0v43rtflV56V2T.json index 3e94c738..cf5520d6 100644 --- a/src/packs/adversaries/adversary_Zombie_Pack_Nf0v43rtflV56V2T.json +++ b/src/packs/adversaries/adversary_Zombie_Pack_Nf0v43rtflV56V2T.json @@ -111,7 +111,8 @@ "source": "Daggerheart SRD", "page": 84, "artist": "" - } + }, + "size": "huge" }, "flags": {}, "_id": "Nf0v43rtflV56V2T", diff --git a/src/packs/beastforms/beastform_Agile_Scout_a9UoCwtrbgKk02mK.json b/src/packs/beastforms/beastform_Agile_Scout_a9UoCwtrbgKk02mK.json index 58892f81..71018bc9 100644 --- a/src/packs/beastforms/beastform_Agile_Scout_a9UoCwtrbgKk02mK.json +++ b/src/packs/beastforms/beastform_Agile_Scout_a9UoCwtrbgKk02mK.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/mammals/rodent-rat-diseaed-gray.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "tiny" }, "mainTrait": "agility", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Aquatic_Predator_ItBVeCl2u5uetgy7.json b/src/packs/beastforms/beastform_Aquatic_Predator_ItBVeCl2u5uetgy7.json index 46610de3..5287de84 100644 --- a/src/packs/beastforms/beastform_Aquatic_Predator_ItBVeCl2u5uetgy7.json +++ b/src/packs/beastforms/beastform_Aquatic_Predator_ItBVeCl2u5uetgy7.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/fish/fish-marlin-swordfight-blue.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "large" }, "mainTrait": "agility", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Aquatic_Scout_qqzdFCxyYupWZK23.json b/src/packs/beastforms/beastform_Aquatic_Scout_qqzdFCxyYupWZK23.json index ef28f80c..95bea914 100644 --- a/src/packs/beastforms/beastform_Aquatic_Scout_qqzdFCxyYupWZK23.json +++ b/src/packs/beastforms/beastform_Aquatic_Scout_qqzdFCxyYupWZK23.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/tentacles/tentacles-octopus-black-pink.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "tiny" }, "mainTrait": "agility", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Armored_Sentry_8pUHJv3BYdjA4Qdf.json b/src/packs/beastforms/beastform_Armored_Sentry_8pUHJv3BYdjA4Qdf.json index 8b752488..ba18c05f 100644 --- a/src/packs/beastforms/beastform_Armored_Sentry_8pUHJv3BYdjA4Qdf.json +++ b/src/packs/beastforms/beastform_Armored_Sentry_8pUHJv3BYdjA4Qdf.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/reptiles/turtle-shell-glowing-green.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "small" }, "mainTrait": "strength", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Epic_Aquatic_Beast_wT4xbF99I55yjKZV.json b/src/packs/beastforms/beastform_Epic_Aquatic_Beast_wT4xbF99I55yjKZV.json index 710bb3c8..0dfe9c20 100644 --- a/src/packs/beastforms/beastform_Epic_Aquatic_Beast_wT4xbF99I55yjKZV.json +++ b/src/packs/beastforms/beastform_Epic_Aquatic_Beast_wT4xbF99I55yjKZV.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/fish/squid-kraken-teal.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "gargantuan" }, "mainTrait": "agility", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Great_Predator_afbMt4Ld6nY3mw0N.json b/src/packs/beastforms/beastform_Great_Predator_afbMt4Ld6nY3mw0N.json index 984c72c8..450a1312 100644 --- a/src/packs/beastforms/beastform_Great_Predator_afbMt4Ld6nY3mw0N.json +++ b/src/packs/beastforms/beastform_Great_Predator_afbMt4Ld6nY3mw0N.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/mammals/wolf-shadow-black.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "large" }, "mainTrait": "strength", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Great_Winged_Beast_b4BMnTbJ3iPPidSb.json b/src/packs/beastforms/beastform_Great_Winged_Beast_b4BMnTbJ3iPPidSb.json index 444fda44..c04b2182 100644 --- a/src/packs/beastforms/beastform_Great_Winged_Beast_b4BMnTbJ3iPPidSb.json +++ b/src/packs/beastforms/beastform_Great_Winged_Beast_b4BMnTbJ3iPPidSb.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/birds/corvid-flying-wings-purple.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "large" }, "mainTrait": "finesse", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Household_Friend_iDmOtiHJJ80AIAVT.json b/src/packs/beastforms/beastform_Household_Friend_iDmOtiHJJ80AIAVT.json index 80756af0..cfb6aea7 100644 --- a/src/packs/beastforms/beastform_Household_Friend_iDmOtiHJJ80AIAVT.json +++ b/src/packs/beastforms/beastform_Household_Friend_iDmOtiHJJ80AIAVT.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/mammals/rabbit-movement-glowing-green.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "tiny" }, "mainTrait": "instinct", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Massive_Behemoth_qjwMzPn33aKZACkv.json b/src/packs/beastforms/beastform_Massive_Behemoth_qjwMzPn33aKZACkv.json index 8e3c0ce5..35715056 100644 --- a/src/packs/beastforms/beastform_Massive_Behemoth_qjwMzPn33aKZACkv.json +++ b/src/packs/beastforms/beastform_Massive_Behemoth_qjwMzPn33aKZACkv.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/mammals/beast-horned-scaled-glowing-orange.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "huge" }, "mainTrait": "strength", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Mighty_Lizard_94tvcC3D5Kp4lzuN.json b/src/packs/beastforms/beastform_Mighty_Lizard_94tvcC3D5Kp4lzuN.json index 4dcb396a..390bf054 100644 --- a/src/packs/beastforms/beastform_Mighty_Lizard_94tvcC3D5Kp4lzuN.json +++ b/src/packs/beastforms/beastform_Mighty_Lizard_94tvcC3D5Kp4lzuN.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/reptiles/lizard-iguana-green.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "large" }, "mainTrait": "instinct", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Mighty_Strider_zRLjqKx4Rn2TjivL.json b/src/packs/beastforms/beastform_Mighty_Strider_zRLjqKx4Rn2TjivL.json index f77c7b5d..adb9627b 100644 --- a/src/packs/beastforms/beastform_Mighty_Strider_zRLjqKx4Rn2TjivL.json +++ b/src/packs/beastforms/beastform_Mighty_Strider_zRLjqKx4Rn2TjivL.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/environment/creatures/horse-tan.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "large" }, "mainTrait": "agility", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Mythic_Aerial_Hunter_jV6EuEacyQlHW4SN.json b/src/packs/beastforms/beastform_Mythic_Aerial_Hunter_jV6EuEacyQlHW4SN.json index 34898d53..dc373c27 100644 --- a/src/packs/beastforms/beastform_Mythic_Aerial_Hunter_jV6EuEacyQlHW4SN.json +++ b/src/packs/beastforms/beastform_Mythic_Aerial_Hunter_jV6EuEacyQlHW4SN.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/reptiles/dragon-winged-blue.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "gargantuan" }, "mainTrait": "finesse", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Nimble_Grazer_CItO8yX6amQaqyk7.json b/src/packs/beastforms/beastform_Nimble_Grazer_CItO8yX6amQaqyk7.json index 08d83325..183ad150 100644 --- a/src/packs/beastforms/beastform_Nimble_Grazer_CItO8yX6amQaqyk7.json +++ b/src/packs/beastforms/beastform_Nimble_Grazer_CItO8yX6amQaqyk7.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/mammals/deer-antlers-glowing-blue.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "medium" }, "mainTrait": "agility", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Pack_Predator_YLisKYYhAGca50WM.json b/src/packs/beastforms/beastform_Pack_Predator_YLisKYYhAGca50WM.json index 58d28e2d..834493bb 100644 --- a/src/packs/beastforms/beastform_Pack_Predator_YLisKYYhAGca50WM.json +++ b/src/packs/beastforms/beastform_Pack_Predator_YLisKYYhAGca50WM.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/mammals/wolf-howl-moon-forest-blue.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "medium" }, "mainTrait": "strength", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Pouncing_Predator_33oFSZ1PwFqInHPe.json b/src/packs/beastforms/beastform_Pouncing_Predator_33oFSZ1PwFqInHPe.json index 5df71fd3..d172d8f3 100644 --- a/src/packs/beastforms/beastform_Pouncing_Predator_33oFSZ1PwFqInHPe.json +++ b/src/packs/beastforms/beastform_Pouncing_Predator_33oFSZ1PwFqInHPe.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/abilities/cougar-roar-rush-orange.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "medium" }, "mainTrait": "instinct", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Powerful_Beast_m8BVTuJI1wCvzTcf.json b/src/packs/beastforms/beastform_Powerful_Beast_m8BVTuJI1wCvzTcf.json index bbbc9a66..7fa832e6 100644 --- a/src/packs/beastforms/beastform_Powerful_Beast_m8BVTuJI1wCvzTcf.json +++ b/src/packs/beastforms/beastform_Powerful_Beast_m8BVTuJI1wCvzTcf.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/abilities/bear-roar-bite-brown-green.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "large" }, "mainTrait": "strength", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Stalking_Arachnid_A4TVRY0D5r9EiVwA.json b/src/packs/beastforms/beastform_Stalking_Arachnid_A4TVRY0D5r9EiVwA.json index dc1ba68f..16520a9c 100644 --- a/src/packs/beastforms/beastform_Stalking_Arachnid_A4TVRY0D5r9EiVwA.json +++ b/src/packs/beastforms/beastform_Stalking_Arachnid_A4TVRY0D5r9EiVwA.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/invertebrates/spider-mandibles-brown.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "tiny" }, "mainTrait": "finesse", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Striking_Serpent_1XrZWGDttBAAUxR1.json b/src/packs/beastforms/beastform_Striking_Serpent_1XrZWGDttBAAUxR1.json index 1cdf3fa3..f78500c9 100644 --- a/src/packs/beastforms/beastform_Striking_Serpent_1XrZWGDttBAAUxR1.json +++ b/src/packs/beastforms/beastform_Striking_Serpent_1XrZWGDttBAAUxR1.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/reptiles/serpent-horned-green.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "small" }, "mainTrait": "finesse", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Terrible_Lizard_5BABxRe2XVrYTj8N.json b/src/packs/beastforms/beastform_Terrible_Lizard_5BABxRe2XVrYTj8N.json index d15fa0d9..49818b74 100644 --- a/src/packs/beastforms/beastform_Terrible_Lizard_5BABxRe2XVrYTj8N.json +++ b/src/packs/beastforms/beastform_Terrible_Lizard_5BABxRe2XVrYTj8N.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/abilities/dragon-breath-purple.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "gargantuan" }, "mainTrait": "strength", "advantageOn": { diff --git a/src/packs/beastforms/beastform_Winged_Beast_mZ4Wlqtss2FlNNvL.json b/src/packs/beastforms/beastform_Winged_Beast_mZ4Wlqtss2FlNNvL.json index cc78e6a4..4ca44471 100644 --- a/src/packs/beastforms/beastform_Winged_Beast_mZ4Wlqtss2FlNNvL.json +++ b/src/packs/beastforms/beastform_Winged_Beast_mZ4Wlqtss2FlNNvL.json @@ -9,7 +9,8 @@ "tokenRingImg": "icons/creatures/birds/raptor-owl-flying-moon.webp", "tokenSize": { "height": null, - "width": null + "width": null, + "size": "tiny" }, "mainTrait": "finesse", "advantageOn": { diff --git a/styles/less/sheets/actors/adversary/header.less b/styles/less/sheets/actors/adversary/header.less index aa3e6e83..8bd3fcee 100644 --- a/styles/less/sheets/actors/adversary/header.less +++ b/styles/less/sheets/actors/adversary/header.less @@ -40,6 +40,7 @@ .tag { display: flex; flex-direction: row; + gap: 4px; justify-content: center; align-items: center; padding: 3px 5px; diff --git a/styles/less/sheets/items/beastform.less b/styles/less/sheets/items/beastform.less index 162c4925..100b024a 100644 --- a/styles/less/sheets/items/beastform.less +++ b/styles/less/sheets/items/beastform.less @@ -5,5 +5,8 @@ flex-direction: column; margin-top: 10px; } + .hint { + font-style: italic; + } } } diff --git a/styles/less/ui/settings/settings.less b/styles/less/ui/settings/settings.less index 49c9fc7c..34f17d53 100644 --- a/styles/less/ui/settings/settings.less +++ b/styles/less/ui/settings/settings.less @@ -16,6 +16,12 @@ } } + &.three-columns { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + gap: 2px; + } + &.six-columns { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr; diff --git a/templates/settings/homebrew-settings/settings.hbs b/templates/settings/homebrew-settings/settings.hbs index e7340323..5da053f4 100644 --- a/templates/settings/homebrew-settings/settings.hbs +++ b/templates/settings/homebrew-settings/settings.hbs @@ -25,6 +25,20 @@ {{/each}}
+
+ + {{localize "Token Sizes"}} + + + + {{formGroup settingFields.schema.fields.tokenSizes.fields.tiny value=settingFields._source.tokenSizes.tiny localize=true}} + {{formGroup settingFields.schema.fields.tokenSizes.fields.small value=settingFields._source.tokenSizes.small localize=true}} + {{formGroup settingFields.schema.fields.tokenSizes.fields.medium value=settingFields._source.tokenSizes.medium localize=true}} + {{formGroup settingFields.schema.fields.tokenSizes.fields.large value=settingFields._source.tokenSizes.large localize=true}} + {{formGroup settingFields.schema.fields.tokenSizes.fields.huge value=settingFields._source.tokenSizes.huge localize=true}} + {{formGroup settingFields.schema.fields.tokenSizes.fields.gargantuan value=settingFields._source.tokenSizes.gargantuan localize=true}} +
+
{{localize "DAGGERHEART.SETTINGS.Homebrew.currency.title"}} diff --git a/templates/sheets-settings/adversary-settings/details.hbs b/templates/sheets-settings/adversary-settings/details.hbs index 194c7f0c..0eb8da30 100644 --- a/templates/sheets-settings/adversary-settings/details.hbs +++ b/templates/sheets-settings/adversary-settings/details.hbs @@ -13,6 +13,7 @@ {{/if}} {{formGroup systemFields.difficulty value=document._source.system.difficulty localize=true}} + {{formGroup systemFields.size value=document._source.system.size label=(localize "DAGGERHEART.GENERAL.tokenSize") localize=true}} {{formField systemFields.description value=document._source.system.description label=(localize "DAGGERHEART.ACTORS.Adversary.FIELDS.description.label")}} {{formField systemFields.motivesAndTactics value=document._source.system.motivesAndTactics label=(localize "DAGGERHEART.ACTORS.Adversary.FIELDS.motivesAndTactics.label")}}
diff --git a/templates/sheets-settings/token-config/appearance.hbs b/templates/sheets-settings/token-config/appearance.hbs new file mode 100644 index 00000000..0f6019ba --- /dev/null +++ b/templates/sheets-settings/token-config/appearance.hbs @@ -0,0 +1,82 @@ +
+ {{formGroup fields.texture.fields.src value=source.texture.src rootId=rootId}} + {{#if randomImgEnabled}} + {{formGroup fields.randomImg value=source.randomImg classes="slim" rootId=rootId}} + {{else if hasAlternates}} +
+ + +
+ {{/if}} + + +
+ +
+ + {{formInput fields.width value=source.width id=(concat rootId "-width") disabled=actorSizeUsed}} + + {{formInput fields.height value=source.height id=(concat rootId "-height") disabled=actorSizeUsed}} +
+
+ + {{#if shapes}} + {{formGroup fields.shape value=source.shape choices=shapes classes="slim" rootId=rootId}} + {{/if}} + {{formGroup fields.texture.fields.fit value=source.texture.fit choices=textureFitModes classes="slim" rootId=rootId}} + +
+ +
+ + {{formInput fields.texture.fields.anchorX value=source.texture.anchorX id=(concat rootId "-anchorX") + placeholder="0.5"}} + + {{formInput fields.texture.fields.anchorY value=source.texture.anchorY id=(concat rootId "-anchorY") + placeholder="0.5"}} +
+

{{localize "TOKEN.AnchorHint"}}

+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+
+ + {{formGroup fields.texture.fields.tint value=source.texture.tint placeholder="#ffffff" rootId=rootId}} + {{formGroup fields.alpha value=source.alpha step=0.05 rootId=rootId}} + {{formGroup fields.lockRotation value=source.lockRotation rootId=rootId}} + +
+ {{localize "TOKEN.RING.SHEET.legend"}} + {{formGroup fields.ring.fields.enabled value=source.ring.enabled rootId=rootId}} + {{formGroup fields.ring.fields.colors.fields.ring value=source.ring.colors.ring rootId=rootId}} + {{formGroup fields.ring.fields.colors.fields.background value=source.ring.colors.background rootId=rootId}} + {{formGroup fields.ring.fields.subject.fields.texture value=source.ring.subject.texture rootId=rootId}} + {{formGroup fields.ring.fields.subject.fields.scale value=source.ring.subject.scale max=3 step=0.02 rootId=rootId}} + {{formGroup fields.ring.fields.effects value=source.ring.effects input=ringEffectsInput stacked=true rootId=rootId}} +
+
diff --git a/templates/sheets/actors/adversary/header.hbs b/templates/sheets/actors/adversary/header.hbs index 42a673d5..5bdfa421 100644 --- a/templates/sheets/actors/adversary/header.hbs +++ b/templates/sheets/actors/adversary/header.hbs @@ -18,6 +18,14 @@ /{{localize "DAGGERHEART.GENERAL.HitPoints.short"}} {{/if}} +
+ + {{#unless (eq source.system.size 'custom')}} + {{localize (concat "DAGGERHEART.CONFIG.TokenSize." source.system.size)}} + {{else}} + {{source.prototypeToken.width}}x{{source.prototypeToken.height}} + {{/unless}} +
diff --git a/templates/sheets/items/beastform/settings.hbs b/templates/sheets/items/beastform/settings.hbs index c0ea3965..844b9d61 100644 --- a/templates/sheets/items/beastform/settings.hbs +++ b/templates/sheets/items/beastform/settings.hbs @@ -20,18 +20,35 @@ {{/unless}} {{/if}} -
+
{{localize "DAGGERHEART.ITEMS.Beastform.tokenTitle"}} + {{#unless (eq source.system.beastformType 'evolved')}} +
+ {{formGroup systemFields.tokenImg value=source.system.tokenImg localize=true}} +
-
- {{formGroup systemFields.tokenImg value=source.system.tokenImg localize=true}} -
- -
- {{formGroup systemFields.tokenRingImg value=source.system.tokenRingImg localize=true}} -
- - {{formGroup systemFields.tokenSize.fields.height value=source.system.tokenSize.height localize=true placeholder=(localize "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.placeholder") }} - {{formGroup systemFields.tokenSize.fields.width value=source.system.tokenSize.width localize=true placeholder=(localize "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.placeholder")}} +
+ {{formGroup systemFields.tokenRingImg value=source.system.tokenRingImg localize=true}} +
+
+ {{formGroup systemFields.tokenSize.fields.size value=source.system.tokenSize.size label=(localize "DAGGERHEART.GENERAL.tokenSize") localize=true }} + {{formGroup + systemFields.tokenSize.fields.height + value=source.system.tokenSize.height + localize=true + placeholder=(localize (ifThen dimensionsDisabled "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.disabledPlaceholder" "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.placeholder")) + disabled=dimensionsDisabled + }} + {{formGroup + systemFields.tokenSize.fields.width + value=source.system.tokenSize.width + localize=true + placeholder=(localize (ifThen dimensionsDisabled "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.disabledPlaceholder" "DAGGERHEART.ITEMS.Beastform.FIELDS.tokenSize.placeholder")) + disabled=dimensionsDisabled + }} +
+ {{else}} + {{localize "DAGGERHEART.ITEMS.Beastform.evolvedTokenHint"}} + {{/unless}}
\ No newline at end of file From 790a5b4938232241e1d4f4b46b845d14e81ad74a Mon Sep 17 00:00:00 2001 From: Nikhil Nagarajan Date: Mon, 22 Dec 2025 10:59:22 -0500 Subject: [PATCH 15/17] Adding in more details in authors - Ikraik (#1457) --- system.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/system.json b/system.json index 14a4efc8..b9aada8c 100644 --- a/system.json +++ b/system.json @@ -20,6 +20,9 @@ }, { "name": "Ikraik" + "url": "https://github.com/ikraik", + "email": "ikraik0.0gaming@gmail.com", + "discord": "ikraik" }, { "name": "IrkTheImp" From f0531d3587291e2bfffba8ccdabd7b2435c61d7f Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Mon, 22 Dec 2025 17:03:49 +0100 Subject: [PATCH 16/17] [Fix] Sheet Labels (#1456) * Added human readable sheet labels to all sheets * Prefixed sheet labels with 'Default DH' * :carpentry_saw: --- daggerheart.mjs | 102 ++++++++++++++++++++++++++++++++++++++---------- lang/en.json | 2 + 2 files changed, 84 insertions(+), 20 deletions(-) diff --git a/daggerheart.mjs b/daggerheart.mjs index 08a1be02..f1d8c67a 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -90,34 +90,94 @@ Hooks.once('init', () => { makeDefault: true }); + const sheetLabel = typePath => () => + game.i18n.format('DAGGERHEART.GENERAL.typeSheet', { + type: game.i18n.localize(typePath) + }); + const { Items, Actors } = foundry.documents.collections; Items.unregisterSheet('core', foundry.applications.sheets.ItemSheetV2); - Items.registerSheet(SYSTEM.id, applications.sheets.items.Ancestry, { types: ['ancestry'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.sheets.items.Community, { types: ['community'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.sheets.items.Class, { types: ['class'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.sheets.items.Subclass, { types: ['subclass'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.sheets.items.Feature, { types: ['feature'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.sheets.items.DomainCard, { types: ['domainCard'], makeDefault: true }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Ancestry, { + types: ['ancestry'], + makeDefault: true, + label: sheetLabel('TYPES.Item.ancestry') + }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Community, { + types: ['community'], + makeDefault: true, + label: sheetLabel('TYPES.Item.community') + }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Class, { + types: ['class'], + makeDefault: true, + label: sheetLabel('TYPES.Item.class') + }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Subclass, { + types: ['subclass'], + makeDefault: true, + label: sheetLabel('TYPES.Item.subclass') + }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Feature, { + types: ['feature'], + makeDefault: true, + label: sheetLabel('TYPES.Item.feature') + }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.DomainCard, { + types: ['domainCard'], + makeDefault: true, + label: sheetLabel('TYPES.Item.domainCard') + }); Items.registerSheet(SYSTEM.id, applications.sheets.items.Loot, { types: ['loot'], - makeDefault: true + makeDefault: true, + label: sheetLabel('TYPES.Item.loot') + }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Consumable, { + types: ['consumable'], + makeDefault: true, + label: sheetLabel('TYPES.Item.consumable') + }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Weapon, { + types: ['weapon'], + makeDefault: true, + label: sheetLabel('TYPES.Item.weapon') + }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Armor, { + types: ['armor'], + makeDefault: true, + label: sheetLabel('TYPES.Item.armor') + }); + Items.registerSheet(SYSTEM.id, applications.sheets.items.Beastform, { + types: ['beastform'], + makeDefault: true, + label: sheetLabel('TYPES.Item.beastform') }); - Items.registerSheet(SYSTEM.id, applications.sheets.items.Consumable, { types: ['consumable'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.sheets.items.Weapon, { types: ['weapon'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.sheets.items.Armor, { types: ['armor'], makeDefault: true }); - Items.registerSheet(SYSTEM.id, applications.sheets.items.Beastform, { types: ['beastform'], makeDefault: true }); Actors.unregisterSheet('core', foundry.applications.sheets.ActorSheetV2); - Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Character, { types: ['character'], makeDefault: true }); - Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Companion, { types: ['companion'], makeDefault: true }); - Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Adversary, { types: ['adversary'], makeDefault: true }); + Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Character, { + types: ['character'], + makeDefault: true, + label: sheetLabel('TYPES.Actor.character') + }); + Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Companion, { + types: ['companion'], + makeDefault: true, + label: sheetLabel('TYPES.Actor.companion') + }); + Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Adversary, { + types: ['adversary'], + makeDefault: true, + label: sheetLabel('TYPES.Actor.adversary') + }); Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Environment, { types: ['environment'], - makeDefault: true + makeDefault: true, + label: sheetLabel('TYPES.Actor.environment') }); Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Party, { types: ['party'], - makeDefault: true + makeDefault: true, + label: sheetLabel('TYPES.Actor.party') }); DocumentSheetConfig.unregisterSheet( @@ -130,7 +190,8 @@ Hooks.once('init', () => { SYSTEM.id, applications.sheetConfigs.ActiveEffectConfig, { - makeDefault: true + makeDefault: true, + label: sheetLabel('DOCUMENT.ActiveEffect') } ); @@ -139,9 +200,10 @@ Hooks.once('init', () => { // Make Compendium Dialog resizable foundry.applications.sidebar.apps.Compendium.DEFAULT_OPTIONS.window.resizable = true; + DocumentSheetConfig.unregisterSheet(foundry.documents.Scene, 'core', foundry.applications.sheets.SceneConfig); DocumentSheetConfig.registerSheet(foundry.documents.Scene, SYSTEM.id, applications.scene.DhSceneConfigSettings, { makeDefault: true, - label: 'Daggerheart' + label: sheetLabel('DOCUMENT.Scene') }); settingsRegistration.registerDHSettings(); @@ -248,7 +310,7 @@ Hooks.on('chatMessage', (_, message) => { } }); -const updateActorsRangeDependentEffects = async (token) => { +const updateActorsRangeDependentEffects = async token => { const rangeMeasurement = game.settings.get( CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules @@ -283,7 +345,7 @@ const updateActorsRangeDependentEffects = async (token) => { await effect.update({ disabled: !enabledEffect }); } -} +}; const updateAllRangeDependentEffects = async () => { const effectsAutomation = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).effects; diff --git a/lang/en.json b/lang/en.json index 498a45cb..6e9a2489 100755 --- a/lang/en.json +++ b/lang/en.json @@ -36,6 +36,7 @@ }, "DAGGERHEART": { + "CharacterSheet": "Character Sheet", "ACTIONS": { "TYPES": { "attack": { @@ -2184,6 +2185,7 @@ "traitModifier": "Trait Modifier", "true": "True", "type": "Type", + "typeSheet": "System {type} Sheet", "unarmed": "Unarmed", "unarmedAttack": "Unarmed Attack", "unarmored": "Unarmored", From 51eadc499f9f46d18ea8d523f5d315658fdef4eb Mon Sep 17 00:00:00 2001 From: WBHarry Date: Mon, 22 Dec 2025 17:06:43 +0100 Subject: [PATCH 17/17] Corrected system.json syntax --- system.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system.json b/system.json index b9aada8c..a58f23db 100644 --- a/system.json +++ b/system.json @@ -19,7 +19,7 @@ "discord": "cptn_cosmo" }, { - "name": "Ikraik" + "name": "Ikraik", "url": "https://github.com/ikraik", "email": "ikraik0.0gaming@gmail.com", "discord": "ikraik"