mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
Merge branch 'main' into feature/death-moves
This commit is contained in:
commit
9a3355175b
229 changed files with 2452 additions and 893 deletions
190
daggerheart.mjs
190
daggerheart.mjs
|
|
@ -18,7 +18,6 @@ import {
|
||||||
socketRegistration
|
socketRegistration
|
||||||
} from './module/systemRegistration/_module.mjs';
|
} from './module/systemRegistration/_module.mjs';
|
||||||
import { placeables } from './module/canvas/_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 './node_modules/@yaireo/tagify/dist/tagify.css';
|
||||||
import TemplateManager from './module/documents/templateManager.mjs';
|
import TemplateManager from './module/documents/templateManager.mjs';
|
||||||
|
|
||||||
|
|
@ -56,6 +55,8 @@ CONFIG.Canvas.rulerClass = placeables.DhRuler;
|
||||||
CONFIG.Canvas.layers.templates.layerClass = placeables.DhTemplateLayer;
|
CONFIG.Canvas.layers.templates.layerClass = placeables.DhTemplateLayer;
|
||||||
CONFIG.MeasuredTemplate.objectClass = placeables.DhMeasuredTemplate;
|
CONFIG.MeasuredTemplate.objectClass = placeables.DhMeasuredTemplate;
|
||||||
|
|
||||||
|
CONFIG.Scene.documentClass = documents.DhScene;
|
||||||
|
|
||||||
CONFIG.Token.documentClass = documents.DhToken;
|
CONFIG.Token.documentClass = documents.DhToken;
|
||||||
CONFIG.Token.prototypeSheetClass = applications.sheetConfigs.DhPrototypeTokenConfig;
|
CONFIG.Token.prototypeSheetClass = applications.sheetConfigs.DhPrototypeTokenConfig;
|
||||||
CONFIG.Token.objectClass = placeables.DhTokenPlaceable;
|
CONFIG.Token.objectClass = placeables.DhTokenPlaceable;
|
||||||
|
|
@ -91,34 +92,94 @@ Hooks.once('init', () => {
|
||||||
makeDefault: true
|
makeDefault: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const sheetLabel = typePath => () =>
|
||||||
|
game.i18n.format('DAGGERHEART.GENERAL.typeSheet', {
|
||||||
|
type: game.i18n.localize(typePath)
|
||||||
|
});
|
||||||
|
|
||||||
const { Items, Actors } = foundry.documents.collections;
|
const { Items, Actors } = foundry.documents.collections;
|
||||||
Items.unregisterSheet('core', foundry.applications.sheets.ItemSheetV2);
|
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.Ancestry, {
|
||||||
Items.registerSheet(SYSTEM.id, applications.sheets.items.Community, { types: ['community'], makeDefault: true });
|
types: ['ancestry'],
|
||||||
Items.registerSheet(SYSTEM.id, applications.sheets.items.Class, { types: ['class'], makeDefault: true });
|
makeDefault: true,
|
||||||
Items.registerSheet(SYSTEM.id, applications.sheets.items.Subclass, { types: ['subclass'], makeDefault: true });
|
label: sheetLabel('TYPES.Item.ancestry')
|
||||||
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.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, {
|
Items.registerSheet(SYSTEM.id, applications.sheets.items.Loot, {
|
||||||
types: ['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.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.Character, {
|
||||||
Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Companion, { types: ['companion'], makeDefault: true });
|
types: ['character'],
|
||||||
Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Adversary, { types: ['adversary'], makeDefault: true });
|
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, {
|
Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Environment, {
|
||||||
types: ['environment'],
|
types: ['environment'],
|
||||||
makeDefault: true
|
makeDefault: true,
|
||||||
|
label: sheetLabel('TYPES.Actor.environment')
|
||||||
});
|
});
|
||||||
Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Party, {
|
Actors.registerSheet(SYSTEM.id, applications.sheets.actors.Party, {
|
||||||
types: ['party'],
|
types: ['party'],
|
||||||
makeDefault: true
|
makeDefault: true,
|
||||||
|
label: sheetLabel('TYPES.Actor.party')
|
||||||
});
|
});
|
||||||
|
|
||||||
DocumentSheetConfig.unregisterSheet(
|
DocumentSheetConfig.unregisterSheet(
|
||||||
|
|
@ -131,7 +192,8 @@ Hooks.once('init', () => {
|
||||||
SYSTEM.id,
|
SYSTEM.id,
|
||||||
applications.sheetConfigs.ActiveEffectConfig,
|
applications.sheetConfigs.ActiveEffectConfig,
|
||||||
{
|
{
|
||||||
makeDefault: true
|
makeDefault: true,
|
||||||
|
label: sheetLabel('DOCUMENT.ActiveEffect')
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -140,9 +202,10 @@ Hooks.once('init', () => {
|
||||||
// Make Compendium Dialog resizable
|
// Make Compendium Dialog resizable
|
||||||
foundry.applications.sidebar.apps.Compendium.DEFAULT_OPTIONS.window.resizable = true;
|
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, {
|
DocumentSheetConfig.registerSheet(foundry.documents.Scene, SYSTEM.id, applications.scene.DhSceneConfigSettings, {
|
||||||
makeDefault: true,
|
makeDefault: true,
|
||||||
label: 'Daggerheart'
|
label: sheetLabel('DOCUMENT.Scene')
|
||||||
});
|
});
|
||||||
|
|
||||||
settingsRegistration.registerDHSettings();
|
settingsRegistration.registerDHSettings();
|
||||||
|
|
@ -179,7 +242,6 @@ Hooks.on('ready', async () => {
|
||||||
ui.compendiumBrowser = new applications.ui.ItemBrowser();
|
ui.compendiumBrowser = new applications.ui.ItemBrowser();
|
||||||
|
|
||||||
socketRegistration.registerSocketHooks();
|
socketRegistration.registerSocketHooks();
|
||||||
registerRollDiceHooks();
|
|
||||||
socketRegistration.registerUserQueries();
|
socketRegistration.registerUserQueries();
|
||||||
|
|
||||||
if (!game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.userFlags.welcomeMessage)) {
|
if (!game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.userFlags.welcomeMessage)) {
|
||||||
|
|
@ -195,9 +257,9 @@ Hooks.on('ready', async () => {
|
||||||
|
|
||||||
Hooks.once('dicesoniceready', () => {});
|
Hooks.once('dicesoniceready', () => {});
|
||||||
|
|
||||||
Hooks.on('renderChatMessageHTML', (_, element, message) => {
|
Hooks.on('renderChatMessageHTML', (document, element) => {
|
||||||
enricherRenderSetup(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));
|
if (cssClass) cssClass.split(' ').forEach(cls => element.classList.add(cls));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -282,52 +344,70 @@ Hooks.on('chatMessage', (_, message) => {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Hooks.on('moveToken', async (movedToken, data) => {
|
const updateActorsRangeDependentEffects = async token => {
|
||||||
const effectsAutomation = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).effects;
|
const rangeMeasurement = game.settings.get(
|
||||||
if (!effectsAutomation.rangeDependent) return;
|
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) => {
|
// If there are no targets, assume false. Otherwise, start with the effect enabled.
|
||||||
const rangeMeasurement = game.settings.get(
|
let enabledEffect = game.user.targets.size !== 0;
|
||||||
CONFIG.DH.id,
|
// Expect all targets to meet the rangeDependence requirements
|
||||||
CONFIG.DH.SETTINGS.gameSettings.variantRules
|
for (let userTarget of game.user.targets) {
|
||||||
).rangeMeasurement;
|
const disposition = userTarget.document.disposition;
|
||||||
|
if ((target === 'friendly' && disposition !== 1) || (target === 'hostile' && disposition !== -1)) {
|
||||||
for (let effect of effects.filter(x => x.system.rangeDependence?.enabled)) {
|
enabledEffect = false;
|
||||||
const { target, range, type } = effect.system.rangeDependence;
|
break;
|
||||||
if ((target === 'friendly' && disposition !== 1) || (target === 'hostile' && disposition !== -1))
|
}
|
||||||
return false;
|
|
||||||
|
|
||||||
const distanceBetween = canvas.grid.measurePath([
|
const distanceBetween = canvas.grid.measurePath([
|
||||||
{ ...movedToken.toObject(), x: data.destination.x, y: data.destination.y },
|
userTarget.document.movement.destination,
|
||||||
token
|
token.movement.destination
|
||||||
]).distance;
|
]).distance;
|
||||||
const distance = rangeMeasurement[range];
|
const distance = rangeMeasurement[range];
|
||||||
|
|
||||||
const reverse = type === CONFIG.DH.GENERAL.rangeInclusion.outsideRange.id;
|
const reverse = type === CONFIG.DH.GENERAL.rangeInclusion.outsideRange.id;
|
||||||
const newDisabled = reverse ? distanceBetween <= distance : distanceBetween > distance;
|
if (reverse ? distanceBetween <= distance : distanceBetween > distance) {
|
||||||
const oldDisabled = effectUpdates[effect.uuid] ? effectUpdates[effect.uuid].disabled : newDisabled;
|
enabledEffect = false;
|
||||||
effectUpdates[effect.uuid] = {
|
break;
|
||||||
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 (token.actor) await updateEffects(movedToken.disposition, token, token.actor.effects, effectUpdates);
|
await effect.update({ disabled: !enabledEffect });
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for (let key in effectUpdates) {
|
const updateAllRangeDependentEffects = async () => {
|
||||||
const effect = effectUpdates[key];
|
const effectsAutomation = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).effects;
|
||||||
await effect.value.update({ disabled: effect.disabled });
|
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));
|
Hooks.on('renderCompendiumDirectory', (app, html) => applications.ui.ItemBrowser.injectSidebarButton(html));
|
||||||
|
|
|
||||||
38
lang/en.json
38
lang/en.json
|
|
@ -36,6 +36,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"DAGGERHEART": {
|
"DAGGERHEART": {
|
||||||
|
"CharacterSheet": "Character Sheet",
|
||||||
"ACTIONS": {
|
"ACTIONS": {
|
||||||
"TYPES": {
|
"TYPES": {
|
||||||
"attack": {
|
"attack": {
|
||||||
|
|
@ -611,6 +612,9 @@
|
||||||
"insufficientHope": "The initiating character doesn't have enough hope",
|
"insufficientHope": "The initiating character doesn't have enough hope",
|
||||||
"createTagTeam": "Create TagTeam Roll",
|
"createTagTeam": "Create TagTeam Roll",
|
||||||
"chatMessageRollTitle": "Roll"
|
"chatMessageRollTitle": "Roll"
|
||||||
|
},
|
||||||
|
"TokenConfig": {
|
||||||
|
"actorSizeUsed": "Actor size is set, determining the dimensions"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"CLASS": {
|
"CLASS": {
|
||||||
|
|
@ -620,11 +624,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"CONFIG": {
|
"CONFIG": {
|
||||||
"ActionType": {
|
|
||||||
"passive": "Passive",
|
|
||||||
"action": "Action",
|
|
||||||
"reaction": "Reaction"
|
|
||||||
},
|
|
||||||
"AdversaryTrait": {
|
"AdversaryTrait": {
|
||||||
"relentless": {
|
"relentless": {
|
||||||
"name": "Relentless",
|
"name": "Relentless",
|
||||||
|
|
@ -1033,6 +1032,12 @@
|
||||||
"description": ""
|
"description": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"FeatureForm": {
|
||||||
|
"label": "Feature Form",
|
||||||
|
"passive": "Passive",
|
||||||
|
"action": "Action",
|
||||||
|
"reaction": "Reaction"
|
||||||
|
},
|
||||||
"Gold": {
|
"Gold": {
|
||||||
"title": "Gold",
|
"title": "Gold",
|
||||||
"coins": "Coins",
|
"coins": "Coins",
|
||||||
|
|
@ -1146,6 +1151,14 @@
|
||||||
"rect": "Rectangle",
|
"rect": "Rectangle",
|
||||||
"ray": "Ray"
|
"ray": "Ray"
|
||||||
},
|
},
|
||||||
|
"TokenSize": {
|
||||||
|
"tiny": "Tiny",
|
||||||
|
"small": "Small",
|
||||||
|
"medium": "Medium",
|
||||||
|
"large": "Large",
|
||||||
|
"huge": "Huge",
|
||||||
|
"gargantuan": "Gargantuan"
|
||||||
|
},
|
||||||
"Traits": {
|
"Traits": {
|
||||||
"agility": {
|
"agility": {
|
||||||
"name": "Agility",
|
"name": "Agility",
|
||||||
|
|
@ -2096,6 +2109,7 @@
|
||||||
"fear": "Fear",
|
"fear": "Fear",
|
||||||
"features": "Features",
|
"features": "Features",
|
||||||
"formula": "Formula",
|
"formula": "Formula",
|
||||||
|
"general": "General",
|
||||||
"gm": "GM",
|
"gm": "GM",
|
||||||
"healing": "Healing",
|
"healing": "Healing",
|
||||||
"healingRoll": "Healing Roll",
|
"healingRoll": "Healing Roll",
|
||||||
|
|
@ -2168,10 +2182,12 @@
|
||||||
"plural": "Targets"
|
"plural": "Targets"
|
||||||
},
|
},
|
||||||
"title": "Title",
|
"title": "Title",
|
||||||
|
"tokenSize": "Token Size",
|
||||||
"total": "Total",
|
"total": "Total",
|
||||||
"traitModifier": "Trait Modifier",
|
"traitModifier": "Trait Modifier",
|
||||||
"true": "True",
|
"true": "True",
|
||||||
"type": "Type",
|
"type": "Type",
|
||||||
|
"typeSheet": "System {type} Sheet",
|
||||||
"unarmed": "Unarmed",
|
"unarmed": "Unarmed",
|
||||||
"unarmedAttack": "Unarmed Attack",
|
"unarmedAttack": "Unarmed Attack",
|
||||||
"unarmored": "Unarmored",
|
"unarmored": "Unarmored",
|
||||||
|
|
@ -2224,6 +2240,7 @@
|
||||||
"tokenRingImg": { "label": "Subject Texture" },
|
"tokenRingImg": { "label": "Subject Texture" },
|
||||||
"tokenSize": {
|
"tokenSize": {
|
||||||
"placeholder": "Using character dimensions",
|
"placeholder": "Using character dimensions",
|
||||||
|
"disabledPlaceholder": "Set by character size",
|
||||||
"height": { "label": "Height" },
|
"height": { "label": "Height" },
|
||||||
"width": { "label": "Width" }
|
"width": { "label": "Width" }
|
||||||
},
|
},
|
||||||
|
|
@ -2249,7 +2266,9 @@
|
||||||
"hybridizeFeatureTitle": "Hybrid Features",
|
"hybridizeFeatureTitle": "Hybrid Features",
|
||||||
"hybridizeDrag": "Drag a form here to hybridize it.",
|
"hybridizeDrag": "Drag a form here to hybridize it.",
|
||||||
"mainTrait": "Main Trait",
|
"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": {
|
"Class": {
|
||||||
"hopeFeatures": "Hope Features",
|
"hopeFeatures": "Hope Features",
|
||||||
|
|
@ -2529,8 +2548,8 @@
|
||||||
"enabled": { "label": "Enabled" },
|
"enabled": { "label": "Enabled" },
|
||||||
"tokens": { "label": "Tokens" }
|
"tokens": { "label": "Tokens" }
|
||||||
},
|
},
|
||||||
"massiveDamage":{
|
"massiveDamage": {
|
||||||
"title":"Massive Damage",
|
"title": "Massive Damage",
|
||||||
"enabled": { "label": "Enabled" }
|
"enabled": { "label": "Enabled" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2804,7 +2823,8 @@
|
||||||
"companionPartnerLevelBlock": "The companion needs an assigned partner to level up.",
|
"companionPartnerLevelBlock": "The companion needs an assigned partner to level up.",
|
||||||
"configureAttribution": "Configure Attribution",
|
"configureAttribution": "Configure Attribution",
|
||||||
"deleteItem": "Delete Item",
|
"deleteItem": "Delete Item",
|
||||||
"immune": "Immune"
|
"immune": "Immune",
|
||||||
|
"tokenSize": "The token size used on the canvas"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -195,9 +195,9 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
if (this.config.roll) {
|
if (this.config.roll) {
|
||||||
this.reactionOverride = !this.reactionOverride;
|
this.reactionOverride = !this.reactionOverride;
|
||||||
this.config.actionType = this.reactionOverride
|
this.config.actionType = this.reactionOverride
|
||||||
? CONFIG.DH.ITEM.actionTypes.reaction.id
|
? 'reaction'
|
||||||
: this.config.actionType === CONFIG.DH.ITEM.actionTypes.reaction.id
|
: this.config.actionType === 'reaction'
|
||||||
? CONFIG.DH.ITEM.actionTypes.action.id
|
? 'action'
|
||||||
: this.config.actionType;
|
: this.config.actionType;
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
}
|
}
|
||||||
|
|
||||||
getRefreshables() {
|
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) {
|
if (x.system.actions) {
|
||||||
const recoverable = x.system.actions.reduce((acc, action) => {
|
const recoverable = x.system.actions.reduce((acc, action) => {
|
||||||
if (refreshIsAllowed([this.shortrest ? 'shortRest' : 'longRest'], action.uses.recovery)) {
|
if (refreshIsAllowed([this.shortrest ? 'shortRest' : 'longRest'], action.uses.recovery)) {
|
||||||
|
|
|
||||||
|
|
@ -1,69 +1,61 @@
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
export default class ItemTransferDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
export default class ItemTransferDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
constructor(item) {
|
constructor(data) {
|
||||||
super({});
|
super({});
|
||||||
|
this.data = data;
|
||||||
this.item = item;
|
|
||||||
this.quantity = item.system.quantity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
return this.item.name;
|
return this.data.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
tag: 'form',
|
tag: 'form',
|
||||||
classes: ['daggerheart', 'dh-style', 'dialog', 'item-transfer'],
|
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' },
|
window: { icon: 'fa-solid fa-hand-holding-hand' },
|
||||||
actions: {
|
actions: {
|
||||||
finish: ItemTransferDialog.#finish
|
finish: ItemTransferDialog.#finish
|
||||||
},
|
}
|
||||||
form: { handler: this.updateData, submitOnChange: true, closeOnSubmit: false }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static PARTS = {
|
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) {
|
async _prepareContext(_options) {
|
||||||
const context = await super._prepareContext(_options);
|
const context = await super._prepareContext(_options);
|
||||||
context.item = this.item;
|
return foundry.utils.mergeObject(context, this.data);
|
||||||
context.quantity = this.quantity;
|
|
||||||
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async updateData(_event, _element, formData) {
|
|
||||||
const { quantity } = foundry.utils.expandObject(formData.object);
|
|
||||||
this.quantity = quantity;
|
|
||||||
this.render();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async #finish() {
|
static async #finish() {
|
||||||
this.close({ submitted: true });
|
this.selected = this.form.elements.quantity.valueAsNumber || null;
|
||||||
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
close(options = {}) {
|
static #determineTransferOptions({ originActor, targetActor, item, currency }) {
|
||||||
if (!options.submitted) this.quantity = null;
|
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 => {
|
return new Promise(resolve => {
|
||||||
const app = new this(item);
|
const data = this.#determineTransferOptions(options);
|
||||||
app.addEventListener('close', () => resolve(app.quantity), { once: true });
|
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 });
|
app.render({ force: true });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -220,8 +220,8 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
!roll.system.isCritical && criticalRoll
|
!roll.system.isCritical && criticalRoll
|
||||||
? (await getCritDamageBonus(damage.formula)) + damage.total
|
? (await getCritDamageBonus(damage.formula)) + damage.total
|
||||||
: damage.total;
|
: damage.total;
|
||||||
|
const updatedDamageParts = damage.parts;
|
||||||
if (systemData.damage[key]) {
|
if (systemData.damage[key]) {
|
||||||
const updatedDamageParts = damage.parts;
|
|
||||||
if (!roll.system.isCritical && criticalRoll) {
|
if (!roll.system.isCritical && criticalRoll) {
|
||||||
for (let part of updatedDamageParts) {
|
for (let part of updatedDamageParts) {
|
||||||
const criticalDamage = await getCritDamageBonus(part.formula);
|
const criticalDamage = await getCritDamageBonus(part.formula);
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
||||||
deleteAdversaryType: this.deleteAdversaryType,
|
deleteAdversaryType: this.deleteAdversaryType,
|
||||||
selectAdversaryType: this.selectAdversaryType,
|
selectAdversaryType: this.selectAdversaryType,
|
||||||
save: this.save,
|
save: this.save,
|
||||||
|
resetTokenSizes: this.resetTokenSizes,
|
||||||
reset: this.reset
|
reset: this.reset
|
||||||
},
|
},
|
||||||
form: { handler: this.updateData, submitOnChange: true }
|
form: { handler: this.updateData, submitOnChange: true }
|
||||||
|
|
@ -424,6 +425,14 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async resetTokenSizes() {
|
||||||
|
await this.settings.updateSource({
|
||||||
|
tokenSizes: this.settings.schema.fields.tokenSizes.initial
|
||||||
|
});
|
||||||
|
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
static async reset() {
|
static async reset() {
|
||||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||||
window: {
|
window: {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,18 @@
|
||||||
export default class DhPrototypeTokenConfig extends foundry.applications.sheets.PrototypeTokenConfig {
|
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 */
|
/** @inheritDoc */
|
||||||
async _prepareResourcesTab() {
|
async _prepareResourcesTab() {
|
||||||
const token = this.token;
|
const token = this.token;
|
||||||
|
|
@ -17,4 +31,11 @@ export default class DhPrototypeTokenConfig extends foundry.applications.sheets.
|
||||||
turnMarkerAnimations: CONFIG.Combat.settings.turnMarkerAnimations
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,18 @@
|
||||||
export default class DhTokenConfig extends foundry.applications.sheets.TokenConfig {
|
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 */
|
/** @inheritDoc */
|
||||||
async _prepareResourcesTab() {
|
async _prepareResourcesTab() {
|
||||||
const token = this.token;
|
const token = this.token;
|
||||||
|
|
@ -17,4 +31,11 @@ export default class DhTokenConfig extends foundry.applications.sheets.TokenConf
|
||||||
turnMarkerAnimations: CONFIG.Combat.settings.turnMarkerAnimations
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -675,16 +675,21 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
roll: {
|
roll: {
|
||||||
trait: button.dataset.attribute
|
trait: button.dataset.attribute
|
||||||
},
|
},
|
||||||
hasRoll: true
|
hasRoll: true,
|
||||||
};
|
|
||||||
const result = await this.document.diceRoll({
|
|
||||||
...config,
|
|
||||||
actionType: 'action',
|
actionType: 'action',
|
||||||
headerTitle: `${game.i18n.localize('DAGGERHEART.GENERAL.dualityRoll')}: ${this.actor.name}`,
|
headerTitle: `${game.i18n.localize('DAGGERHEART.GENERAL.dualityRoll')}: ${this.actor.name}`,
|
||||||
title: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', {
|
title: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', {
|
||||||
ability: abilityLabel
|
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
|
//TODO: redo toggleEquipItem method
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,6 @@ export default function DHApplicationMixin(Base) {
|
||||||
for (const deltaInput of htmlElement.querySelectorAll('input[data-allow-delta]')) {
|
for (const deltaInput of htmlElement.querySelectorAll('input[data-allow-delta]')) {
|
||||||
deltaInput.dataset.numValue = deltaInput.value;
|
deltaInput.dataset.numValue = deltaInput.value;
|
||||||
deltaInput.inputMode = 'numeric';
|
deltaInput.inputMode = 'numeric';
|
||||||
deltaInput.pattern = '^[+=\\-]?\d*';
|
|
||||||
|
|
||||||
const handleUpdate = (delta = 0) => {
|
const handleUpdate = (delta = 0) => {
|
||||||
const min = Number(deltaInput.min) || 0;
|
const min = Number(deltaInput.min) || 0;
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
/* 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) {
|
async _onDropItem(event, item) {
|
||||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||||
const physicalActorTypes = ['character', 'party'];
|
|
||||||
const originActor = item.actor;
|
const originActor = item.actor;
|
||||||
if (
|
if (
|
||||||
item.actor?.uuid === this.document.uuid ||
|
item.actor?.uuid === this.document.uuid ||
|
||||||
!originActor ||
|
!originActor ||
|
||||||
!physicalActorTypes.includes(this.document.type)
|
!['character', 'party'].includes(this.document.type)
|
||||||
) {
|
) {
|
||||||
return super._onDropItem(event, item);
|
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.isInventoryItem) {
|
||||||
if (item.system.metadata.isQuantifiable) {
|
if (item.system.metadata.isQuantifiable) {
|
||||||
const actorItem = originActor.items.get(data.originId);
|
const actorItem = originActor.items.get(data.originId);
|
||||||
const quantityTransfered =
|
const quantityTransfered = await game.system.api.applications.dialogs.ItemTransferDialog.configure({
|
||||||
actorItem.system.quantity === 1
|
item,
|
||||||
? 1
|
targetActor: this.document
|
||||||
: await game.system.api.applications.dialogs.ItemTransferDialog.configure(item);
|
});
|
||||||
|
|
||||||
if (quantityTransfered) {
|
if (quantityTransfered) {
|
||||||
if (quantityTransfered === actorItem.system.quantity) {
|
if (quantityTransfered === actorItem.system.quantity) {
|
||||||
|
|
@ -314,6 +338,16 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
||||||
* @param {DragEvent} event - The drag event
|
* @param {DragEvent} event - The drag event
|
||||||
*/
|
*/
|
||||||
async _onDragStart(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"]');
|
const attackItem = event.currentTarget.closest('.inventory-item[data-type="attack"]');
|
||||||
if (attackItem) {
|
if (attackItem) {
|
||||||
const attackData = {
|
const attackData = {
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ export default class BeastformSheet extends DHBaseItemSheet {
|
||||||
name: context.document.system.advantageOn[key].value
|
name: context.document.system.advantageOn[key].value
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
|
context.dimensionsDisabled = context.document.system.tokenSize.size !== 'custom';
|
||||||
break;
|
break;
|
||||||
case 'effects':
|
case 'effects':
|
||||||
context.effects.actives = context.effects.actives.map(effect => {
|
context.effects.actives = context.effects.actives.map(effect => {
|
||||||
|
|
|
||||||
|
|
@ -31,4 +31,11 @@ export default class FeatureSheet extends DHBaseItemSheet {
|
||||||
labelPrefix: 'DAGGERHEART.GENERAL.Tabs'
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,4 +17,30 @@ export default class DhActorDirectory extends foundry.applications.sidebar.tabs.
|
||||||
: null;
|
: 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 =>
|
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 =>
|
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 =>
|
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 =>
|
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 =>
|
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 =>
|
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 =>
|
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 =>
|
html.querySelectorAll('.group-roll-header-expand-section').forEach(element =>
|
||||||
element.addEventListener('click', this.groupRollExpandSection)
|
element.addEventListener('click', this.groupRollExpandSection)
|
||||||
|
|
|
||||||
|
|
@ -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 = {
|
export const levelChoices = {
|
||||||
attributes: {
|
attributes: {
|
||||||
name: 'attributes',
|
name: 'attributes',
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ export const armorFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'damage',
|
type: 'damage',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.ArmorFeature.burning.actions.burn.name',
|
name: 'DAGGERHEART.CONFIG.ArmorFeature.burning.actions.burn.name',
|
||||||
description: 'DAGGERHEART.CONFIG.ArmorFeature.burning.actions.burn.description',
|
description: 'DAGGERHEART.CONFIG.ArmorFeature.burning.actions.burn.description',
|
||||||
|
|
@ -174,7 +173,6 @@ export const armorFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.actions.hope.name',
|
name: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.actions.hope.name',
|
||||||
description: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.actions.hope.description',
|
description: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.actions.hope.description',
|
||||||
|
|
@ -188,7 +186,6 @@ export const armorFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.actions.impenetrable.name',
|
name: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.actions.impenetrable.name',
|
||||||
description: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.actions.impenetrable.description',
|
description: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.actions.impenetrable.description',
|
||||||
|
|
@ -231,7 +228,6 @@ export const armorFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.ArmorFeature.painful.actions.pain.name',
|
name: 'DAGGERHEART.CONFIG.ArmorFeature.painful.actions.pain.name',
|
||||||
description: 'DAGGERHEART.CONFIG.ArmorFeature.painful.actions.pain.description',
|
description: 'DAGGERHEART.CONFIG.ArmorFeature.painful.actions.pain.description',
|
||||||
|
|
@ -269,7 +265,6 @@ export const armorFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.ArmorFeature.quiet.actions.quiet.name',
|
name: 'DAGGERHEART.CONFIG.ArmorFeature.quiet.actions.quiet.name',
|
||||||
description: 'DAGGERHEART.CONFIG.ArmorFeature.quiet.actions.quiet.description',
|
description: 'DAGGERHEART.CONFIG.ArmorFeature.quiet.actions.quiet.description',
|
||||||
|
|
@ -306,7 +301,6 @@ export const armorFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'attack',
|
type: 'attack',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.ArmorFeature.resilient.actions.resilient.name',
|
name: 'DAGGERHEART.CONFIG.ArmorFeature.resilient.actions.resilient.name',
|
||||||
description: 'DAGGERHEART.CONFIG.ArmorFeature.resilient.actions.resilient.description',
|
description: 'DAGGERHEART.CONFIG.ArmorFeature.resilient.actions.resilient.description',
|
||||||
|
|
@ -353,7 +347,6 @@ export const armorFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.ArmorFeature.shifting.actions.shift.name',
|
name: 'DAGGERHEART.CONFIG.ArmorFeature.shifting.actions.shift.name',
|
||||||
description: 'DAGGERHEART.CONFIG.ArmorFeature.shifting.actions.shift.description',
|
description: 'DAGGERHEART.CONFIG.ArmorFeature.shifting.actions.shift.description',
|
||||||
|
|
@ -373,7 +366,6 @@ export const armorFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'attack',
|
type: 'attack',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.ArmorFeature.timeslowing.actions.slowTime.name',
|
name: 'DAGGERHEART.CONFIG.ArmorFeature.timeslowing.actions.slowTime.name',
|
||||||
description: 'DAGGERHEART.CONFIG.ArmorFeature.timeslowing.actions.slowTime.description',
|
description: 'DAGGERHEART.CONFIG.ArmorFeature.timeslowing.actions.slowTime.description',
|
||||||
|
|
@ -401,7 +393,6 @@ export const armorFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.ArmorFeature.truthseeking.actions.truthseeking.name',
|
name: 'DAGGERHEART.CONFIG.ArmorFeature.truthseeking.actions.truthseeking.name',
|
||||||
description: 'DAGGERHEART.CONFIG.ArmorFeature.truthseeking.actions.truthseeking.description',
|
description: 'DAGGERHEART.CONFIG.ArmorFeature.truthseeking.actions.truthseeking.description',
|
||||||
|
|
@ -537,7 +528,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.actions.bounce.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.actions.bounce.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.actions.bounce.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.actions.bounce.description',
|
||||||
|
|
@ -582,7 +572,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.actions.addDamage.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.actions.addDamage.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.actions.addDamage.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.actions.addDamage.description',
|
||||||
|
|
@ -596,7 +585,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.burning.actions.burn.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.burning.actions.burn.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.burning.actions.burn.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.burning.actions.burn.description',
|
||||||
|
|
@ -610,7 +598,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.charged.actions.markStress.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.charged.actions.markStress.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.charged.actions.markStress.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.charged.actions.markStress.description',
|
||||||
|
|
@ -647,7 +634,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.actions.attack.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.actions.attack.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.actions.attack.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.actions.attack.description',
|
||||||
|
|
@ -688,7 +674,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.actions.extraDamage.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.actions.extraDamage.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.actions.extraDamage.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.actions.extraDamage.description',
|
||||||
|
|
@ -702,7 +687,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.actions.deflect.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.actions.deflect.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.actions.deflect.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.actions.deflect.description',
|
||||||
|
|
@ -739,7 +723,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'damage',
|
type: 'damage',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.actions.attack.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.actions.attack.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.actions.attack.descriptive',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.actions.attack.descriptive',
|
||||||
|
|
@ -784,7 +767,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.actions.devastate.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.actions.devastate.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.actions.devastate.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.actions.devastate.description',
|
||||||
|
|
@ -835,7 +817,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.actions.doubleUp.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.actions.doubleUp.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.actions.doubleUp.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.actions.doubleUp.description',
|
||||||
|
|
@ -849,7 +830,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.actions.duel.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.actions.duel.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.actions.duel.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.actions.duel.description',
|
||||||
|
|
@ -863,7 +843,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect', // Should prompt a dc 14 reaction save on adversaries
|
type: 'effect', // Should prompt a dc 14 reaction save on adversaries
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.actions.erupt.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.actions.erupt.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.actions.erupt.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.actions.erupt.description',
|
||||||
|
|
@ -877,7 +856,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.actions.grapple.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.actions.grapple.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.actions.grapple.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.actions.grapple.description',
|
||||||
|
|
@ -897,7 +875,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.description',
|
||||||
|
|
@ -929,7 +906,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'healing',
|
type: 'healing',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.healing.actions.heal.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.healing.actions.heal.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.healing.actions.heal.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.healing.actions.heal.description',
|
||||||
|
|
@ -977,7 +953,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.actions.hook.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.actions.hook.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.actions.hook.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.actions.hook.description',
|
||||||
|
|
@ -991,7 +966,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.hot.actions.hot.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.hot.actions.hot.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.hot.actions.hot.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.hot.actions.hot.description',
|
||||||
|
|
@ -1005,7 +979,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.actions.invigorate.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.actions.invigorate.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.actions.invigorate.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.actions.invigorate.description',
|
||||||
|
|
@ -1019,7 +992,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.actions.lifesteal.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.actions.lifesteal.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.actions.lifesteal.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.actions.lifesteal.description',
|
||||||
|
|
@ -1033,7 +1005,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.actions.lockOn.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.actions.lockOn.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.actions.lockOn.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.actions.lockOn.description',
|
||||||
|
|
@ -1047,7 +1018,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.long.actions.long.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.long.actions.long.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.long.actions.long.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.long.actions.long.description',
|
||||||
|
|
@ -1061,7 +1031,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.actions.luck.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.actions.luck.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.actions.luck.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.actions.luck.description',
|
||||||
|
|
@ -1099,7 +1068,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.painful.actions.pain.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.painful.actions.pain.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.painful.actions.pain.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.painful.actions.pain.description',
|
||||||
|
|
@ -1145,7 +1113,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.parry.actions.parry.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.parry.actions.parry.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.parry.actions.parry.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.parry.actions.parry.description',
|
||||||
|
|
@ -1159,7 +1126,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.actions.persuade.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.actions.persuade.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.actions.persuade.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.actions.persuade.description',
|
||||||
|
|
@ -1196,7 +1162,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.pompous.actions.pompous.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.pompous.actions.pompous.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.pompous.actions.pompous.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.pompous.actions.pompous.description',
|
||||||
|
|
@ -1240,7 +1205,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.quick.actions.quick.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.quick.actions.quick.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.quick.actions.quick.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.quick.actions.quick.description',
|
||||||
|
|
@ -1278,7 +1242,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.actions.reload.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.actions.reload.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.actions.reload.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.actions.reload.description',
|
||||||
|
|
@ -1292,7 +1255,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.retractable.actions.retract.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.retractable.actions.retract.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.retractable.actions.retract.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.retractable.actions.retract.description',
|
||||||
|
|
@ -1306,7 +1268,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.returning.actions.return.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.returning.actions.return.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.returning.actions.return.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.returning.actions.return.description',
|
||||||
|
|
@ -1320,7 +1281,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.scary.actions.scare.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.scary.actions.scare.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.scary.actions.scare.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.scary.actions.scare.description',
|
||||||
|
|
@ -1376,7 +1336,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.actions.shelter.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.actions.shelter.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.actions.shelter.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.actions.shelter.description',
|
||||||
|
|
@ -1390,7 +1349,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.startling.actions.startle.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.startling.actions.startle.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.startling.actions.startle.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.startling.actions.startle.description',
|
||||||
|
|
@ -1410,7 +1368,6 @@ export const weaponFeatures = {
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'effect',
|
type: 'effect',
|
||||||
actionType: 'action',
|
|
||||||
chatDisplay: true,
|
chatDisplay: true,
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.timebending.actions.bendTime.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.timebending.actions.bendTime.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.timebending.actions.bendTime.description',
|
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)));
|
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 = {
|
export const featureTypes = {
|
||||||
ancestry: {
|
ancestry: {
|
||||||
id: 'ancestry',
|
id: 'ancestry',
|
||||||
|
|
@ -1515,21 +1478,6 @@ export const featureSubTypes = {
|
||||||
mastery: 'mastery'
|
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 = {
|
export const itemResourceTypes = {
|
||||||
simple: {
|
simple: {
|
||||||
id: 'simple',
|
id: 'simple',
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
||||||
|
|
||||||
// Execute the Action Worflow in order based of schema fields
|
// Execute the Action Worflow in order based of schema fields
|
||||||
await this.executeWorkflow(config);
|
await this.executeWorkflow(config);
|
||||||
|
await config.resourceUpdates.updateResources();
|
||||||
|
|
||||||
if (Hooks.call(`${CONFIG.DH.id}.postUseAction`, this, config) === false) return;
|
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,
|
isDirect: !!this.damage?.direct,
|
||||||
selectedRollMode: game.settings.get('core', 'rollMode'),
|
selectedRollMode: game.settings.get('core', 'rollMode'),
|
||||||
data: this.getRollData(),
|
data: this.getRollData(),
|
||||||
evaluate: this.hasRoll
|
evaluate: this.hasRoll,
|
||||||
|
resourceUpdates: new ResourceUpdateMap(this.actor)
|
||||||
};
|
};
|
||||||
|
|
||||||
DHBaseAction.applyKeybindings(config);
|
DHBaseAction.applyKeybindings(config);
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
@ -322,11 +325,46 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
||||||
* @returns {string[]} An array of localized tag strings.
|
* @returns {string[]} An array of localized tag strings.
|
||||||
*/
|
*/
|
||||||
_getTags() {
|
_getTags() {
|
||||||
const tags = [
|
const tags = [game.i18n.localize(`DAGGERHEART.ACTIONS.TYPES.${this.type}.name`)];
|
||||||
game.i18n.localize(`DAGGERHEART.ACTIONS.TYPES.${this.type}.name`),
|
|
||||||
game.i18n.localize(`DAGGERHEART.CONFIG.ActionType.${this.actionType}`)
|
|
||||||
];
|
|
||||||
|
|
||||||
return tags;
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -65,20 +65,30 @@ export default class BeastformEffect extends BaseEffect {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateToken = token => ({
|
const updateToken = token => {
|
||||||
...baseUpdate,
|
const { x, y } = game.system.api.documents.DhToken.getSnappedPositionInSquareGrid(
|
||||||
'texture': {
|
token.object.scene.grid,
|
||||||
enabled: this.characterTokenData.usesDynamicToken,
|
{ x: token.x, y: token.y, elevation: token.elevation },
|
||||||
src: token.flags.daggerheart?.beastformTokenImg ?? this.characterTokenData.tokenImg
|
baseUpdate.width,
|
||||||
},
|
baseUpdate.height
|
||||||
'ring': {
|
);
|
||||||
subject: {
|
return {
|
||||||
texture:
|
...baseUpdate,
|
||||||
token.flags.daggerheart?.beastformSubjectTexture ?? this.characterTokenData.tokenRingImg
|
x,
|
||||||
}
|
y,
|
||||||
},
|
'texture': {
|
||||||
'flags.daggerheart': { '-=beastformTokenImg': null, '-=beastformSubjectTexture': null }
|
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);
|
await updateActorTokens(this.parent.parent, update, updateToken);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ export default class DhpAdversary extends BaseDataActor {
|
||||||
label: 'TYPES.Actor.adversary',
|
label: 'TYPES.Actor.adversary',
|
||||||
type: 'adversary',
|
type: 'adversary',
|
||||||
settingSheet: DHAdversarySettings,
|
settingSheet: DHAdversarySettings,
|
||||||
hasAttribution: true
|
hasAttribution: true,
|
||||||
|
usesSize: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -142,7 +143,7 @@ export default class DhpAdversary extends BaseDataActor {
|
||||||
}
|
}
|
||||||
|
|
||||||
isItemValid(source) {
|
isItemValid(source) {
|
||||||
return source.type === "feature";
|
return source.type === 'feature';
|
||||||
}
|
}
|
||||||
|
|
||||||
async _preUpdate(changes, options, user) {
|
async _preUpdate(changes, options, user) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import DHBaseActorSettings from '../../applications/sheets/api/actor-setting.mjs';
|
import DHBaseActorSettings from '../../applications/sheets/api/actor-setting.mjs';
|
||||||
|
import DHItem from '../../documents/item.mjs';
|
||||||
import { getScrollTextData } from '../../helpers/utils.mjs';
|
import { getScrollTextData } from '../../helpers/utils.mjs';
|
||||||
|
|
||||||
const resistanceField = (resistanceLabel, immunityLabel, reductionLabel) =>
|
const resistanceField = (resistanceLabel, immunityLabel, reductionLabel) =>
|
||||||
|
|
@ -41,7 +42,8 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
|
||||||
settingSheet: null,
|
settingSheet: null,
|
||||||
hasResistances: true,
|
hasResistances: true,
|
||||||
hasAttribution: false,
|
hasAttribution: false,
|
||||||
hasLimitedView: true
|
hasLimitedView: true,
|
||||||
|
usesSize: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,6 +78,13 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
|
||||||
'DAGGERHEART.GENERAL.DamageResistance.magicalReduction'
|
'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;
|
return schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,6 +115,17 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
|
||||||
return data;
|
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() {
|
async _preDelete() {
|
||||||
/* Clear all partyMembers from tagTeam setting.*/
|
/* Clear all partyMembers from tagTeam setting.*/
|
||||||
/* Revisit this when tagTeam is improved for many parties */
|
/* Revisit this when tagTeam is improved for many parties */
|
||||||
|
|
|
||||||
|
|
@ -435,6 +435,34 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
return attack;
|
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() {
|
get sheetLists() {
|
||||||
const ancestryFeatures = [],
|
const ancestryFeatures = [],
|
||||||
communityFeatures = [],
|
communityFeatures = [],
|
||||||
|
|
@ -443,7 +471,7 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
companionFeatures = [],
|
companionFeatures = [],
|
||||||
features = [];
|
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) {
|
if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.ancestry.id) {
|
||||||
ancestryFeatures.push(item);
|
ancestryFeatures.push(item);
|
||||||
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.community.id) {
|
} 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) {
|
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.class.id) {
|
||||||
classFeatures.push(item);
|
classFeatures.push(item);
|
||||||
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.subclass.id) {
|
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.subclass.id) {
|
||||||
if (this.class.subclass) {
|
subclassFeatures.push(item);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.companion.id) {
|
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.companion.id) {
|
||||||
companionFeatures.push(item);
|
companionFeatures.push(item);
|
||||||
} else if (item.type === 'feature' && !item.system.type) {
|
} else if (item.type === 'feature' && !item.system.type) {
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export default class DhParty extends BaseDataActor {
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
isItemValid(source) {
|
isItemValid(source) {
|
||||||
return ["weapon", "armor", "consumable", "loot"].includes(source.type);
|
return ['weapon', 'armor', 'consumable', 'loot'].includes(source.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareBaseData() {
|
prepareBaseData() {
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,18 @@ export default class BeastformField extends fields.SchemaField {
|
||||||
|
|
||||||
beastformEffect.changes = [...beastformEffect.changes, ...evolvedForm.changes];
|
beastformEffect.changes = [...beastformEffect.changes, ...evolvedForm.changes];
|
||||||
formData.system.features = [...formData.system.features, ...selectedForm.system.features.map(x => x.uuid)];
|
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) {
|
if (selectedForm.system.beastformType === CONFIG.DH.ITEM.beastformTypes.hybrid.id) {
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ export default class CostField extends fields.ArrayField {
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
await actor.modifyResource(resources);
|
config.resourceUpdates.addResources(resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ export default class TargetField extends fields.SchemaField {
|
||||||
return {
|
return {
|
||||||
id: token.id,
|
id: token.id,
|
||||||
actorId: token.actor.uuid,
|
actorId: token.actor.uuid,
|
||||||
name: token.actor.name,
|
name: token.name,
|
||||||
img: token.actor.img,
|
img: token.actor.img,
|
||||||
difficulty: token.actor.system.difficulty,
|
difficulty: token.actor.system.difficulty,
|
||||||
evasion: token.actor.system.evasion,
|
evasion: token.actor.system.evasion,
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,12 @@ export function ActionMixin(Base) {
|
||||||
return this.documentName;
|
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() {
|
get relativeUUID() {
|
||||||
return `.Item.${this.item.id}.Action.${this.id}`;
|
return `.Item.${this.item.id}.Action.${this.id}`;
|
||||||
}
|
}
|
||||||
|
|
@ -256,7 +262,7 @@ export function ActionMixin(Base) {
|
||||||
async toChat(origin) {
|
async toChat(origin) {
|
||||||
const cls = getDocumentClass('ChatMessage');
|
const cls = getDocumentClass('ChatMessage');
|
||||||
const systemData = {
|
const systemData = {
|
||||||
title: game.i18n.localize('DAGGERHEART.CONFIG.ActionType.action'),
|
title: game.i18n.localize('DAGGERHEART.CONFIG.FeatureForm.action'),
|
||||||
origin: origin,
|
origin: origin,
|
||||||
action: {
|
action: {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,12 @@ export default class DHBeastform extends BaseDataItem {
|
||||||
base64: false
|
base64: false
|
||||||
}),
|
}),
|
||||||
tokenSize: new fields.SchemaField({
|
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 }),
|
height: new fields.NumberField({ integer: true, min: 1, initial: null, nullable: true }),
|
||||||
width: 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()]);
|
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 = {
|
const prototypeTokenUpdate = {
|
||||||
height: this.tokenSize.height,
|
height,
|
||||||
width: this.tokenSize.width,
|
width,
|
||||||
texture: {
|
texture: {
|
||||||
src: this.tokenImg
|
src: this.tokenImg
|
||||||
},
|
},
|
||||||
|
|
@ -202,16 +217,25 @@ export default class DHBeastform extends BaseDataItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const tokenUpdate = token => {
|
||||||
const tokenUpdate = token => ({
|
const { x, y } = game.system.api.documents.DhToken.getSnappedPositionInSquareGrid(
|
||||||
...prototypeTokenUpdate,
|
token.object.scene.grid,
|
||||||
flags: {
|
{ x: token.x, y: token.y, elevation: token.elevation },
|
||||||
daggerheart: {
|
width ?? token.width,
|
||||||
beastformTokenImg: token.texture.src,
|
height ?? token.height
|
||||||
beastformSubjectTexture: token.ring.subject.texture
|
);
|
||||||
|
return {
|
||||||
|
...prototypeTokenUpdate,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
flags: {
|
||||||
|
daggerheart: {
|
||||||
|
beastformTokenImg: token.texture.src,
|
||||||
|
beastformSubjectTexture: token.ring.subject.texture
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
});
|
};
|
||||||
|
|
||||||
await updateActorTokens(this.parent.parent, prototypeTokenUpdate, tokenUpdate);
|
await updateActorTokens(this.parent.parent, prototypeTokenUpdate, tokenUpdate);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,13 @@ export default class DHFeature extends BaseDataItem {
|
||||||
initial: null
|
initial: null
|
||||||
}),
|
}),
|
||||||
multiclassOrigin: new fields.BooleanField({ initial: false }),
|
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'
|
||||||
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,38 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
|
||||||
traitArray: new fields.ArrayField(new fields.NumberField({ required: true, integer: true }), {
|
traitArray: new fields.ArrayField(new fields.NumberField({ required: true, integer: true }), {
|
||||||
initial: () => [2, 1, 1, 0, 0, -1]
|
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({
|
currency: new fields.SchemaField({
|
||||||
title: new fields.StringField({
|
title: new fields.StringField({
|
||||||
required: true,
|
required: true,
|
||||||
|
|
|
||||||
|
|
@ -236,81 +236,3 @@ export default class DHRoll extends Roll {
|
||||||
return {};
|
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 !== CONFIG.DH.ITEM.actionTypes.reaction.id &&
|
|
||||||
!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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs';
|
||||||
import D20Roll from './d20Roll.mjs';
|
import D20Roll from './d20Roll.mjs';
|
||||||
import { setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs';
|
import { setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs';
|
||||||
import { getDiceSoNicePresets } from '../config/generalConfig.mjs';
|
import { getDiceSoNicePresets } from '../config/generalConfig.mjs';
|
||||||
|
import { ResourceUpdateMap } from '../data/action/baseAction.mjs';
|
||||||
|
|
||||||
export default class DualityRoll extends D20Roll {
|
export default class DualityRoll extends D20Roll {
|
||||||
_advantageFaces = 6;
|
_advantageFaces = 6;
|
||||||
|
|
@ -19,7 +20,7 @@ export default class DualityRoll extends D20Roll {
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
return game.i18n.localize(
|
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'}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -219,6 +220,88 @@ export default class DualityRoll extends D20Roll {
|
||||||
return data;
|
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) {
|
static async reroll(rollString, target, message) {
|
||||||
let parsedRoll = game.system.api.dice.DualityRoll.fromData({ ...rollString, evaluated: false });
|
let parsedRoll = game.system.api.dice.DualityRoll.fromData({ ...rollString, evaluated: false });
|
||||||
const term = parsedRoll.terms[target.dataset.dieIndex];
|
const term = parsedRoll.terms[target.dataset.dieIndex];
|
||||||
|
|
@ -257,13 +340,20 @@ export default class DualityRoll extends D20Roll {
|
||||||
newRoll.extra = newRoll.extra.slice(2);
|
newRoll.extra = newRoll.extra.slice(2);
|
||||||
|
|
||||||
const tagTeamSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll);
|
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 ?? '' },
|
source: { actor: message.system.source.actor ?? '' },
|
||||||
targets: message.system.targets,
|
targets: message.system.targets,
|
||||||
tagTeamSelected: Object.values(tagTeamSettings.members).some(x => x.messageId === message._id),
|
tagTeamSelected: Object.values(tagTeamSettings.members).some(x => x.messageId === message._id),
|
||||||
roll: newRoll,
|
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 };
|
return { newRoll, parsedRoll };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ export { default as DhpCombat } from './combat.mjs';
|
||||||
export { default as DHCombatant } from './combatant.mjs';
|
export { default as DHCombatant } from './combatant.mjs';
|
||||||
export { default as DhActiveEffect } from './activeEffect.mjs';
|
export { default as DhActiveEffect } from './activeEffect.mjs';
|
||||||
export { default as DhChatMessage } from './chatMessage.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 DhToken } from './token.mjs';
|
||||||
export { default as DhTooltipManager } from './tooltipManager.mjs';
|
export { default as DhTooltipManager } from './tooltipManager.mjs';
|
||||||
export { default as DhTemplateManager } from './templateManager.mjs';
|
export { default as DhTemplateManager } from './templateManager.mjs';
|
||||||
|
|
|
||||||
|
|
@ -194,27 +194,10 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareDerivedData() {
|
prepareDerivedData() {
|
||||||
/* Preventing subclass features from transferring to actor if they do not have the right subclass advancement */
|
/* Check for item availability such as in the case of subclass advancement. */
|
||||||
if (this.parent?.type === 'feature') {
|
if (this.parent?.parent?.system?.isItemAvailable) {
|
||||||
const origSubclassParent = this.parent.system.originItemType === 'subclass';
|
if (!this.parent.parent.system.isItemAvailable(this.parent)) {
|
||||||
if (origSubclassParent) {
|
this.transfer = false;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { LevelOptionType } from '../data/levelTier.mjs';
|
||||||
import DHFeature from '../data/item/feature.mjs';
|
import DHFeature from '../data/item/feature.mjs';
|
||||||
import { createScrollText, damageKeyToNumber } from '../helpers/utils.mjs';
|
import { createScrollText, damageKeyToNumber } from '../helpers/utils.mjs';
|
||||||
import DhCompanionLevelUp from '../applications/levelup/companionLevelup.mjs';
|
import DhCompanionLevelUp from '../applications/levelup/companionLevelup.mjs';
|
||||||
|
import { ResourceUpdateMap } from '../data/action/baseAction.mjs';
|
||||||
|
|
||||||
export default class DhpActor extends Actor {
|
export default class DhpActor extends Actor {
|
||||||
parties = new Set();
|
parties = new Set();
|
||||||
|
|
@ -73,16 +74,27 @@ export default class DhpActor extends Actor {
|
||||||
/**@inheritdoc */
|
/**@inheritdoc */
|
||||||
async _preCreate(data, options, user) {
|
async _preCreate(data, options, user) {
|
||||||
if ((await super._preCreate(data, options, user)) === false) return false;
|
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
|
// Configure prototype token settings
|
||||||
const prototypeToken = {};
|
|
||||||
if (['character', 'companion', 'party'].includes(this.type))
|
if (['character', 'companion', 'party'].includes(this.type))
|
||||||
Object.assign(prototypeToken, {
|
Object.assign(update, {
|
||||||
sight: { enabled: true },
|
prototypeToken: {
|
||||||
actorLink: true,
|
sight: { enabled: true },
|
||||||
disposition: CONST.TOKEN_DISPOSITIONS.FRIENDLY
|
actorLink: true,
|
||||||
|
disposition: CONST.TOKEN_DISPOSITIONS.FRIENDLY
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.updateSource({ prototypeToken });
|
this.updateSource(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onUpdate(changes, options, userId) {
|
_onUpdate(changes, options, userId) {
|
||||||
|
|
@ -477,6 +489,7 @@ export default class DhpActor extends Actor {
|
||||||
async diceRoll(config) {
|
async diceRoll(config) {
|
||||||
config.source = { ...(config.source ?? {}), actor: this.uuid };
|
config.source = { ...(config.source ?? {}), actor: this.uuid };
|
||||||
config.data = this.getRollData();
|
config.data = this.getRollData();
|
||||||
|
config.resourceUpdates = new ResourceUpdateMap(this);
|
||||||
const rollClass = config.roll.lite ? CONFIG.Dice.daggerheart['DHRoll'] : this.rollClass;
|
const rollClass = config.roll.lite ? CONFIG.Dice.daggerheart['DHRoll'] : this.rollClass;
|
||||||
return await rollClass.build(config);
|
return await rollClass.build(config);
|
||||||
}
|
}
|
||||||
|
|
@ -765,8 +778,9 @@ export default class DhpActor extends Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
convertDamageToThreshold(damage) {
|
convertDamageToThreshold(damage) {
|
||||||
const massiveDamageEnabled=game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).massiveDamage.enabled;
|
const massiveDamageEnabled = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules)
|
||||||
if (massiveDamageEnabled && damage >= (this.system.damageThresholds.severe * 2)) {
|
.massiveDamage.enabled;
|
||||||
|
if (massiveDamageEnabled && damage >= this.system.damageThresholds.severe * 2) {
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
return damage >= this.system.damageThresholds.severe ? 3 : damage >= this.system.damageThresholds.major ? 2 : 1;
|
return damage >= this.system.damageThresholds.severe ? 3 : damage >= this.system.damageThresholds.major ? 2 : 1;
|
||||||
|
|
|
||||||
40
module/documents/scene.mjs
Normal file
40
module/documents/scene.mjs
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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.
|
* 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
|
* @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 ?? {});
|
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<string, DeepReadonly<TokenHexagonalShapeData>>}
|
||||||
|
*/
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ export const registerDHSettings = () => {
|
||||||
scope: 'world',
|
scope: 'world',
|
||||||
config: true,
|
config: true,
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
onChange: () => ui.combat.render(),
|
onChange: () => ui.combat.render()
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const registerMenuSettings = () => {
|
const registerMenuSettings = () => {
|
||||||
|
|
@ -46,6 +46,9 @@ const registerMenuSettings = () => {
|
||||||
if (value.maxFear) {
|
if (value.maxFear) {
|
||||||
if (ui.resources) ui.resources.render({ force: true });
|
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
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,10 +73,13 @@ export const registerSocketHooks = () => {
|
||||||
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.Countdown });
|
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.Countdown });
|
||||||
break;
|
break;
|
||||||
case GMUpdateEvent.UpdateSaveMessage:
|
case GMUpdateEvent.UpdateSaveMessage:
|
||||||
const action = await fromUuid(data.update.action),
|
const message = game.messages.get(data.update.message);
|
||||||
message = game.messages.get(data.update.message);
|
if (!message) return;
|
||||||
if (!action || !message) return;
|
game.system.api.fields.ActionFields.SaveField.updateSaveMessage(
|
||||||
action.updateSaveMessage(data.update.result, message, data.update.token);
|
data.update.result,
|
||||||
|
message,
|
||||||
|
data.update.token
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,8 @@
|
||||||
"experiences": {
|
"experiences": {
|
||||||
"pe7OIoJsqlpMXEvs": {
|
"pe7OIoJsqlpMXEvs": {
|
||||||
"name": "Tremor Sense",
|
"name": "Tremor Sense",
|
||||||
"value": 2
|
"value": 2,
|
||||||
|
"description": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bonuses": {
|
"bonuses": {
|
||||||
|
|
@ -148,7 +149,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 75,
|
"page": 75,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "large"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"ownership": {
|
"ownership": {
|
||||||
|
|
@ -381,7 +383,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
|
|
@ -546,7 +549,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
@ -681,7 +685,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 91,
|
"page": 91,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "gargantuan"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "G7jiltRjgvVhZewm",
|
"_id": "G7jiltRjgvVhZewm",
|
||||||
|
|
@ -263,7 +264,7 @@
|
||||||
"img": "icons/magic/unholy/silhouette-evil-horned-giant.webp",
|
"img": "icons/magic/unholy/silhouette-evil-horned-giant.webp",
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
"sort": 0,
|
"sort": 100000,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
"MQSznptE5yLT7kj8": 3
|
"MQSznptE5yLT7kj8": 3
|
||||||
|
|
@ -360,7 +361,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
"sort": 0,
|
"sort": 200000,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
"MQSznptE5yLT7kj8": 3
|
"MQSznptE5yLT7kj8": 3
|
||||||
|
|
@ -461,13 +462,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "BuL6ndgaiJtjaM2T",
|
"_id": "BuL6ndgaiJtjaM2T",
|
||||||
"img": "icons/skills/melee/strike-slashes-orange.webp",
|
"img": "icons/skills/melee/strike-slashes-orange.webp",
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
"sort": 0,
|
"sort": 300000,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
"MQSznptE5yLT7kj8": 3
|
"MQSznptE5yLT7kj8": 3
|
||||||
|
|
@ -540,13 +542,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "bOTsfXr9yNIGkIzK",
|
"_id": "bOTsfXr9yNIGkIzK",
|
||||||
"img": "icons/magic/light/explosion-glow-spiral-yellow.webp",
|
"img": "icons/magic/light/explosion-glow-spiral-yellow.webp",
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
"sort": 0,
|
"sort": 400000,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
"MQSznptE5yLT7kj8": 3
|
"MQSznptE5yLT7kj8": 3
|
||||||
|
|
@ -701,13 +704,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "49cIxZRFiAM6jDva",
|
"_id": "49cIxZRFiAM6jDva",
|
||||||
"img": "icons/magic/air/fog-gas-smoke-purple.webp",
|
"img": "icons/magic/air/fog-gas-smoke-purple.webp",
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
"sort": 0,
|
"sort": 500000,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
"MQSznptE5yLT7kj8": 3
|
"MQSznptE5yLT7kj8": 3
|
||||||
|
|
@ -756,13 +760,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "KLdLRKoJHBJlHwYe",
|
"_id": "KLdLRKoJHBJlHwYe",
|
||||||
"img": "icons/skills/movement/arrow-upward-yellow.webp",
|
"img": "icons/skills/movement/arrow-upward-yellow.webp",
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
"sort": 0,
|
"sort": 600000,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
"MQSznptE5yLT7kj8": 3
|
"MQSznptE5yLT7kj8": 3
|
||||||
|
|
@ -787,7 +792,7 @@
|
||||||
"img": "icons/skills/movement/feet-winged-boots-blue.webp",
|
"img": "icons/skills/movement/feet-winged-boots-blue.webp",
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
"sort": 0,
|
"sort": 700000,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
"fBcTgyTzoARBvohY": 3
|
"fBcTgyTzoARBvohY": 3
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 84,
|
"page": 84,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "vNIbYQ4YSzNf0WPE",
|
"_id": "vNIbYQ4YSzNf0WPE",
|
||||||
|
|
@ -223,7 +224,8 @@
|
||||||
"resource": null,
|
"resource": null,
|
||||||
"actions": {},
|
"actions": {},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "passive"
|
||||||
},
|
},
|
||||||
"_id": "2yREz60uPY80tAa4",
|
"_id": "2yREz60uPY80tAa4",
|
||||||
"img": "icons/magic/symbols/runes-carved-stone-yellow.webp",
|
"img": "icons/magic/symbols/runes-carved-stone-yellow.webp",
|
||||||
|
|
@ -278,7 +280,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "4wT7CmM1DJEPcraF",
|
"_id": "4wT7CmM1DJEPcraF",
|
||||||
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 97,
|
"page": 97,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "WPEOIGfclNJxWb87",
|
"_id": "WPEOIGfclNJxWb87",
|
||||||
|
|
@ -289,7 +290,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "jNmMyq5QI2HNgffy",
|
"_id": "jNmMyq5QI2HNgffy",
|
||||||
"img": "icons/magic/death/skull-weapon-staff-glow-pink.webp",
|
"img": "icons/magic/death/skull-weapon-staff-glow-pink.webp",
|
||||||
|
|
@ -467,7 +469,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "4EECsXzHFG0RoIg0",
|
"_id": "4EECsXzHFG0RoIg0",
|
||||||
"img": "icons/magic/unholy/projectile-missile-green.webp",
|
"img": "icons/magic/unholy/projectile-missile-green.webp",
|
||||||
|
|
@ -561,7 +564,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "XxXOrFovbCz9zFxR",
|
"_id": "XxXOrFovbCz9zFxR",
|
||||||
"img": "icons/magic/death/undead-zombie-grave-green.webp",
|
"img": "icons/magic/death/undead-zombie-grave-green.webp",
|
||||||
|
|
@ -640,7 +644,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "k4MSykLRoW3qp7Lk",
|
"_id": "k4MSykLRoW3qp7Lk",
|
||||||
"img": "icons/magic/death/skull-horned-worn-fire-blue.webp",
|
"img": "icons/magic/death/skull-horned-worn-fire-blue.webp",
|
||||||
|
|
@ -756,7 +761,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "FKcuCo0v2U7fVkqq",
|
"_id": "FKcuCo0v2U7fVkqq",
|
||||||
"img": "icons/magic/unholy/hand-claw-fire-green.webp",
|
"img": "icons/magic/unholy/hand-claw-fire-green.webp",
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,8 @@
|
||||||
"experiences": {
|
"experiences": {
|
||||||
"Gtr9I2G39GcXT2Si": {
|
"Gtr9I2G39GcXT2Si": {
|
||||||
"name": "Local Knowledge",
|
"name": "Local Knowledge",
|
||||||
"value": 3
|
"value": 3,
|
||||||
|
"description": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bonuses": {
|
"bonuses": {
|
||||||
|
|
@ -116,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 77,
|
"page": 77,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "JRhrrEg5UroURiAD",
|
"_id": "JRhrrEg5UroURiAD",
|
||||||
|
|
@ -311,7 +313,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 84,
|
"page": 84,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "0ts6CGd93lLqGZI5",
|
"_id": "0ts6CGd93lLqGZI5",
|
||||||
|
|
@ -328,7 +329,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "Wuf5y9tJ88BwzLv2",
|
"_id": "Wuf5y9tJ88BwzLv2",
|
||||||
"img": "icons/skills/ranged/arrows-flying-triple-brown.webp",
|
"img": "icons/skills/ranged/arrows-flying-triple-brown.webp",
|
||||||
|
|
@ -425,7 +427,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "ayGHTtyjSuIR4BrV",
|
"_id": "ayGHTtyjSuIR4BrV",
|
||||||
"img": "icons/skills/ranged/arrows-flying-salvo-blue.webp",
|
"img": "icons/skills/ranged/arrows-flying-salvo-blue.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 84,
|
"page": 84,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "h5RuhzGL17dW5FBT",
|
"_id": "h5RuhzGL17dW5FBT",
|
||||||
|
|
@ -419,7 +420,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "lAmiK8wVxjyHwKlp",
|
"_id": "lAmiK8wVxjyHwKlp",
|
||||||
"img": "icons/magic/air/fog-gas-smoke-green.webp",
|
"img": "icons/magic/air/fog-gas-smoke-green.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 85,
|
"page": 85,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "large"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "dgH3fW9FTYLaIDvS",
|
"_id": "dgH3fW9FTYLaIDvS",
|
||||||
|
|
@ -342,7 +343,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "ZqfLMjVkbUwDw4p6",
|
"_id": "ZqfLMjVkbUwDw4p6",
|
||||||
"img": "icons/commodities/tech/transmission.webp",
|
"img": "icons/commodities/tech/transmission.webp",
|
||||||
|
|
@ -441,7 +443,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "lqyN4CQop53BzarW",
|
"_id": "lqyN4CQop53BzarW",
|
||||||
"img": "icons/magic/light/beam-rays-blue.webp",
|
"img": "icons/magic/light/beam-rays-blue.webp",
|
||||||
|
|
@ -540,7 +543,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "IHQoqt39T772FVMs",
|
"_id": "IHQoqt39T772FVMs",
|
||||||
"img": "icons/magic/fire/explosion-embers-orange.webp",
|
"img": "icons/magic/fire/explosion-embers-orange.webp",
|
||||||
|
|
@ -644,7 +648,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "XtnByqUr9AuYU9Ip",
|
"_id": "XtnByqUr9AuYU9Ip",
|
||||||
"img": "icons/skills/movement/arrow-upward-yellow.webp",
|
"img": "icons/skills/movement/arrow-upward-yellow.webp",
|
||||||
|
|
@ -781,7 +786,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "3bPURmuwQs06fThQ",
|
"_id": "3bPURmuwQs06fThQ",
|
||||||
"img": "icons/magic/lightning/bolt-strike-embers-teal.webp",
|
"img": "icons/magic/lightning/bolt-strike-embers-teal.webp",
|
||||||
|
|
@ -858,7 +864,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "ijIaKjroxq3xZd9Z",
|
"_id": "ijIaKjroxq3xZd9Z",
|
||||||
"img": "icons/magic/sonic/explosion-impact-shock-wave.webp",
|
"img": "icons/magic/sonic/explosion-impact-shock-wave.webp",
|
||||||
|
|
@ -996,7 +1003,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "JCue4ko61bjhedXv",
|
"_id": "JCue4ko61bjhedXv",
|
||||||
"img": "icons/creatures/invertebrates/wasp-swarm-tan.webp",
|
"img": "icons/creatures/invertebrates/wasp-swarm-tan.webp",
|
||||||
|
|
@ -1096,7 +1104,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "ITzpRJr2jWK0Ksmp",
|
"_id": "ITzpRJr2jWK0Ksmp",
|
||||||
"img": "icons/creatures/magical/construct-golem-stone-blue.webp",
|
"img": "icons/creatures/magical/construct-golem-stone-blue.webp",
|
||||||
|
|
@ -1195,7 +1204,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "YvfzPyJbbv2ia6Yp",
|
"_id": "YvfzPyJbbv2ia6Yp",
|
||||||
"img": "icons/magic/sonic/explosion-shock-wave-teal.webp",
|
"img": "icons/magic/sonic/explosion-shock-wave-teal.webp",
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 75,
|
"page": 75,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "large"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "71qKDLKO3CsrNkdy",
|
"_id": "71qKDLKO3CsrNkdy",
|
||||||
|
|
@ -350,7 +351,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
|
|
@ -485,7 +487,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 77,
|
"page": 77,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "B4LZcGuBAHzyVdzy",
|
"_id": "B4LZcGuBAHzyVdzy",
|
||||||
|
|
@ -358,7 +359,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 83,
|
"page": 83,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "2UeZ0tEe7AzgSJNd",
|
"_id": "2UeZ0tEe7AzgSJNd",
|
||||||
|
|
@ -342,7 +343,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
@ -433,7 +435,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 75,
|
"page": 75,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "large"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "8Zkqk1jU09nKL2fy",
|
"_id": "8Zkqk1jU09nKL2fy",
|
||||||
|
|
@ -467,7 +468,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
@ -548,7 +550,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 85,
|
"page": 85,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "tiny"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "jDmHqGvzg5wjgmxE",
|
"_id": "jDmHqGvzg5wjgmxE",
|
||||||
|
|
@ -443,7 +444,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "Zn25zBr96y1hrmnr",
|
"_id": "Zn25zBr96y1hrmnr",
|
||||||
"img": "icons/magic/lightning/bolt-strike-purple.webp",
|
"img": "icons/magic/lightning/bolt-strike-purple.webp",
|
||||||
|
|
@ -540,7 +542,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "urXRi4bdBfvl8U6K",
|
"_id": "urXRi4bdBfvl8U6K",
|
||||||
"img": "icons/magic/control/sihouette-hold-beam-green.webp",
|
"img": "icons/magic/control/sihouette-hold-beam-green.webp",
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 85,
|
"page": 85,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "99TqczuQipBmaB8i",
|
"_id": "99TqczuQipBmaB8i",
|
||||||
|
|
@ -272,7 +273,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "MWfKUGzT1YBmLvpn",
|
"_id": "MWfKUGzT1YBmLvpn",
|
||||||
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 75,
|
"page": 75,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "uOP5oT9QzXPlnf3p",
|
"_id": "uOP5oT9QzXPlnf3p",
|
||||||
|
|
@ -393,7 +394,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
@ -449,7 +451,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
|
|
@ -593,7 +596,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 85,
|
"page": 85,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "ZxWaWPdzFIUPNC62",
|
"_id": "ZxWaWPdzFIUPNC62",
|
||||||
|
|
@ -300,7 +301,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "rSMUPC5GhR982ifg",
|
"_id": "rSMUPC5GhR982ifg",
|
||||||
"img": "icons/magic/perception/eye-slit-orange.webp",
|
"img": "icons/magic/perception/eye-slit-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 76,
|
"page": 76,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "CBBuEXAlLKFMJdjg",
|
"_id": "CBBuEXAlLKFMJdjg",
|
||||||
|
|
@ -318,7 +319,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
|
|
@ -413,7 +415,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 85,
|
"page": 85,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "0NxCSugvKQ4W8OYZ",
|
"_id": "0NxCSugvKQ4W8OYZ",
|
||||||
|
|
@ -341,7 +342,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "kCffzM8rX8NEr9d2",
|
"_id": "kCffzM8rX8NEr9d2",
|
||||||
"img": "icons/magic/unholy/beam-ringed-impact-purple.webp",
|
"img": "icons/magic/unholy/beam-ringed-impact-purple.webp",
|
||||||
|
|
@ -401,7 +403,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "IHWDn097sRgjlZXO",
|
"_id": "IHWDn097sRgjlZXO",
|
||||||
"img": "icons/magic/unholy/orb-contained-pink.webp",
|
"img": "icons/magic/unholy/orb-contained-pink.webp",
|
||||||
|
|
@ -511,7 +514,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "JpSrduK3vjd9h098",
|
"_id": "JpSrduK3vjd9h098",
|
||||||
"img": "icons/magic/air/fog-gas-smoke-dense-pink.webp",
|
"img": "icons/magic/air/fog-gas-smoke-dense-pink.webp",
|
||||||
|
|
@ -643,7 +647,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "x6FbcrfOscb3er6P",
|
"_id": "x6FbcrfOscb3er6P",
|
||||||
"img": "icons/magic/unholy/silhouette-robe-evil-glow.webp",
|
"img": "icons/magic/unholy/silhouette-robe-evil-glow.webp",
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 86,
|
"page": 86,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "tyBOpLfigAhI9bU3",
|
"_id": "tyBOpLfigAhI9bU3",
|
||||||
|
|
@ -364,7 +365,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "ohASSruBxcvuItIK",
|
"_id": "ohASSruBxcvuItIK",
|
||||||
"img": "icons/magic/unholy/barrier-fire-pink.webp",
|
"img": "icons/magic/unholy/barrier-fire-pink.webp",
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 86,
|
"page": 86,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "zx99sOGTXicP4SSD",
|
"_id": "zx99sOGTXicP4SSD",
|
||||||
|
|
@ -272,7 +273,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "WP6xQtYzouPEFr82",
|
"_id": "WP6xQtYzouPEFr82",
|
||||||
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 76,
|
"page": 76,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "9x2xY9zwc3xzbXo5",
|
"_id": "9x2xY9zwc3xzbXo5",
|
||||||
|
|
@ -285,7 +286,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
@ -388,7 +390,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 91,
|
"page": 91,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "pnyjIGxxvurcWmTv",
|
"_id": "pnyjIGxxvurcWmTv",
|
||||||
|
|
@ -329,7 +330,8 @@
|
||||||
"resource": null,
|
"resource": null,
|
||||||
"actions": {},
|
"actions": {},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "BKgv2D1IdI813R8k",
|
"_id": "BKgv2D1IdI813R8k",
|
||||||
"img": "icons/skills/movement/arrows-up-trio-red.webp",
|
"img": "icons/skills/movement/arrows-up-trio-red.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 92,
|
"page": 92,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "kE4dfhqmIQpNd44e",
|
"_id": "kE4dfhqmIQpNd44e",
|
||||||
|
|
@ -290,7 +291,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "FC8PIf4BVkhmoJX8",
|
"_id": "FC8PIf4BVkhmoJX8",
|
||||||
"img": "icons/magic/death/skull-flames-white-blue.webp",
|
"img": "icons/magic/death/skull-flames-white-blue.webp",
|
||||||
|
|
@ -412,7 +414,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "dlMdfUjy2GaqgeOJ",
|
"_id": "dlMdfUjy2GaqgeOJ",
|
||||||
"img": "icons/creatures/unholy/demon-fire-horned-mask.webp",
|
"img": "icons/creatures/unholy/demon-fire-horned-mask.webp",
|
||||||
|
|
@ -507,7 +510,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "7qjx1c4C1fUfvXnu",
|
"_id": "7qjx1c4C1fUfvXnu",
|
||||||
"img": "icons/skills/melee/strike-weapons-orange.webp",
|
"img": "icons/skills/melee/strike-weapons-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 92,
|
"page": 92,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "2VN3BftageoTTIzu",
|
"_id": "2VN3BftageoTTIzu",
|
||||||
|
|
@ -454,7 +455,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "Y3W44ifKIcoYpONN",
|
"_id": "Y3W44ifKIcoYpONN",
|
||||||
"img": "icons/skills/melee/spear-tips-quintuple-orange.webp",
|
"img": "icons/skills/melee/spear-tips-quintuple-orange.webp",
|
||||||
|
|
@ -509,7 +511,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "6BKWOTuxQWJd5RP5",
|
"_id": "6BKWOTuxQWJd5RP5",
|
||||||
"img": "icons/creatures/unholy/demon-fire-horned-winged-roar.webp",
|
"img": "icons/creatures/unholy/demon-fire-horned-winged-roar.webp",
|
||||||
|
|
@ -587,7 +590,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "FLp1dPSJz1ezY0gD",
|
"_id": "FLp1dPSJz1ezY0gD",
|
||||||
"img": "icons/magic/control/fear-fright-shadow-monster-red.webp",
|
"img": "icons/magic/control/fear-fright-shadow-monster-red.webp",
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 92,
|
"page": 92,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "SxSOkM4bcVOFyjbo",
|
"_id": "SxSOkM4bcVOFyjbo",
|
||||||
|
|
@ -256,7 +257,8 @@
|
||||||
"resource": null,
|
"resource": null,
|
||||||
"actions": {},
|
"actions": {},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "KVyhgMJSSHTwRISA",
|
"_id": "KVyhgMJSSHTwRISA",
|
||||||
"img": "icons/magic/control/fear-fright-monster-grin-purple-blue.webp",
|
"img": "icons/magic/control/fear-fright-monster-grin-purple-blue.webp",
|
||||||
|
|
@ -311,7 +313,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "pSAupMWw1eYqm84z",
|
"_id": "pSAupMWw1eYqm84z",
|
||||||
"img": "icons/magic/perception/eye-ringed-glow-angry-small-teal.webp",
|
"img": "icons/magic/perception/eye-ringed-glow-angry-small-teal.webp",
|
||||||
|
|
@ -383,7 +386,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "589tCxFc8KZ3rdzP",
|
"_id": "589tCxFc8KZ3rdzP",
|
||||||
"img": "icons/magic/perception/hand-eye-black.webp",
|
"img": "icons/magic/perception/hand-eye-black.webp",
|
||||||
|
|
|
||||||
|
|
@ -118,7 +118,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 92,
|
"page": 92,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "large"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "5lphJAgzoqZI3VoG",
|
"_id": "5lphJAgzoqZI3VoG",
|
||||||
|
|
@ -286,7 +287,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "a33PW8UkziliowlR",
|
"_id": "a33PW8UkziliowlR",
|
||||||
"img": "icons/skills/melee/maneuver-greatsword-yellow.webp",
|
"img": "icons/skills/melee/maneuver-greatsword-yellow.webp",
|
||||||
|
|
@ -393,7 +395,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "DjGydqLXT4rDa7Av",
|
"_id": "DjGydqLXT4rDa7Av",
|
||||||
"img": "icons/skills/melee/blood-slash-foam-red.webp",
|
"img": "icons/skills/melee/blood-slash-foam-red.webp",
|
||||||
|
|
@ -482,7 +485,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "2F75BO0xEU8Zlj7T",
|
"_id": "2F75BO0xEU8Zlj7T",
|
||||||
"img": "icons/creatures/unholy/demon-fire-horned-clawed.webp",
|
"img": "icons/creatures/unholy/demon-fire-horned-clawed.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 86,
|
"page": 86,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "large"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "NoRZ1PqB8N5wcIw0",
|
"_id": "NoRZ1PqB8N5wcIw0",
|
||||||
|
|
@ -308,7 +309,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "WEbHwamS5ZBphiKq",
|
"_id": "WEbHwamS5ZBphiKq",
|
||||||
"img": "icons/creatures/unholy/demons-horned-glowing-pink.webp",
|
"img": "icons/creatures/unholy/demons-horned-glowing-pink.webp",
|
||||||
|
|
@ -403,7 +405,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "3mOBJE5c3cP2cGP1",
|
"_id": "3mOBJE5c3cP2cGP1",
|
||||||
"img": "icons/skills/melee/strike-weapons-orange.webp",
|
"img": "icons/skills/melee/strike-weapons-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 93,
|
"page": 93,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "tBWHW00epmMnkawe",
|
"_id": "tBWHW00epmMnkawe",
|
||||||
|
|
@ -350,7 +351,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "o69lipskvBwGVhe4",
|
"_id": "o69lipskvBwGVhe4",
|
||||||
"img": "icons/magic/sonic/projectile-sound-rings-wave.webp",
|
"img": "icons/magic/sonic/projectile-sound-rings-wave.webp",
|
||||||
|
|
@ -456,7 +458,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "BQPGgbNzKbNkGDJb",
|
"_id": "BQPGgbNzKbNkGDJb",
|
||||||
"img": "icons/skills/melee/strike-slashes-red.webp",
|
"img": "icons/skills/melee/strike-slashes-red.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 76,
|
"page": 76,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "wNzeuQLfLUMvgHlQ",
|
"_id": "wNzeuQLfLUMvgHlQ",
|
||||||
|
|
@ -417,7 +418,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 93,
|
"page": 93,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "wR7cFKrHvRzbzhBT",
|
"_id": "wR7cFKrHvRzbzhBT",
|
||||||
|
|
@ -337,7 +338,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "i9HbArl09dX2BvzY",
|
"_id": "i9HbArl09dX2BvzY",
|
||||||
"img": "icons/magic/nature/root-vines-grow-brown.webp",
|
"img": "icons/magic/nature/root-vines-grow-brown.webp",
|
||||||
|
|
@ -392,7 +394,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "yKWQLL3qsEZlQjyb",
|
"_id": "yKWQLL3qsEZlQjyb",
|
||||||
"img": "icons/magic/nature/tree-animated-stump-mushrooms-teal.webp",
|
"img": "icons/magic/nature/tree-animated-stump-mushrooms-teal.webp",
|
||||||
|
|
@ -517,7 +520,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "z4JbqiHuxrWy6Cpu",
|
"_id": "z4JbqiHuxrWy6Cpu",
|
||||||
"img": "icons/magic/nature/vines-thorned-curled-glow-teal-purple.webp",
|
"img": "icons/magic/nature/vines-thorned-curled-glow-teal-purple.webp",
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 86,
|
"page": 86,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "TLzY1nDw0Bu9Ud40",
|
"_id": "TLzY1nDw0Bu9Ud40",
|
||||||
|
|
@ -330,7 +331,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "u5NL1eUJeAkIEpgt",
|
"_id": "u5NL1eUJeAkIEpgt",
|
||||||
"img": "icons/magic/lightning/bolt-strike-sparks-teal.webp",
|
"img": "icons/magic/lightning/bolt-strike-sparks-teal.webp",
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 93,
|
"page": 93,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "tiny"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "P7h54ZePFPHpYwvB",
|
"_id": "P7h54ZePFPHpYwvB",
|
||||||
|
|
@ -272,7 +273,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "13OraSLq2YjpZqbm",
|
"_id": "13OraSLq2YjpZqbm",
|
||||||
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 86,
|
"page": 86,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"ownership": {
|
"ownership": {
|
||||||
|
|
@ -336,7 +337,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "ojiIZHBd0sMLxSUE",
|
"_id": "ojiIZHBd0sMLxSUE",
|
||||||
"img": "icons/skills/melee/hand-grip-sword-orange.webp",
|
"img": "icons/skills/melee/hand-grip-sword-orange.webp",
|
||||||
|
|
@ -391,7 +393,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "zcfyEY29yWqJtZbl",
|
"_id": "zcfyEY29yWqJtZbl",
|
||||||
"img": "icons/magic/defensive/shield-barrier-blue.webp",
|
"img": "icons/magic/defensive/shield-barrier-blue.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 86,
|
"page": 86,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "ChwwVqowFw8hJQwT",
|
"_id": "ChwwVqowFw8hJQwT",
|
||||||
|
|
@ -354,7 +355,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "g0h3Zo6xqgfSlyxi",
|
"_id": "g0h3Zo6xqgfSlyxi",
|
||||||
"img": "icons/skills/melee/strike-slashes-red.webp",
|
"img": "icons/skills/melee/strike-slashes-red.webp",
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 97,
|
"page": 97,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "OsLG2BjaEdTZUJU9",
|
"_id": "OsLG2BjaEdTZUJU9",
|
||||||
|
|
@ -350,7 +351,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "gC4whvt2r9Tfso9Y",
|
"_id": "gC4whvt2r9Tfso9Y",
|
||||||
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 97,
|
"page": 97,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "PELRry1vqjBzSAlr",
|
"_id": "PELRry1vqjBzSAlr",
|
||||||
|
|
@ -311,7 +312,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "s15sNyb3JYMzBLIU",
|
"_id": "s15sNyb3JYMzBLIU",
|
||||||
"img": "icons/magic/fire/projectile-beams-salvo-red.webp",
|
"img": "icons/magic/fire/projectile-beams-salvo-red.webp",
|
||||||
|
|
@ -364,7 +366,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "ecp9o8t1dQFXGsse",
|
"_id": "ecp9o8t1dQFXGsse",
|
||||||
"img": "icons/magic/death/skull-energy-light-white.webp",
|
"img": "icons/magic/death/skull-energy-light-white.webp",
|
||||||
|
|
@ -429,7 +432,8 @@
|
||||||
"resource": null,
|
"resource": null,
|
||||||
"actions": {},
|
"actions": {},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "C74czwNeWF5vS1DZ",
|
"_id": "C74czwNeWF5vS1DZ",
|
||||||
"img": "icons/magic/symbols/ring-circle-smoke-blue.webp",
|
"img": "icons/magic/symbols/ring-circle-smoke-blue.webp",
|
||||||
|
|
@ -549,7 +553,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "gwSgBhkcekCGvXxz",
|
"_id": "gwSgBhkcekCGvXxz",
|
||||||
"img": "icons/magic/unholy/strike-hand-glow-pink.webp",
|
"img": "icons/magic/unholy/strike-hand-glow-pink.webp",
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 97,
|
"page": 97,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"prototypeToken": {
|
"prototypeToken": {
|
||||||
"name": "Fallen Warlord: Realm Breaker",
|
"name": "Fallen Warlord: Realm Breaker",
|
||||||
|
|
@ -476,7 +477,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "PVLjJaQLH3LK3svk",
|
"_id": "PVLjJaQLH3LK3svk",
|
||||||
"img": "icons/skills/melee/blood-slash-foam-red.webp",
|
"img": "icons/skills/melee/blood-slash-foam-red.webp",
|
||||||
|
|
@ -612,7 +614,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "48tIwFQr64IQ5LaY",
|
"_id": "48tIwFQr64IQ5LaY",
|
||||||
"img": "icons/magic/control/fear-fright-monster-grin-red-orange.webp",
|
"img": "icons/magic/control/fear-fright-monster-grin-red-orange.webp",
|
||||||
|
|
@ -690,7 +693,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "v74W0MUqVi9vPUEw",
|
"_id": "v74W0MUqVi9vPUEw",
|
||||||
"img": "icons/magic/death/skull-energy-light-purple.webp",
|
"img": "icons/magic/death/skull-energy-light-purple.webp",
|
||||||
|
|
@ -715,7 +719,8 @@
|
||||||
"resource": null,
|
"resource": null,
|
||||||
"actions": {},
|
"actions": {},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "RscRTl8U8u6WcwAB",
|
"_id": "RscRTl8U8u6WcwAB",
|
||||||
"img": "icons/magic/unholy/silhouette-evil-horned-giant.webp",
|
"img": "icons/magic/unholy/silhouette-evil-horned-giant.webp",
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 98,
|
"page": 98,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"prototypeToken": {
|
"prototypeToken": {
|
||||||
"name": "Fallen Warlord: Undefeated Champion",
|
"name": "Fallen Warlord: Undefeated Champion",
|
||||||
|
|
@ -470,7 +471,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "t8yOkGWmPgQ6EbIr",
|
"_id": "t8yOkGWmPgQ6EbIr",
|
||||||
"img": "icons/skills/melee/sword-stuck-glowing-pink.webp",
|
"img": "icons/skills/melee/sword-stuck-glowing-pink.webp",
|
||||||
|
|
@ -525,7 +527,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "AP7W9ruUCdTHO69S",
|
"_id": "AP7W9ruUCdTHO69S",
|
||||||
"img": "icons/magic/death/undead-skeleton-worn-blue.webp",
|
"img": "icons/magic/death/undead-skeleton-worn-blue.webp",
|
||||||
|
|
@ -615,7 +618,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "55P7ZijSbQeVHCw4",
|
"_id": "55P7ZijSbQeVHCw4",
|
||||||
"img": "icons/magic/unholy/barrier-fire-pink.webp",
|
"img": "icons/magic/unholy/barrier-fire-pink.webp",
|
||||||
|
|
@ -749,7 +753,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "ReWtcLE5akrSauI1",
|
"_id": "ReWtcLE5akrSauI1",
|
||||||
"img": "icons/skills/melee/strike-weapons-orange.webp",
|
"img": "icons/skills/melee/strike-weapons-orange.webp",
|
||||||
|
|
@ -827,7 +832,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "tQRotPLi3eokgUdM",
|
"_id": "tQRotPLi3eokgUdM",
|
||||||
"img": "icons/magic/death/skull-energy-light-purple.webp",
|
"img": "icons/magic/death/skull-energy-light-purple.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 87,
|
"page": 87,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "large"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "8VZIgU12cB3cvlyH",
|
"_id": "8VZIgU12cB3cvlyH",
|
||||||
|
|
@ -332,7 +333,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "6ZrDjgnWufJohkp1",
|
"_id": "6ZrDjgnWufJohkp1",
|
||||||
"img": "icons/skills/ranged/arrow-flying-broadhead-metal.webp",
|
"img": "icons/skills/ranged/arrow-flying-broadhead-metal.webp",
|
||||||
|
|
@ -420,7 +422,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "w1oHm0NoEavQgUzl",
|
"_id": "w1oHm0NoEavQgUzl",
|
||||||
"img": "icons/creatures/mammals/ox-bull-horned-glowing-orange.webp",
|
"img": "icons/creatures/mammals/ox-bull-horned-glowing-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 87,
|
"page": 87,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "large"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "YnObCleGjPT7yqEc",
|
"_id": "YnObCleGjPT7yqEc",
|
||||||
|
|
@ -311,7 +312,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "ro8AtBdgklyyuydK",
|
"_id": "ro8AtBdgklyyuydK",
|
||||||
"img": "icons/skills/melee/shield-damaged-broken-orange.webp",
|
"img": "icons/skills/melee/shield-damaged-broken-orange.webp",
|
||||||
|
|
@ -410,7 +412,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "kKBbEAffbHxmHo15",
|
"_id": "kKBbEAffbHxmHo15",
|
||||||
"img": "icons/skills/melee/strike-flail-spiked-pink.webp",
|
"img": "icons/skills/melee/strike-flail-spiked-pink.webp",
|
||||||
|
|
@ -505,7 +508,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "B0EniYxyLvjJSqYb",
|
"_id": "B0EniYxyLvjJSqYb",
|
||||||
"img": "icons/skills/melee/strike-weapons-orange.webp",
|
"img": "icons/skills/melee/strike-weapons-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 87,
|
"page": 87,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "large"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"ownership": {
|
"ownership": {
|
||||||
|
|
@ -410,7 +411,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "MabIQE1Kjn60j08J",
|
"_id": "MabIQE1Kjn60j08J",
|
||||||
"img": "icons/skills/melee/strike-slashes-orange.webp",
|
"img": "icons/skills/melee/strike-slashes-orange.webp",
|
||||||
|
|
@ -553,7 +555,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "NEOQ0E9AGSSIDm4v",
|
"_id": "NEOQ0E9AGSSIDm4v",
|
||||||
"img": "icons/skills/movement/arrow-upward-yellow.webp",
|
"img": "icons/skills/movement/arrow-upward-yellow.webp",
|
||||||
|
|
@ -671,7 +674,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "jY0ynjYvbS6E3NgJ",
|
"_id": "jY0ynjYvbS6E3NgJ",
|
||||||
"img": "icons/skills/movement/arrow-down-pink.webp",
|
"img": "icons/skills/movement/arrow-down-pink.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 76,
|
"page": 76,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "IIWV4ysJPFPnTP7W",
|
"_id": "IIWV4ysJPFPnTP7W",
|
||||||
|
|
@ -359,7 +360,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 76,
|
"page": 76,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "small"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "4PfLnaCrOcMdb4dK",
|
"_id": "4PfLnaCrOcMdb4dK",
|
||||||
|
|
@ -306,7 +307,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 87,
|
"page": 87,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "large"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "5s8wSvpyC5rxY5aD",
|
"_id": "5s8wSvpyC5rxY5aD",
|
||||||
|
|
@ -274,7 +275,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "FMgB28X1LammRInU",
|
"_id": "FMgB28X1LammRInU",
|
||||||
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 76,
|
"page": 76,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "fmfntuJ8mHRCAktP",
|
"_id": "fmfntuJ8mHRCAktP",
|
||||||
|
|
@ -314,7 +315,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
@ -419,7 +421,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
|
|
@ -552,7 +555,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 77,
|
"page": 77,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "large"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "8KWVLWXFhlY2kYx0",
|
"_id": "8KWVLWXFhlY2kYx0",
|
||||||
|
|
@ -385,7 +386,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
@ -565,7 +567,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 88,
|
"page": 88,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "8mJYMpbLTb8qIOrr",
|
"_id": "8mJYMpbLTb8qIOrr",
|
||||||
|
|
@ -484,7 +485,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "9SO2ov36lFH2YV0S",
|
"_id": "9SO2ov36lFH2YV0S",
|
||||||
"img": "icons/creatures/reptiles/snake-fangs-bite-green.webp",
|
"img": "icons/creatures/reptiles/snake-fangs-bite-green.webp",
|
||||||
|
|
@ -600,7 +602,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "047o6OtNlUwLG1H1",
|
"_id": "047o6OtNlUwLG1H1",
|
||||||
"img": "icons/magic/earth/strike-body-stone-crumble.webp",
|
"img": "icons/magic/earth/strike-body-stone-crumble.webp",
|
||||||
|
|
@ -695,7 +698,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "IRIaFxFughjXVu0Y",
|
"_id": "IRIaFxFughjXVu0Y",
|
||||||
"img": "icons/skills/melee/strike-weapons-orange.webp",
|
"img": "icons/skills/melee/strike-weapons-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 93,
|
"page": 93,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "gargantuan"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "dsfB3YhoL5SudvS2",
|
"_id": "dsfB3YhoL5SudvS2",
|
||||||
|
|
@ -487,7 +488,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "q45DiEFlXqcXZ5hv",
|
"_id": "q45DiEFlXqcXZ5hv",
|
||||||
"img": "icons/magic/earth/barrier-stone-brown-green.webp",
|
"img": "icons/magic/earth/barrier-stone-brown-green.webp",
|
||||||
|
|
@ -621,7 +623,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "ag7t5EW358M0qiSL",
|
"_id": "ag7t5EW358M0qiSL",
|
||||||
"img": "icons/skills/melee/strike-weapons-orange.webp",
|
"img": "icons/skills/melee/strike-weapons-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 93,
|
"page": 93,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "gargantuan"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "xIICT6tEdnA7dKDV",
|
"_id": "xIICT6tEdnA7dKDV",
|
||||||
|
|
@ -310,7 +311,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "B8ZrtRCZrwwwWJOE",
|
"_id": "B8ZrtRCZrwwwWJOE",
|
||||||
"img": "icons/magic/water/projectile-icecicle-glowing.webp",
|
"img": "icons/magic/water/projectile-icecicle-glowing.webp",
|
||||||
|
|
@ -438,7 +440,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "bcwFQeuU6ZfIGjau",
|
"_id": "bcwFQeuU6ZfIGjau",
|
||||||
"img": "icons/magic/water/vortex-water-whirlpool-blue.webp",
|
"img": "icons/magic/water/vortex-water-whirlpool-blue.webp",
|
||||||
|
|
@ -533,7 +536,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "BGE42W1XPd0vpimR",
|
"_id": "BGE42W1XPd0vpimR",
|
||||||
"img": "icons/magic/water/tendrils-ice-thorns.webp",
|
"img": "icons/magic/water/tendrils-ice-thorns.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 80,
|
"page": 80,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "SHXedd9zZPVfUgUa",
|
"_id": "SHXedd9zZPVfUgUa",
|
||||||
|
|
@ -447,7 +448,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
|
|
@ -540,7 +542,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 98,
|
"page": 98,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "kabueAo6BALApWqp",
|
"_id": "kabueAo6BALApWqp",
|
||||||
|
|
@ -330,7 +331,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "Ye35DuZroQfeFoNw",
|
"_id": "Ye35DuZroQfeFoNw",
|
||||||
"img": "icons/skills/ranged/arrows-flying-salvo-yellow.webp",
|
"img": "icons/skills/ranged/arrows-flying-salvo-yellow.webp",
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 98,
|
"page": 98,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "VENwg7xEFcYObjmT",
|
"_id": "VENwg7xEFcYObjmT",
|
||||||
|
|
@ -327,7 +328,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "ZpypjDbaurs1YSFb",
|
"_id": "ZpypjDbaurs1YSFb",
|
||||||
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
"img": "icons/creatures/abilities/tail-strike-bone-orange.webp",
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 77,
|
"page": 77,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "uRtghKE9mHlII4rs",
|
"_id": "uRtghKE9mHlII4rs",
|
||||||
|
|
@ -339,7 +340,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 77,
|
"page": 77,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "mK3A5FTx6k8iPU3F",
|
"_id": "mK3A5FTx6k8iPU3F",
|
||||||
|
|
@ -292,7 +293,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
@ -356,7 +358,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
@ -452,7 +455,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 95,
|
"page": 95,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "i2UNbRvgyoSs07M6",
|
"_id": "i2UNbRvgyoSs07M6",
|
||||||
|
|
@ -448,7 +449,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "Oj6qkLG1N6uqQHcx",
|
"_id": "Oj6qkLG1N6uqQHcx",
|
||||||
"img": "icons/creatures/abilities/fang-tooth-blood-red.webp",
|
"img": "icons/creatures/abilities/fang-tooth-blood-red.webp",
|
||||||
|
|
@ -503,7 +505,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "IWtpuQCuV82lOSry",
|
"_id": "IWtpuQCuV82lOSry",
|
||||||
"img": "icons/creatures/mammals/bat-giant-tattered-purple.webp",
|
"img": "icons/creatures/mammals/bat-giant-tattered-purple.webp",
|
||||||
|
|
@ -601,7 +604,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "6FsQf339qGHnz3ZF",
|
"_id": "6FsQf339qGHnz3ZF",
|
||||||
"img": "icons/magic/unholy/strike-beam-blood-small-red-purple.webp",
|
"img": "icons/magic/unholy/strike-beam-blood-small-red-purple.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 98,
|
"page": 98,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "r1mbfSSwKWdcFdAU",
|
"_id": "r1mbfSSwKWdcFdAU",
|
||||||
|
|
@ -371,7 +372,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "FilEB21L5q9XxKE1",
|
"_id": "FilEB21L5q9XxKE1",
|
||||||
"img": "icons/magic/light/beams-rays-orange-purple-small.webp",
|
"img": "icons/magic/light/beams-rays-orange-purple-small.webp",
|
||||||
|
|
@ -514,7 +516,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "Vrb8dIJcOJ3ClwO5",
|
"_id": "Vrb8dIJcOJ3ClwO5",
|
||||||
"img": "icons/magic/light/beam-strike-orange-gold.webp",
|
"img": "icons/magic/light/beam-strike-orange-gold.webp",
|
||||||
|
|
@ -569,7 +572,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "9LpLXpQBfQryJA60",
|
"_id": "9LpLXpQBfQryJA60",
|
||||||
"img": "icons/magic/holy/barrier-shield-winged-blue.webp",
|
"img": "icons/magic/holy/barrier-shield-winged-blue.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 94,
|
"page": 94,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "large"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "6hbqmxDXFOzZJDk4",
|
"_id": "6hbqmxDXFOzZJDk4",
|
||||||
|
|
@ -416,7 +417,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "pfXYuH7rtsyVjSXh",
|
"_id": "pfXYuH7rtsyVjSXh",
|
||||||
"img": "icons/creatures/slimes/slime-face-melting-green.webp",
|
"img": "icons/creatures/slimes/slime-face-melting-green.webp",
|
||||||
|
|
@ -508,7 +510,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "Mq90kFBM5ix2pzzh",
|
"_id": "Mq90kFBM5ix2pzzh",
|
||||||
"img": "icons/creatures/slimes/slime-movement-pseudopods-green.webp",
|
"img": "icons/creatures/slimes/slime-movement-pseudopods-green.webp",
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 94,
|
"page": 94,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "huge"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "MI126iMOOobQ1Obn",
|
"_id": "MI126iMOOobQ1Obn",
|
||||||
|
|
@ -354,7 +355,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "b2KflqWoOxHMQf97",
|
"_id": "b2KflqWoOxHMQf97",
|
||||||
"img": "icons/magic/life/cross-beam-green.webp",
|
"img": "icons/magic/life/cross-beam-green.webp",
|
||||||
|
|
@ -432,7 +434,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"_id": "bCeCu8M25izOAsuY",
|
"_id": "bCeCu8M25izOAsuY",
|
||||||
"img": "icons/magic/death/skull-energy-light-white.webp",
|
"img": "icons/magic/death/skull-energy-light-white.webp",
|
||||||
|
|
@ -485,7 +488,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "reaction"
|
||||||
},
|
},
|
||||||
"_id": "sJzjcRBgYRp5f53E",
|
"_id": "sJzjcRBgYRp5f53E",
|
||||||
"img": "icons/magic/symbols/star-rising-purple.webp",
|
"img": "icons/magic/symbols/star-rising-purple.webp",
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 77,
|
"page": 77,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "5Lh1T0zaT8Pkr2U2",
|
"_id": "5Lh1T0zaT8Pkr2U2",
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,8 @@
|
||||||
"source": "Daggerheart SRD",
|
"source": "Daggerheart SRD",
|
||||||
"page": 78,
|
"page": 78,
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
},
|
||||||
|
"size": "medium"
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"_id": "MbBPIOxaxXYNApXz",
|
"_id": "MbBPIOxaxXYNApXz",
|
||||||
|
|
@ -260,7 +261,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
|
|
@ -397,7 +399,8 @@
|
||||||
},
|
},
|
||||||
"originItemType": null,
|
"originItemType": null,
|
||||||
"subType": null,
|
"subType": null,
|
||||||
"originId": null
|
"originId": null,
|
||||||
|
"featureForm": "action"
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [],
|
||||||
"folder": null,
|
"folder": null,
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue