From c6859f838425ec7f4aa6391e8c244410992d2c8d Mon Sep 17 00:00:00 2001 From: Zen-Raven Date: Fri, 26 Sep 2025 19:06:20 -0700 Subject: [PATCH 1/3] Code Cleanup -Refactored ability and feature sharing sheet worker code - Reorganized code for readability - Moved Draw Steel logo to top of sheet so it will be displayed for both the character and NPC sheets - Changed styling on NPC ability edit checkboxes to be pencils. --- Draw Steel/draw-steel.css | 29 +- Draw Steel/draw-steel.html | 659 +++++++++++++++++-------------------- 2 files changed, 323 insertions(+), 365 deletions(-) diff --git a/Draw Steel/draw-steel.css b/Draw Steel/draw-steel.css index 564a97fe3161..db15ebdb5753 100644 --- a/Draw Steel/draw-steel.css +++ b/Draw Steel/draw-steel.css @@ -21,6 +21,10 @@ filter: invert(100%); } +.sheet-header { + display: grid; +} + .sheet-body { min-width:800px; } @@ -1419,9 +1423,24 @@ sheet-darkmode .npc-header-panel { grid-template-columns: 30px repeat(4, 1fr) 30px; } -input.npc-ability-edit-toggle { - right: 5px; +#npc-ability-edit-toggle { + right: 5px; position: absolute; + appearance: none; + background-color: transparent; + border-color: transparent; + color: #aaa; +} + +#npc-ability-edit-toggle::before { + content: 'p'; + font-family: "Pictos"; + font-size: 1.5em; + cursor: pointer; +} + +#npc-ability-edit-toggle:hover { + color: #ccc; } input.npc-ability-edit-toggle:not(:checked) ~ div.npc-ability-card-edit, @@ -1634,7 +1653,7 @@ label.npc-edit-icon { font-size: 1.5em; position: absolute; left: calc(100% - 45px); - top: 67px; + top: 125px; color: #aaa; cursor: pointer; } @@ -1671,8 +1690,8 @@ input.npc-edit-toggle:not(:checked) ~ div.npc-edit { grid-template-columns: 1fr 1fr; } -.npc-edit-stats > input[type="text"], -.npc-edit-stats > input[type="number"] { +.npc-edit .npc-edit-stats > input[type="text"], +.npc-edit .npc-edit-stats > input[type="number"] { width: 4.5em; } diff --git a/Draw Steel/draw-steel.html b/Draw Steel/draw-steel.html index 8ce3c2ea501b..af5dba3669ed 100644 --- a/Draw Steel/draw-steel.html +++ b/Draw Steel/draw-steel.html @@ -1,14 +1,16 @@ +
+

+ Powered By Draw Steel +

+
-

- Powered By Draw Steel -

@@ -1263,24 +1265,7 @@
} /** -**Looking for Power Roll for Ability Card -**/ -on("change:repeating_abilities:has_power_roll", function(event) { - const repeatingId = event.sourceAttribute.match(/repeating_abilities_[^_]+/)[0]; - const sourceAttr = `${repeatingId}_has_power_roll`; - const targetAttr = `${repeatingId}_show_power_roll`; - - getAttrs([sourceAttr], function(values) { - const show = values[sourceAttr] === "on" ? "1" : "0"; - setAttrs({ - [targetAttr]: show - }); - }); -}); - - -/** -**Characteristic Roll +** Power Roll **/ async function rollPower(characteristic) { @@ -1348,186 +1333,50 @@
}); } - $20('.npc-characteristic-input-group > label').on('click', (e) => { - const characteristic = e.htmlAttributes['data-characteristic']; - rollPower(characteristic); - }); - - $20('.characteristic-input-group > label').on('click', (e) => { - const characteristic = e.htmlAttributes['data-characteristic']; - rollPower(characteristic); - }); - /** -**Feature display -**/ -on('clicked:repeating_classfeatures:classfeatureshare', async (event) => { - const attrs = await getAttrsAsync([ - 'repeating_classfeatures_classfeature_name', - 'repeating_classfeatures_classfeature_description', - ]); - - const directMap = { - name: attrs.repeating_classfeatures_classfeature_name || '', - effect: attrs.repeating_classfeatures_classfeature_description || '', - }; +** Feature Display +**/ - const rollValueMap = { - hasEffect: directMap.effect.trim() ? 1 : 0, - }; - - const roll = `&{template:ability} ` - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - .join('') - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `) - .join(''); - - console.log('classfeature values', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); -}); - -on('clicked:repeating_ancestrytraits:ancfeatureshare', async (event) => { - const attrs = await getAttrsAsync([ - 'repeating_ancestrytraits_ancestrytrait_name', - 'repeating_ancestrytraits_ancestrytrait_description', - ]); - - const directMap = { - name: attrs.repeating_ancestrytraits_ancestrytrait_name || '', - effect: attrs.repeating_ancestrytraits_ancestrytrait_description || '', - }; - - const rollValueMap = { - hasEffect: directMap.effect.trim() ? 1 : 0, - }; - - const roll = `&{template:ability} ` - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - .join('') - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `) - .join(''); - - console.log('ancestrytrait values', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); -}); - -on('clicked:repeating_perks:perkfeatureshare', async (event) => { - const attrs = await getAttrsAsync([ - 'repeating_perks_perk_name', - 'repeating_perks_perk_description', - ]); - - const directMap = { - name: attrs.repeating_perks_perk_name || '', - effect: attrs.repeating_perks_perk_description || '', - }; - - const rollValueMap = { - hasEffect: directMap.effect.trim() ? 1 : 0, - }; - - const roll = `&{template:ability} ` - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - .join('') - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `) - .join(''); - - console.log('perk values', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); -}); - -on('clicked:repeating_titles:titlefeatureshare', async (event) => { - const attrs = await getAttrsAsync([ - 'repeating_titles_title_name', - 'repeating_titles_title_description', - ]); - - const directMap = { - name: attrs.repeating_titles_title_name || '', - effect: attrs.repeating_titles_title_description || '', - }; - - const rollValueMap = { - hasEffect: directMap.effect.trim() ? 1 : 0, - }; - - const roll = `&{template:ability} ` - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - .join('') - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `) - .join(''); - - console.log('title values', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); -}); + function featureDisplay(name, subtitle, description) { + const roll = `@{wtype}&{template:monsterability}` + + '{{charactername=@{character_name}}} ' + + '{{name=' + name + '}} ' + + '{{trait=' + description + '}} ' + + '{{subtype=' + subtitle + '}} ' + + '{{hasTrait=[[1]]}}'; + console.log('Feature Display:', roll); + startRoll(roll, ({ rollId }) => finishRoll(rollId)); + } /** -**Repeated Ability display +** Build Ability Roll + constructs and executes rolls using the ability sharing roll template **/ - on('clicked:repeating_abilities:share', async (event) => { - const abilityAttributeNames = [ - 'ability_name', 'ability_cost', 'ability_description', 'ability_keywords', - 'ability_type', 'ability_distance', 'ability_target', 'ability_trigger', - 'has_power_roll', 'ability_characteristic', - 'ability_tier_1', 'ability_tier_2', 'ability_tier_3', 'ability_effect', - ]; - const attrs = await getAttrsAsync([ - 'resource_name', - ...abilityAttributeNames.map(x => `repeating_abilities_${x}`), - ]); - const resourceName = attrs.resource_name || getTranslationByKey('resource-name-placeholder'); - - const directMap = { - name: attrs.repeating_abilities_ability_cost && attrs.repeating_abilities_ability_cost !== '0' - ? `${attrs.repeating_abilities_ability_name} (${attrs.repeating_abilities_ability_cost} ${resourceName})` - : attrs.repeating_abilities_ability_name, - cost: attrs.repeating_abilities_ability_cost, - description: attrs.repeating_abilities_ability_description, - keywords: attrs.repeating_abilities_ability_keywords, - distance: attrs.repeating_abilities_ability_distance, - target: attrs.repeating_abilities_ability_target, - trigger: attrs.repeating_abilities_ability_trigger, - characteristic: attrs.repeating_abilities_ability_characteristic, - tier1: attrs.repeating_abilities_ability_tier_1, - tier2: attrs.repeating_abilities_ability_tier_2, - tier3: attrs.repeating_abilities_ability_tier_3, - effect: attrs.repeating_abilities_ability_effect, - }; - const translateMap = { - type: attrs.repeating_abilities_ability_type || 'no-action', - }; - const rollValueMap = { - hasTrigger: attrs.repeating_abilities_ability_type.includes('triggered') - && attrs.repeating_abilities_ability_trigger - ? 1 : 0, - hasPowerRoll: attrs.repeating_abilities_has_power_roll === 'on' - ? 1 : 0, - hasEffect: attrs.repeating_abilities_ability_effect - ? 1 : 0, - hasDistance: attrs.repeating_abilities_ability_distance - ? 1 : 0, - hasTarget: attrs.repeating_abilities_ability_target - ? 1 : 0, + function buildAbilityRoll(directMap, rollValueMap) { + + const isDefined = (value) => { + // Exclude null, undefined, and empty strings + if (!value) return false; + // Specifically exclude the string '0' (for things like ability_cost = 0) + if (typeof value === 'string' && value.trim() === '0') return false; + return true; }; - const roll = `&{template:ability} ` + + const roll = `@{wtype}&{template:monsterability} ` + + '{{charactername=@{character_name}}} ' + '{{powerRoll=^{power-roll}}} ' + Object.entries(directMap) + .filter(([key, value]) => isDefined(value)) .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(translateMap) - .map(([key, value]) => `{{${key}=^{${value}}}} `) + .join(' ') + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - console.log('ability values', roll); + .filter(([key, value]) => value === 1) + .map(([key, value]) => `{{${key}=[[${value}]]}} `) + .join(' '); startRoll(roll, ({ rollId }) => finishRoll(rollId)); - }); + return roll; + } + /** **Repeated Ability power roll @@ -1610,52 +1459,8 @@
startRoll(roll, ({ rollId }) => finishRoll(rollId)); }); - /** - **Melee Free Strike Display - **/ - on('clicked:melee_share', async (event) => { - const attributeNames = [ - 'melee_free_strike_name', - 'melee_free_strike_keywords', - 'melee_free_strike_distance', - 'melee_free_strike_target', - 'melee_free_strike_characteristic', - 'melee_free_strike_tier_1', - 'melee_free_strike_tier_2', - 'melee_free_strike_tier_3' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.melee_free_strike_name, - keywords: attrs.melee_free_strike_keywords, - distance: attrs.melee_free_strike_distance, - target: attrs.melee_free_strike_target, - characteristic: attrs.melee_free_strike_characteristic, - tier1: attrs.melee_free_strike_tier_1, - tier2: attrs.melee_free_strike_tier_2, - tier3: attrs.melee_free_strike_tier_3 - }; -const rollValueMap = { - hasPowerRoll: '1', - hasDistance: '1', - hasTarget: '1', -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + '{{type=^{main-action}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Melee Free Strike roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); - }); - /** **Melee Free Strike Power Roll **/ @@ -1715,58 +1520,13 @@
+ '{{type=^{main-action}}} ' + Object.entries(directMap) .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); + + Object.entries(rollValueMap) + .map(([key, value]) => `{{${key}=[[${value}]]}} `); console.log('Melee Free Strike power roll:', roll); startRoll(roll, ({ rollId }) => finishRoll(rollId)); }); - /** - **Ranged Free Strike Display - **/ - on('clicked:ranged_share', async (event) => { - const attributeNames = [ - 'ranged_free_strike_name', - 'ranged_free_strike_keywords', - 'ranged_free_strike_distance', - 'ranged_free_strike_target', - 'ranged_free_strike_characteristic', - 'ranged_free_strike_tier_1', - 'ranged_free_strike_tier_2', - 'ranged_free_strike_tier_3' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.ranged_free_strike_name, - keywords: attrs.ranged_free_strike_keywords, - distance: attrs.ranged_free_strike_distance, - target: attrs.ranged_free_strike_target, - characteristic: attrs.ranged_free_strike_characteristic, - tier1: attrs.ranged_free_strike_tier_1, - tier2: attrs.ranged_free_strike_tier_2, - tier3: attrs.ranged_free_strike_tier_3 - }; - -const rollValueMap = { - hasPowerRoll: '1', - hasDistance: '1', - hasTarget: '1', -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + '{{type=^{main-action}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Ranged Free Strike roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); - }); - /** **Ranged Free Strike Power Roll **/ @@ -1833,97 +1593,276 @@
startRoll(roll, ({ rollId }) => finishRoll(rollId)); }); - /** - ** Monster Abilities Share - **/ - on('clicked:repeating_npcabilities:share', async (event) => { - const abilityAttributeNames = [ - 'ability_name', 'ability_subtype', 'ability_malice_cost', 'ability_description', 'ability_keywords', - 'ability_trait', 'ability_solo_1_name', 'ability_solo_1_text', 'ability_solo_2_name', 'ability_solo_2_text', +/** +** Ability Sharing Handler +**/ + + async function handleAbilityShare(prefix) { + // 1. Define all possible ability attributes across both player and NPC sections. + const allAbilityAttributeNames = [ + 'ability_name', 'ability_cost', 'ability_description', 'ability_keywords', 'ability_type', 'ability_distance', 'ability_target', 'ability_trigger', - 'has_power_roll', 'ability_characteristic', 'ability_tier_1', 'ability_tier_2', 'ability_tier_3', - 'ability_effect', 'has_effect', 'ability_special', 'has_special', 'has_malice', 'ability_cost', 'ability_malice', + 'has_power_roll', 'ability_characteristic', + 'ability_tier_1', 'ability_tier_2', 'ability_tier_3', 'ability_effect', + 'ability_subtype', 'ability_malice_cost', 'ability_trait', + 'ability_solo_1_name', 'ability_solo_1_text', 'ability_solo_2_name', 'ability_solo_2_text', + 'has_effect', 'ability_special', 'has_special', 'has_malice', 'ability_malice', + ]; + // 2. Define the character-level attributes needed for both. + const globalAttrsToGet = prefix === 'repeating_abilities' + ? ['resource_name'] // Player abilities need resource_name + : []; // Monster abilities need nothing + + // 3. Construct the full list of attributes to fetch. + const attrsToFetch = [ + ...globalAttrsToGet, + ...allAbilityAttributeNames.map(x => `${prefix}_${x}`), ]; - const attrs = await getAttrsAsync([ - 'character_name', - 'wtype', - ...abilityAttributeNames.map(x => `repeating_npcabilities_${x}`), - ]); - const characterName = attrs.character_name; - const wtype = attrs.wtype; + const attrs = await getAttrsAsync(attrsToFetch); + + // 4. Execute the custom logic (player or monster specific) + const { directMap, rollValueMap } = getAbilityMaps(attrs, prefix); + + // 5. Call the shared roll function + const roll = buildAbilityRoll(directMap, rollValueMap); + + console.log(`${prefix}:`, roll); + } + + // The custom logic function that contains the differences + function getAbilityMaps(attrs, prefix) { + let directMap = {}; + let rollValueMap = {}; + let translateMap = {}; let subtype = ''; + let trait = ''; + let hasTrait = 0; - switch(attrs.repeating_npcabilities_ability_subtype) { - case 'signature-ability': - case 'villain-ability': - subtype = getTranslationByKey(attrs.repeating_npcabilities_ability_subtype) || ''; - break; - case 'malice-ability': - case 'malice-trait': - subtype = attrs.repeating_npcabilities_ability_malice_cost + ' ' + getTranslationByKey('malice'); - break; + if (prefix === "repeating_abilities") { + // PLAYER Ability Logic + const resourceName = attrs.resource_name || getTranslationByKey('resource-name-placeholder'); + const cost = attrs[`${prefix}_ability_cost`]; + subtype = cost && cost !== '0' ? `(${cost} ${resourceName})` : ''; + + trait = attrs[`${prefix}_ability_description`]; + hasTrait = 1; + hasEffect = attrs[`${prefix}_ability_effect`] ? 1 : 0; + } + else { + // NPC Ability Logic + switch(attrs[`${prefix}_ability_subtype`]) { + case 'signature-ability': + case 'villain-ability': + subtype = getTranslationByKey(attrs[`${prefix}_ability_subtype`]) || ''; + break; + case 'malice-ability': + case 'malice-trait': + subtype = attrs[`${prefix}_ability_malice_cost`] + ' ' + getTranslationByKey('malice'); + break; + } + trait = attrs[`${prefix}_ability_trait`]; + hasTrait = attrs[`${prefix}_ability_subtype`].includes('trait') && trait ? 1 : 0; + hasEffect = attrs[`${prefix}_has_effect`] === 'on' ? 1 : 0; } - console.log('Type: ' + attrs.repeating_npcabilities_ability_type); - const type = attrs.repeating_npcabilities_ability_type === 'no-action' ? '' : getTranslationByKey(attrs.repeating_npcabilities_ability_type); + + const type = attrs[`${prefix}_ability_type`] === 'no-action' ? '' : getTranslationByKey(attrs[`${prefix}_ability_type`]); - const directMap = { - name: attrs.repeating_npcabilities_ability_name, + // Build the directMap - these will be transformed into a {{key=value}} format. + directMap = { + name: attrs[`${prefix}_ability_name`], subtype: subtype, - trait: attrs.repeating_npcabilities_ability_trait || '', - type: type, - keywords: attrs.repeating_npcabilities_ability_keywords || '', - distance: attrs.repeating_npcabilities_ability_distance || '', - target: attrs.repeating_npcabilities_ability_target || '', - trigger: attrs.repeating_npcabilities_ability_trigger || '', - characteristic: attrs.repeating_npcabilities_ability_characteristic || '', - tier1: attrs.repeating_npcabilities_ability_tier_1 || '', - tier2: attrs.repeating_npcabilities_ability_tier_2 || '', - tier3: attrs.repeating_npcabilities_ability_tier_3 || '', - special: attrs.repeating_npcabilities_ability_special || '', - effect: attrs.repeating_npcabilities_ability_effect || '', - malprop: attrs.repeating_npcabilities_ability_malice || '', - malpropcost: attrs.repeating_npcabilities_ability_cost || '', - solo1name: attrs.repeating_npcabilities_ability_solo_1_name || '', - solo1text: attrs.repeating_npcabilities_ability_solo_1_text || '', - solo2name: attrs.repeating_npcabilities_ability_solo_2_name || '', - solo2text: attrs.repeating_npcabilities_ability_solo_2_text || '', + trait: attrs[`${prefix}_ability_trait`] || '', + type: type, + keywords: attrs[`${prefix}_ability_keywords`] || '', + distance: attrs[`${prefix}_ability_distance`] || '', + target: attrs[`${prefix}_ability_target`] || '', + trigger: attrs[`${prefix}_ability_trigger`] || '', + characteristic: attrs[`${prefix}_ability_characteristic`] || '', + tier1: attrs[`${prefix}_ability_tier_1`] || '', + tier2: attrs[`${prefix}_ability_tier_2`] || '', + tier3: attrs[`${prefix}_ability_tier_3`] || '', + special: attrs[`${prefix}_ability_special`] || '', + effect: attrs[`${prefix}_ability_effect`] || '', + malprop: attrs[`${prefix}_ability_malice`] || '', + malpropcost: attrs[`${prefix}_ability_cost`] || '', + solo1name: attrs[`${prefix}_ability_solo_1_name`] || '', + solo1text: attrs[`${prefix}_ability_solo_1_text`] || '', + solo2name: attrs[`${prefix}_ability_solo_2_name`] || '', + solo2text: attrs[`${prefix}_ability_solo_2_text`] || '', + } + + //Build the rollValueMap - these will be transformed into a {{key=[[value]]}} format. + rollValueMap = { + hasTrait: hasTrait, + hasSolo: attrs[`${prefix}_ability_subtype`] && attrs[`${prefix}_ability_subtype`].includes('solo') ? 1 : 0, + hasTrigger: attrs[`${prefix}_ability_type`].includes('triggered') && attrs[`${prefix}_ability_trigger`] ? 1 : 0, + hasPowerRoll: attrs[`${prefix}_has_power_roll`] === 'on' ? 1 : 0, + hasSpecial: attrs[`${prefix}_has_special`] === 'on' ? 1 : 0, + hasEffect: hasEffect, + hasMalprop: attrs[`${prefix}_has_malice`] === 'on' ? 1 : 0, + }; + + return { directMap, rollValueMap }; + } + +/** +** Event Listeners +**/ + +// Characteristic Power Rolls + $20('.npc-characteristic-input-group > label').on('click', (e) => { + const characteristic = e.htmlAttributes['data-characteristic']; + rollPower(characteristic); + }); + + $20('.characteristic-input-group > label').on('click', (e) => { + const characteristic = e.htmlAttributes['data-characteristic']; + rollPower(characteristic); + }); + + +// Share Player Repeated Ability + on('clicked:repeating_abilities:share', async (event) => { + handleAbilityShare('repeating_abilities'); + }); + +// Share Monster Repeated Abilities + on('clicked:repeating_npcabilities:share', async (event) => { + handleAbilityShare("repeating_npcabilities"); + }); + +//Melee Free Strike Display + on('clicked:melee_share', async (event) => { + const attributeNames = [ + 'melee_free_strike_name', + 'melee_free_strike_keywords', + 'melee_free_strike_distance', + 'melee_free_strike_target', + 'melee_free_strike_characteristic', + 'melee_free_strike_tier_1', + 'melee_free_strike_tier_2', + 'melee_free_strike_tier_3' + ]; + + const attrs = await getAttrsAsync(attributeNames); + + const directMap = { + name: attrs.melee_free_strike_name, + keywords: attrs.melee_free_strike_keywords, + distance: attrs.melee_free_strike_distance, + target: attrs.melee_free_strike_target, + characteristic: attrs.melee_free_strike_characteristic, + tier1: attrs.melee_free_strike_tier_1, + tier2: attrs.melee_free_strike_tier_2, + tier3: attrs.melee_free_strike_tier_3 + }; + + const rollValueMap = { + hasPowerRoll: 1, + hasDistance: 1, + hasTarget: 1, }; + const roll = buildAbilityRoll(directMap, rollValueMap); + console.log('Melee Free Strike roll:', roll); + }); + +// Ranged Free Strike Display + on('clicked:ranged_share', async (event) => { + const attributeNames = [ + 'ranged_free_strike_name', + 'ranged_free_strike_keywords', + 'ranged_free_strike_distance', + 'ranged_free_strike_target', + 'ranged_free_strike_characteristic', + 'ranged_free_strike_tier_1', + 'ranged_free_strike_tier_2', + 'ranged_free_strike_tier_3' + ]; + + const attrs = await getAttrsAsync(attributeNames); + + const directMap = { + name: attrs.ranged_free_strike_name, + keywords: attrs.ranged_free_strike_keywords, + distance: attrs.ranged_free_strike_distance, + target: attrs.ranged_free_strike_target, + characteristic: attrs.ranged_free_strike_characteristic, + tier1: attrs.ranged_free_strike_tier_1, + tier2: attrs.ranged_free_strike_tier_2, + tier3: attrs.ranged_free_strike_tier_3 + }; + const rollValueMap = { - hasTrait: attrs.repeating_npcabilities_ability_subtype.includes('trait') - && attrs.repeating_npcabilities_ability_trait - ? 1 : 0, - hasSolo: attrs.repeating_npcabilities_ability_subtype.includes('solo') - ? 1 : 0, - hasTrigger: attrs.repeating_npcabilities_ability_type.includes('triggered') - && attrs.repeating_npcabilities_ability_trigger - ? 1 : 0, - hasPowerRoll: attrs.repeating_npcabilities_has_power_roll === 'on' - ? 1 : 0, - hasSpecial: attrs.repeating_npcabilities_has_special === 'on' - ? 1 : 0, - hasEffect: attrs.repeating_npcabilities_has_effect === 'on' - ? 1 : 0, - hasMalprop: attrs.repeating_npcabilities_has_malice === 'on' - ? 1 : 0, + hasPowerRoll: 1, + hasDistance: 1, + hasTarget: 1, }; - const roll = wtype + ` &{template:monsterability} ` - + '{{charactername=' + characterName + '}} ' - + '{{powerRoll=^{power-roll}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - console.log('ability values', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + + const roll = buildAbilityRoll(directMap, rollValueMap); + console.log('Ranged Free Strike roll:', roll); }); +// Share Class Features + on('clicked:repeating_classfeatures:classfeatureshare', async (event) => { + const attrs = await getAttrsAsync([ + 'repeating_classfeatures_classfeature_name', + 'repeating_classfeatures_classfeature_description', + ]); + const subtitle = getTranslationByKey('class-features'); + featureDisplay(attrs.repeating_classfeatures_classfeature_name, subtitle, attrs.repeating_classfeatures_classfeature_description); + }); + +// Share Ancestry Features + on('clicked:repeating_ancestrytraits:ancfeatureshare', async (event) => { + const attrs = await getAttrsAsync([ + 'repeating_ancestrytraits_ancestrytrait_name', + 'repeating_ancestrytraits_ancestrytrait_description', + ]); + const subtitle = getTranslationByKey('ancestry-traits'); + featureDisplay(attrs.repeating_ancestrytraits_ancestrytrait_name, subtitle, attrs.repeating_ancestrytraits_ancestrytrait_description); + }); + +// Share Perk Features + on('clicked:repeating_perks:perkfeatureshare', async (event) => { + const attrs = await getAttrsAsync([ + 'repeating_perks_perk_name', + 'repeating_perks_perk_description', + ]); + const subtitle = getTranslationByKey('perks'); + featureDisplay(attrs.repeating_perks_perk_name, subtitle,attrs.repeating_perks_perk_description); - /** - ** import start - **/ + }); + +// Share Title Features + on('clicked:repeating_titles:titlefeatureshare', async (event) => { + const attrs = await getAttrsAsync([ + 'repeating_titles_title_name', + 'repeating_titles_title_description', + ]); + const subtitle = getTranslationByKey('titles'); + featureDisplay(attrs.repeating_titles_title_name, subtitle, attrs.repeating_titles_title_description); + }); + +// Looking for Power Roll for Ability Card + on("change:repeating_abilities:has_power_roll", function(event) { + const repeatingId = event.sourceAttribute.match(/repeating_abilities_[^_]+/)[0]; + const sourceAttr = `${repeatingId}_has_power_roll`; + const targetAttr = `${repeatingId}_show_power_roll`; + getAttrs([sourceAttr], function(values) { + const show = values[sourceAttr] === "on" ? "1" : "0"; + setAttrs({ + [targetAttr]: show + }); + }); + }); + + +/** +** Import from Forge Steel Start +**/ function flattenFeatures(features, level) { const deepFeatureTypes = [ 'Choice', From 8cc2cdd0bd0a5c594bfc9da3c56e6c85500d5e0a Mon Sep 17 00:00:00 2001 From: Zen-Raven Date: Mon, 29 Sep 2025 10:36:43 -0700 Subject: [PATCH 2/3] Code Cleanup for Power Roll Sheetworker - Cleaned up power roll sheet worker code. - Changed player ability cards use a dropdown for characteristics instead of text. Added dark mode coloring to new element. - removed unneeded placeholder properties from spans. - Altered the Power Roll template to include character name. --- Draw Steel/draw-steel.css | 4 + Draw Steel/draw-steel.html | 369 ++++++++++--------------------------- 2 files changed, 102 insertions(+), 271 deletions(-) diff --git a/Draw Steel/draw-steel.css b/Draw Steel/draw-steel.css index db15ebdb5753..fa88d58f2115 100644 --- a/Draw Steel/draw-steel.css +++ b/Draw Steel/draw-steel.css @@ -1053,6 +1053,10 @@ input.ability-edit { font-weight: bold; } +.sheet-darkmode select.power-roll-characteristic { + background-color: #3b4045; +} + .power-roll-characteristic::placeholder { opacity: 0.7; } diff --git a/Draw Steel/draw-steel.html b/Draw Steel/draw-steel.html index af5dba3669ed..1e893f36a99f 100644 --- a/Draw Steel/draw-steel.html +++ b/Draw Steel/draw-steel.html @@ -443,18 +443,19 @@
- +
+ +
+ - +
@@ -469,17 +470,17 @@
💬 - - + + - - + +
+ - +
- + - + - +
@@ -502,18 +503,19 @@
- +
+ +
+ - +
@@ -528,29 +530,29 @@
💬 - - + + - - + +
+ - -
- + - + - +
@@ -584,7 +586,13 @@
+ - +
@@ -601,24 +609,24 @@
💬
- - + +
- + - - + + - - + + - +
+ - +
- + - + - +
- +
@@ -1003,6 +1011,9 @@
+
+ {{charactername}} +
{{name}}
@@ -1268,7 +1279,7 @@
** Power Roll **/ - async function rollPower(characteristic) { + async function rollPower(characteristic, abilityName) { const attrs = await getAttrsAsync([characteristic]); const characteristicValue = attrs[characteristic]; const characteristicTranslation = getTranslationByKey(characteristic) || characteristic; @@ -1280,6 +1291,7 @@
const baneTranslation = getTranslationByKey('bane') || 'bane'; const doubleBaneTranslation = getTranslationByKey('double-bane') || 'double-bane'; const bonusOrPenaltyTranslation = getTranslationByKey('bonus-or-penalty') || 'bonus-or-penalty'; + const name = abilityName ? abilityName : characteristicTranslation + ` ` + powerRollTranslation; const roll = '&{template:powerroll} ' + '[[ [[2d10cs>11cf<0]][2d10] ' + ` + [[${characteristicValue}[${characteristicTranslation}]]][${characteristicTranslation}] ` + @@ -1298,11 +1310,12 @@
'{{edgeBane=$[[2]]}} ' + '{{bonus=$[[3]]}} ' + '{{total=$[[4]]}} ' + - `{{name=` + characteristicTranslation + ` ` + powerRollTranslation + `}} ` + + `{{name=${name}}} ` + `{{characteristic=${characteristic}}} ` + `{{isDoubleEdge=[[0]]}} ` + `{{isDoubleBane=[[0]]}} ` + - '{{tier=[[0]]}} '; + '{{tier=[[0]]}} ' + + '{{charactername=@{character_name}}} '; console.log('roll', roll); startRoll(roll, ({ rollId, results }) => { console.log('roll results', results); @@ -1352,6 +1365,7 @@
** Build Ability Roll constructs and executes rolls using the ability sharing roll template **/ + function buildAbilityRoll(directMap, rollValueMap) { const isDefined = (value) => { @@ -1377,223 +1391,6 @@
return roll; } - -/** -**Repeated Ability power roll -**/ - on('clicked:repeating_abilities:power-roll-share', async (event) => { - const abilityAttributeNames = [ - 'ability_name', 'ability_cost', 'ability_description', 'ability_keywords', - 'ability_type', 'ability_distance', 'ability_target', 'ability_trigger', - 'has_power_roll', 'ability_characteristic', - 'ability_tier_1', 'ability_tier_2', 'ability_tier_3', 'ability_effect', - ]; - const attrs = await getAttrsAsync([ - 'resource_name', - ...abilityAttributeNames.map(x => `repeating_abilities_${x}`), - ]); - const resourceName = attrs.resource_name || getTranslationByKey('resource-name-placeholder'); - - const characteristicValue = attrs['repeating_abilities_ability_characteristic']; - const characteristicTranslation = getTranslationByKey(characteristicValue) || characteristicValue; - const edgeOrBaneTranslation = getTranslationByKey('edge-or-bane') || 'edge-or-bane'; - const noEdgeOrBaneTranslation = getTranslationByKey('no-edge-or-bane') || 'no-edge-or-bane'; - const doubleEdgeTranslation = getTranslationByKey('double-edge') || 'double-edge'; - const edgeTranslation = getTranslationByKey('edge') || 'edge'; - const baneTranslation = getTranslationByKey('bane') || 'bane'; - const doubleBaneTranslation = getTranslationByKey('double-bane') || 'double-bane'; - const bonusOrPenaltyTranslation = getTranslationByKey('bonus-or-penalty') || 'bonus-or-penalty'; - - const directMap = { - name: attrs.repeating_abilities_ability_cost && attrs.repeating_abilities_ability_cost !== '0' - ? `${attrs.repeating_abilities_ability_name} (${attrs.repeating_abilities_ability_cost} ${resourceName})` - : attrs.repeating_abilities_ability_name, - cost: attrs.repeating_abilities_ability_cost, - description: attrs.repeating_abilities_ability_description, - keywords: attrs.repeating_abilities_ability_keywords, - distance: attrs.repeating_abilities_ability_distance, - target: attrs.repeating_abilities_ability_target, - trigger: attrs.repeating_abilities_ability_trigger, - characteristic: attrs.repeating_abilities_ability_characteristic, - tier1: attrs.repeating_abilities_ability_tier_1, - tier2: attrs.repeating_abilities_ability_tier_2, - tier3: attrs.repeating_abilities_ability_tier_3, - effect: attrs.repeating_abilities_ability_effect, - }; - const translateMap = { - type: attrs.repeating_abilities_ability_type || 'no-action', - }; - const rollValueMap = { - hasTrigger: attrs.repeating_abilities_ability_type.includes('triggered') - && attrs.repeating_abilities_ability_trigger - ? 1 : 0, - hasPowerRoll: attrs.repeating_abilities_has_power_roll === 'on' - ? 1 : 0, - hasEffect: attrs.repeating_abilities_ability_effect - ? 1 : 0, - hasDistance: attrs.repeating_abilities_ability_distance - ? 1 : 0, - hasTarget: attrs.repeating_abilities_ability_target - ? 1 : 0, - }; - const roll = '&{template:ability} ' + - '[[ [[2d10cs>11cf<0]][2d10] ' + - ` + [[${characteristicValue}]] ` + - ' + [[?{' + - edgeOrBaneTranslation + - `|${noEdgeOrBaneTranslation},0` + - `|${doubleEdgeTranslation},0[${doubleEdgeTranslation}]` + - `|${edgeTranslation},2[${edgeTranslation}]` + - `|${baneTranslation},-2[${baneTranslation}]` + - `|${doubleBaneTranslation},0[${doubleBaneTranslation}]` + - `}]][${edgeOrBaneTranslation}] ` + - ` + [[?{${bonusOrPenaltyTranslation}|0}]][${bonusOrPenaltyTranslation}] ` + - ']] ' - + '{{powerRoll=^{power-roll}: $[[4]]}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Repeating Ability power roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); - }); - - - - /** - **Melee Free Strike Power Roll - **/ - on('clicked:melee_power_roll_share', async (event) => { - const attributeNames = [ - 'melee_free_strike_name', - 'melee_free_strike_keywords', - 'melee_free_strike_distance', - 'melee_free_strike_target', - 'melee_free_strike_characteristic', - 'melee_free_strike_tier_1', - 'melee_free_strike_tier_2', - 'melee_free_strike_tier_3' - ]; - - const attrs = await getAttrsAsync(attributeNames); - const characteristicValue = attrs['melee_free_strike_characteristic']; - const characteristicTranslation = getTranslationByKey(characteristicValue) || characteristicValue; - const edgeOrBaneTranslation = getTranslationByKey('edge-or-bane') || 'edge-or-bane'; - const noEdgeOrBaneTranslation = getTranslationByKey('no-edge-or-bane') || 'no-edge-or-bane'; - const doubleEdgeTranslation = getTranslationByKey('double-edge') || 'double-edge'; - const edgeTranslation = getTranslationByKey('edge') || 'edge'; - const baneTranslation = getTranslationByKey('bane') || 'bane'; - const doubleBaneTranslation = getTranslationByKey('double-bane') || 'double-bane'; - const bonusOrPenaltyTranslation = getTranslationByKey('bonus-or-penalty') || 'bonus-or-penalty'; - - const directMap = { - name: attrs.melee_free_strike_name, - keywords: attrs.melee_free_strike_keywords, - distance: attrs.melee_free_strike_distance, - target: attrs.melee_free_strike_target, - characteristic: attrs.melee_free_strike_characteristic, - tier1: attrs.melee_free_strike_tier_1, - tier2: attrs.melee_free_strike_tier_2, - tier3: attrs.melee_free_strike_tier_3 - }; - -const rollValueMap = { - hasPowerRoll: '1', - hasDistance: '1', - hasTarget: '1', -}; - const roll = '&{template:ability} ' + - '[[ [[2d10cs>11cf<0]][2d10] ' + - ` + [[${characteristicValue}]] ` + - ' + [[?{' + - edgeOrBaneTranslation + - `|${noEdgeOrBaneTranslation},0` + - `|${doubleEdgeTranslation},0[${doubleEdgeTranslation}]` + - `|${edgeTranslation},2[${edgeTranslation}]` + - `|${baneTranslation},-2[${baneTranslation}]` + - `|${doubleBaneTranslation},0[${doubleBaneTranslation}]` + - `}]][${edgeOrBaneTranslation}] ` + - ` + [[?{${bonusOrPenaltyTranslation}|0}]][${bonusOrPenaltyTranslation}] ` + - ']] ' - + '{{powerRoll=^{power-roll}: $[[4]]}} ' - + '{{type=^{main-action}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Melee Free Strike power roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); - }); - - /** - **Ranged Free Strike Power Roll - **/ - on('clicked:ranged_power_roll_share', async (event) => { - const attributeNames = [ - 'ranged_free_strike_name', - 'ranged_free_strike_keywords', - 'ranged_free_strike_distance', - 'ranged_free_strike_target', - 'ranged_free_strike_characteristic', - 'ranged_free_strike_tier_1', - 'ranged_free_strike_tier_2', - 'ranged_free_strike_tier_3' - ]; - - const attrs = await getAttrsAsync(attributeNames); - const characteristicValue = attrs['ranged_free_strike_characteristic']; - const characteristicTranslation = getTranslationByKey(characteristicValue) || characteristicValue; - const edgeOrBaneTranslation = getTranslationByKey('edge-or-bane') || 'edge-or-bane'; - const noEdgeOrBaneTranslation = getTranslationByKey('no-edge-or-bane') || 'no-edge-or-bane'; - const doubleEdgeTranslation = getTranslationByKey('double-edge') || 'double-edge'; - const edgeTranslation = getTranslationByKey('edge') || 'edge'; - const baneTranslation = getTranslationByKey('bane') || 'bane'; - const doubleBaneTranslation = getTranslationByKey('double-bane') || 'double-bane'; - const bonusOrPenaltyTranslation = getTranslationByKey('bonus-or-penalty') || 'bonus-or-penalty'; - - const directMap = { - name: attrs.ranged_free_strike_name, - keywords: attrs.ranged_free_strike_keywords, - distance: attrs.ranged_free_strike_distance, - target: attrs.ranged_free_strike_target, - characteristic: attrs.ranged_free_strike_characteristic, - tier1: attrs.ranged_free_strike_tier_1, - tier2: attrs.ranged_free_strike_tier_2, - tier3: attrs.ranged_free_strike_tier_3 - }; - -const rollValueMap = { - hasPowerRoll: '1', - hasDistance: '1', - hasTarget: '1', -}; - const roll = '&{template:ability} ' + - '[[ [[2d10cs>11cf<0]][2d10] ' + - ` + [[${characteristicValue}]] ` + - ' + [[?{' + - edgeOrBaneTranslation + - `|${noEdgeOrBaneTranslation},0` + - `|${doubleEdgeTranslation},0[${doubleEdgeTranslation}]` + - `|${edgeTranslation},2[${edgeTranslation}]` + - `|${baneTranslation},-2[${baneTranslation}]` + - `|${doubleBaneTranslation},0[${doubleBaneTranslation}]` + - `}]][${edgeOrBaneTranslation}] ` + - ` + [[?{${bonusOrPenaltyTranslation}|0}]][${bonusOrPenaltyTranslation}] ` + - ']] ' - + '{{powerRoll=^{power-roll}: $[[4]]}} ' - + '{{type=^{main-action}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Ranged Free Strike power roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); - }); - - /** ** Ability Sharing Handler **/ @@ -1631,7 +1428,7 @@
console.log(`${prefix}:`, roll); } - // The custom logic function that contains the differences + // Function builds the maps specific to player and NPC abilities. function getAbilityMaps(attrs, prefix) { let directMap = {}; let rollValueMap = {}; @@ -1639,13 +1436,15 @@
let subtype = ''; let trait = ''; let hasTrait = 0; + let characteristic = ''; - if (prefix === "repeating_abilities") { + if (prefix === 'repeating_abilities') { // PLAYER Ability Logic const resourceName = attrs.resource_name || getTranslationByKey('resource-name-placeholder'); const cost = attrs[`${prefix}_ability_cost`]; subtype = cost && cost !== '0' ? `(${cost} ${resourceName})` : ''; + characteristic = getTranslationByKey(attrs[`${prefix}_ability_characteristic`]); trait = attrs[`${prefix}_ability_description`]; hasTrait = 1; hasEffect = attrs[`${prefix}_ability_effect`] ? 1 : 0; @@ -1662,6 +1461,7 @@
subtype = attrs[`${prefix}_ability_malice_cost`] + ' ' + getTranslationByKey('malice'); break; } + characteristic = attrs[`${prefix}_ability_characteristic`] || ''; trait = attrs[`${prefix}_ability_trait`]; hasTrait = attrs[`${prefix}_ability_subtype`].includes('trait') && trait ? 1 : 0; hasEffect = attrs[`${prefix}_has_effect`] === 'on' ? 1 : 0; @@ -1673,13 +1473,13 @@
directMap = { name: attrs[`${prefix}_ability_name`], subtype: subtype, - trait: attrs[`${prefix}_ability_trait`] || '', + trait: trait || '', type: type, keywords: attrs[`${prefix}_ability_keywords`] || '', distance: attrs[`${prefix}_ability_distance`] || '', target: attrs[`${prefix}_ability_target`] || '', trigger: attrs[`${prefix}_ability_trigger`] || '', - characteristic: attrs[`${prefix}_ability_characteristic`] || '', + characteristic: characteristic, tier1: attrs[`${prefix}_ability_tier_1`] || '', tier2: attrs[`${prefix}_ability_tier_2`] || '', tier3: attrs[`${prefix}_ability_tier_3`] || '', @@ -1727,7 +1527,17 @@
on('clicked:repeating_abilities:share', async (event) => { handleAbilityShare('repeating_abilities'); }); - + +// Repeated Ability power roll + on('clicked:repeating_abilities:power-roll-share', async (event) => { + const attrs = await getAttrsAsync([ + 'repeating_abilities_ability_characteristic', + 'repeating_abilities_ability_name', + ]); + console.log(attrs); + rollPower(attrs.repeating_abilities_ability_characteristic,attrs.repeating_abilities_ability_name); + }); + // Share Monster Repeated Abilities on('clicked:repeating_npcabilities:share', async (event) => { handleAbilityShare("repeating_npcabilities"); @@ -1753,7 +1563,7 @@
keywords: attrs.melee_free_strike_keywords, distance: attrs.melee_free_strike_distance, target: attrs.melee_free_strike_target, - characteristic: attrs.melee_free_strike_characteristic, + characteristic: getTranslationByKey(attrs.melee_free_strike_characteristic), tier1: attrs.melee_free_strike_tier_1, tier2: attrs.melee_free_strike_tier_2, tier3: attrs.melee_free_strike_tier_3 @@ -1768,6 +1578,15 @@
const roll = buildAbilityRoll(directMap, rollValueMap); console.log('Melee Free Strike roll:', roll); }); + +// Melee Free Strike Power Roll + + on('clicked:melee_power_roll_share', async (event) => { + const attrs = await getAttrsAsync(['melee_free_strike_characteristic']); + const mfsTranslation = getTranslationByKey('melee-free-strike'); + console.log(attrs); + rollPower(attrs.melee_free_strike_characteristic, mfsTranslation); + }); // Ranged Free Strike Display on('clicked:ranged_share', async (event) => { @@ -1789,7 +1608,7 @@
keywords: attrs.ranged_free_strike_keywords, distance: attrs.ranged_free_strike_distance, target: attrs.ranged_free_strike_target, - characteristic: attrs.ranged_free_strike_characteristic, + characteristic: getTranslationByKey(attrs.ranged_free_strike_characteristic), tier1: attrs.ranged_free_strike_tier_1, tier2: attrs.ranged_free_strike_tier_2, tier3: attrs.ranged_free_strike_tier_3 @@ -1804,7 +1623,15 @@
const roll = buildAbilityRoll(directMap, rollValueMap); console.log('Ranged Free Strike roll:', roll); }); - + +// Ranged Free Strike Power Roll + on('clicked:ranged_power_roll_share', async (event) => { + const attrs = await getAttrsAsync(['ranged_free_strike_characteristic']); + const rfsTranslation = getTranslationByKey('ranged-free-strike'); + console.log(attrs); + rollPower(attrs.ranged_free_strike_characteristic, rfsTranslation); + }); + // Share Class Features on('clicked:repeating_classfeatures:classfeatureshare', async (event) => { const attrs = await getAttrsAsync([ From 32dcd96a7eed01b71cb9139ef34d9c2b80591543 Mon Sep 17 00:00:00 2001 From: Zen-Raven Date: Wed, 1 Oct 2025 16:40:27 -0700 Subject: [PATCH 3/3] more code cleanup - Added comments to some sections for clarity - Removed edit ability from some of the standard abilities as they will not need to be edited. - Cleaned up sheet worker code for new standard abilities. --- Draw Steel/draw-steel.css | 4 +- Draw Steel/draw-steel.html | 2997 +++++++++++------------------------- 2 files changed, 940 insertions(+), 2061 deletions(-) diff --git a/Draw Steel/draw-steel.css b/Draw Steel/draw-steel.css index 43a6300dbc18..7dc68cbcdd6c 100644 --- a/Draw Steel/draw-steel.css +++ b/Draw Steel/draw-steel.css @@ -1531,7 +1531,7 @@ sheet-darkmode .npc-header-panel { } #npc-ability-edit-toggle { - right: 5px; + right: 5px; position: absolute; appearance: none; background-color: transparent; @@ -1948,4 +1948,4 @@ input.npc-edit-toggle:not(:checked) ~ div.npc-edit { background-color: #3b4045 !important; color: #e0e0e0 !important; border-color: #e0e0e0 !important; -} +} \ No newline at end of file diff --git a/Draw Steel/draw-steel.html b/Draw Steel/draw-steel.html index ff39868a763c..d07ecd1de1f5 100644 --- a/Draw Steel/draw-steel.html +++ b/Draw Steel/draw-steel.html @@ -1,4 +1,5 @@
+

style="height: 60px" />

+
+
@@ -229,6 +232,7 @@
+
@@ -267,6 +271,7 @@
+
@@ -294,6 +299,7 @@
+
@@ -427,6 +433,7 @@
+
@@ -444,6 +451,7 @@
+

@@ -532,205 +540,208 @@

-
- - Edit -
- - - -
- -
- - -
-
- - + - + +
+ + Edit +
+ + + +
+ +
+ + +
+
+ + + + +
+ + + + + +
- - - - - -
-
-
- - - - - - - -
-
- - + - - +
+ + + + + + + +
+
+ + + + + +
+ + + + + +
- - - - - -
-
-
- - Edit -
- - - -
- -
- - -
-
- - + - +
+ + Edit +
+ + + +
+ +
+ + +
+
+ + + + +
+ + + + + +
- - - - - -
-
-
- - - - - - - -
-
- - + - - +
+ + + + + + + +
+
+ + + + + +
+ + + + + +
- - - - - -
-
-
- - Edit -
- - - - - -
-
- - - - - -
-
-
- - Edit -
- - - - - -
-
- - - - - + +
+ + Edit +
+ + + + + +
+
+ + + + + +
-
-
- - Edit -
- - - - - - - +
+ + Edit +
+ + + + + +
+
+ + + + + +
-
- - - - - - - - +
+ + Edit +
+ + + + + + + +
+
+ + + + + + + + +
-
+

@@ -813,454 +824,693 @@

-
+ +
+
+ + + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + + + + +
+ +
+
+
+ +
+ + + + + + + + + + + + + + + + + + +
+
+ + + + + +
+ + + + + + +
+ +
+
+
+ + Edit +
+ + + + + + +
+
+ + + + +
+ + + + + + +
+ +
+
+ + + + + + + +
+
+ + + + + +
+ + + + + + +
+ +
+
+
+ + Edit +
+ + + + + + +
+
+ + + + +
+ + + + + + +
+ +
+
+ + + + + + + +
+
+ + + + + +
+ + + + + + +
+ +
+
+
+ + Edit +
+ + + + + + + +
+
+ + + + + + + + +
+
+
+ + Edit +
+ + + + + + + +
+
+ + + + + + + + +
+
+
+ + Edit +
+ + + + + + + +
+
+ + + + + + + + +
+
+ +
+ + Edit +
+ + + + + + + +
+
+ + + + + + + + +
+
+
+ + Edit +
+ + + + + + + +
+
+ + + + + + + + +
+
+
+
+
+ +

+
Edit
- - - - +
+ + +
+ + + - - + + +
+ + - +
- - + + - + - +
- +
- - - - +
+ + +
+ + + + - - + + + + +
+ - -
- + - + - +
- +
-
-
+ +
+
+ +

+
Edit
- - - - +
+ + +
+ + + - - + + +
+ + - +
- - + + - + - +
- +
- - - - +
+ + +
+ + + + - - + + + + +
+ - -
- + - + - +
- +
-
-
+ +
+
Edit
- - - - - - +
+ - +
- + - + - +
- +
- - - - - - - +
+ - -
- + - + - +
- +
-
+
+ Edit
- - - - - - + +
+
+ - +
- + + - + + - + +
- +
- - - - - - - +
+ - -
- + - + - +
- -
-
-
- - Edit -
- - - - - - - -
-
- - - - - - - - -
-
-
- - Edit -
- - - - - - - -
-
- - - - - - - - -
-
-
- - Edit -
- - - - - - - -
-
- - - - - - - - -
-
- -
- - Edit -
- - - - - - - -
-
- - - - - - - - -
-
-
- - Edit -
- - - - - - - -
-
- - - - - - - - +
-
-

-
+
+ +

+
Edit
- +
- +
- - - - - - + + + + + + +
+ - +
- + - + - +
- +
- - + +
- + - - + + - - - - + + + +
+ - +
- + - + - +
- +
-
-
-

-
- - Edit -
- -
- - -
- - - - - - -
-
- - - + - -
- - - - - - +
+
+ +
+ + + + + + + + + + + + + +
-
-
- -
- - +
+ +
+ + + + + + + + + + + + + +
- - - - - - - - - - -
-
- - + - - -
- - - - - - +
+
+ +
+ + + + + + + + + + + + + +
-
-
-
-
- - Edit -
- -
-
- - + - -
- - - - - - -
- -
-
- - -
-
- - + - - -
- - - - - - -
- -
-
-
- - Edit -
- -
-
- - + - -
- - - - - - -
- -
-
- - -
-
- - + - - -
- - - - - - -
- -
-
-
-
-
-

-
- - Edit -
- -
- - -
- - - - - - -
-
- - - + - -
- - - - - - -
- -
-
- -
- - -
- - - - - - - - - - -
-
- - + - - -
- - - - - - -
- -
-
-
-
- - Edit -
- - - - - - - -
-
- - - - - - - - -
-
-
- - Edit -
- - - - - - - -
-
- - - - - - - - -
-
-
- - Edit -
- - - - - - - -
-
- - - - - - - - -
-
@@ -2414,41 +2384,48 @@
** Ability Sharing Handler **/ - async function handleAbilityShare(prefix) { + async function handleAbilityShare(prefix, abilityPrefix) { // 1. Define all possible ability attributes across both player and NPC sections. const allAbilityAttributeNames = [ - 'ability_name', 'ability_cost', 'ability_description', 'ability_keywords', - 'ability_type', 'ability_distance', 'ability_target', 'ability_trigger', - 'has_power_roll', 'ability_characteristic', - 'ability_tier_1', 'ability_tier_2', 'ability_tier_3', 'ability_effect', - 'ability_subtype', 'ability_malice_cost', 'ability_trait', - 'ability_solo_1_name', 'ability_solo_1_text', 'ability_solo_2_name', 'ability_solo_2_text', - 'has_effect', 'ability_special', 'has_special', 'has_malice', 'ability_malice', + 'name', 'cost', 'description', 'keywords', + 'type', 'distance', 'target', 'trigger', + 'characteristic', 'tier_1', 'tier_2', 'tier_3', 'effect', + 'subtype', 'malice_cost', 'trait', + 'solo_1_name', 'solo_1_text', 'solo_2_name', 'solo_2_text', + 'special', 'malice', + ]; + + const allAbilityToggles = [ + 'has_power_roll', 'has_effect', 'has_special', 'has_malice', ]; + + abPrefix = abilityPrefix ? `${abilityPrefix}_` : ''; + // 2. Define the character-level attributes needed for both. - const globalAttrsToGet = prefix === 'repeating_abilities' - ? ['resource_name'] // Player abilities need resource_name - : []; // Monster abilities need nothing + const globalAttrsToGet = prefix === 'repeating_npcabilities' + ? [] // Monster abilities need nothing + : ['resource_name']; // Player abilities need resource_name // 3. Construct the full list of attributes to fetch. const attrsToFetch = [ ...globalAttrsToGet, - ...allAbilityAttributeNames.map(x => `${prefix}_${x}`), + ...allAbilityAttributeNames.map(x => `${prefix}_${abPrefix}${x}`), + ...allAbilityToggles.map(x => `${prefix}_${x}`), ]; const attrs = await getAttrsAsync(attrsToFetch); - + // 4. Execute the custom logic (player or monster specific) - const { directMap, rollValueMap } = getAbilityMaps(attrs, prefix); + const { directMap, rollValueMap } = getAbilityMaps(attrs, prefix, abPrefix); // 5. Call the shared roll function const roll = buildAbilityRoll(directMap, rollValueMap); - console.log(`${prefix}:`, roll); + console.log(`${prefix}_${abilityPrefix}:`, roll); } // Function builds the maps specific to player and NPC abilities. - function getAbilityMaps(attrs, prefix) { + function getAbilityMaps(attrs, prefix, abilityPrefix) { let directMap = {}; let rollValueMap = {}; let translateMap = {}; @@ -2457,66 +2434,65 @@
let hasTrait = 0; let characteristic = ''; - if (prefix === 'repeating_abilities') { - // PLAYER Ability Logic - const resourceName = attrs.resource_name || getTranslationByKey('resource-name-placeholder'); - const cost = attrs[`${prefix}_ability_cost`]; - subtype = cost && cost !== '0' ? `(${cost} ${resourceName})` : ''; - - characteristic = getTranslationByKey(attrs[`${prefix}_ability_characteristic`]); - trait = attrs[`${prefix}_ability_description`]; - hasTrait = 1; - hasEffect = attrs[`${prefix}_ability_effect`] ? 1 : 0; - } - else { + if (prefix === 'repeating_npcabilities') { // NPC Ability Logic - switch(attrs[`${prefix}_ability_subtype`]) { + switch(attrs[`${prefix}_${abilityPrefix}subtype`]) { case 'signature-ability': case 'villain-ability': - subtype = getTranslationByKey(attrs[`${prefix}_ability_subtype`]) || ''; + subtype = getTranslationByKey(attrs[`${prefix}_${abilityPrefix}subtype`]) || ''; break; case 'malice-ability': case 'malice-trait': - subtype = attrs[`${prefix}_ability_malice_cost`] + ' ' + getTranslationByKey('malice'); + subtype = attrs[`${prefix}_${abilityPrefix}malice_cost`] + ' ' + getTranslationByKey('malice'); break; } - characteristic = attrs[`${prefix}_ability_characteristic`] || ''; - trait = attrs[`${prefix}_ability_trait`]; - hasTrait = attrs[`${prefix}_ability_subtype`].includes('trait') && trait ? 1 : 0; + characteristic = attrs[`${prefix}_${abilityPrefix}characteristic`] || ''; + trait = attrs[`${prefix}_${abilityPrefix}trait`]; + hasTrait = attrs[`${prefix}_${abilityPrefix}subtype`].includes('trait') && trait ? 1 : 0; hasEffect = attrs[`${prefix}_has_effect`] === 'on' ? 1 : 0; + } else { + // PLAYER Ability Logic + const resourceName = attrs.resource_name || getTranslationByKey('resource-name-placeholder'); + const cost = attrs[`${prefix}_${abilityPrefix}_cost`]; + subtype = cost && cost !== '0' ? `(${cost} ${resourceName})` : ''; + characteristic = attrs[`${prefix}_${abilityPrefix}characteristic`] ? getTranslationByKey(attrs[`${prefix}_${abilityPrefix}characteristic`]) || '' : ''; + trait = attrs[`${prefix}_${abilityPrefix}description`]; + hasTrait = 1; + hasEffect = attrs[`${prefix}_${abilityPrefix}effect`] ? 1 : 0; } + - const type = attrs[`${prefix}_ability_type`] === 'no-action' ? '' : getTranslationByKey(attrs[`${prefix}_ability_type`]); + const type = attrs[`${prefix}_${abilityPrefix}type`] === 'no-action' ? '' : getTranslationByKey(attrs[`${prefix}_${abilityPrefix}type`]); // Build the directMap - these will be transformed into a {{key=value}} format. directMap = { - name: attrs[`${prefix}_ability_name`], + name: attrs[`${prefix}_${abilityPrefix}name`], subtype: subtype, trait: trait || '', type: type, - keywords: attrs[`${prefix}_ability_keywords`] || '', - distance: attrs[`${prefix}_ability_distance`] || '', - target: attrs[`${prefix}_ability_target`] || '', - trigger: attrs[`${prefix}_ability_trigger`] || '', + keywords: attrs[`${prefix}_${abilityPrefix}keywords`] || '', + distance: attrs[`${prefix}_${abilityPrefix}distance`] || '', + target: attrs[`${prefix}_${abilityPrefix}target`] || '', + trigger: attrs[`${prefix}_${abilityPrefix}trigger`] || '', characteristic: characteristic, - tier1: attrs[`${prefix}_ability_tier_1`] || '', - tier2: attrs[`${prefix}_ability_tier_2`] || '', - tier3: attrs[`${prefix}_ability_tier_3`] || '', - special: attrs[`${prefix}_ability_special`] || '', - effect: attrs[`${prefix}_ability_effect`] || '', - malprop: attrs[`${prefix}_ability_malice`] || '', - malpropcost: attrs[`${prefix}_ability_cost`] || '', - solo1name: attrs[`${prefix}_ability_solo_1_name`] || '', - solo1text: attrs[`${prefix}_ability_solo_1_text`] || '', - solo2name: attrs[`${prefix}_ability_solo_2_name`] || '', - solo2text: attrs[`${prefix}_ability_solo_2_text`] || '', + tier1: attrs[`${prefix}_${abilityPrefix}tier_1`] || '', + tier2: attrs[`${prefix}_${abilityPrefix}tier_2`] || '', + tier3: attrs[`${prefix}_${abilityPrefix}tier_3`] || '', + special: attrs[`${prefix}_${abilityPrefix}special`] || '', + effect: attrs[`${prefix}_${abilityPrefix}effect`] || '', + malprop: attrs[`${prefix}_${abilityPrefix}malice`] || '', + malpropcost: attrs[`${prefix}_${abilityPrefix}cost`] || '', + solo1name: attrs[`${prefix}_${abilityPrefix}solo_1_name`] || '', + solo1text: attrs[`${prefix}_${abilityPrefix}solo_1_text`] || '', + solo2name: attrs[`${prefix}_${abilityPrefix}solo_2_name`] || '', + solo2text: attrs[`${prefix}_${abilityPrefix}solo_2_text`] || '', } //Build the rollValueMap - these will be transformed into a {{key=[[value]]}} format. rollValueMap = { hasTrait: hasTrait, - hasSolo: attrs[`${prefix}_ability_subtype`] && attrs[`${prefix}_ability_subtype`].includes('solo') ? 1 : 0, - hasTrigger: attrs[`${prefix}_ability_type`].includes('triggered') && attrs[`${prefix}_ability_trigger`] ? 1 : 0, + hasSolo: attrs[`${prefix}_${abilityPrefix}subtype`] && attrs[`${prefix}_${abilityPrefix}subtype`].includes('solo') ? 1 : 0, + hasTrigger: attrs[`${prefix}_${abilityPrefix}type`].includes('triggered') && attrs[`${prefix}_${abilityPrefix}trigger`] ? 1 : 0, hasPowerRoll: attrs[`${prefix}_has_power_roll`] === 'on' ? 1 : 0, hasSpecial: attrs[`${prefix}_has_special`] === 'on' ? 1 : 0, hasEffect: hasEffect, @@ -2530,7 +2506,35 @@
**Repeated Maneuvers display **/ on('clicked:repeating_maneuvers:share', async (event) => { - const abilityAttributeNames = [ + handleAbilityShare('repeating_maneuvers', 'maneuver'); + }); + +/** +**Repeated Triggered display +**/ + on('clicked:repeating_triggered:share', async (event) => { + handleAbilityShare('repeating_triggered', 'triggered'); + }); + +/** +**Repeated No Action display +**/ + on('clicked:repeating_noaction:share', async (event) => { + handleAbilityShare('repeating_noaction', 'noaction'); + }); + +/** +**Repeated Moves display +**/ + on('clicked:repeating_moves:share', async (event) => { + handleAbilityShare('repeating_moves', 'moves'); + }); + +/** +**Repeated Maneuvers power roll +**/ + on('clicked:repeating_maneuvers:power-roll-share', async (event) => { + const maneuverAttributeNames = [ 'maneuver_name', 'maneuver_cost', 'maneuver_description', 'maneuver_keywords', 'maneuver_type', 'maneuver_distance', 'maneuver_target', 'maneuver_trigger', 'has_power_roll', 'maneuver_characteristic', @@ -2538,247 +2542,7 @@
]; const attrs = await getAttrsAsync([ 'resource_name', - ...abilityAttributeNames.map(x => `repeating_maneuvers_${x}`), - ]); - const resourceName = attrs.resource_name || getTranslationByKey('resource-name-placeholder'); - - const directMap = { - name: attrs.repeating_maneuvers_maneuver_cost && attrs.repeating_maneuvers_maneuver_cost !== '0' - ? `${attrs.repeating_maneuvers_maneuver_name} (${attrs.repeating_maneuvers_maneuver_cost} ${resourceName})` - : attrs.repeating_maneuvers_maneuver_name, - cost: attrs.repeating_maneuvers_maneuver_cost, - description: attrs.repeating_maneuvers_maneuver_description, - keywords: attrs.repeating_maneuvers_maneuver_keywords, - distance: attrs.repeating_maneuvers_maneuver_distance, - target: attrs.repeating_maneuvers_maneuver_target, - trigger: attrs.repeating_maneuvers_maneuver_trigger, - characteristic: attrs.repeating_maneuvers_maneuver_characteristic, - tier1: attrs.repeating_maneuvers_maneuver_tier_1, - tier2: attrs.repeating_maneuvers_maneuver_tier_2, - tier3: attrs.repeating_maneuvers_maneuver_tier_3, - effect: attrs.repeating_maneuvers_maneuver_effect, - }; - const translateMap = { - type: attrs.repeating_maneuvers_maneuver_type || 'no-action', - }; - const rollValueMap = { - hasTrigger: attrs.repeating_maneuvers_maneuver_type.includes('triggered') - && attrs.repeating_maneuvers_maneuver_trigger - ? 1 : 0, - hasPowerRoll: attrs.repeating_maneuvers_has_power_roll === 'on' - ? 1 : 0, - hasEffect: attrs.repeating_maneuvers_maneuver_effect - ? 1 : 0, - hasDistance: attrs.repeating_maneuvers_maneuver_distance - ? 1 : 0, - hasTarget: attrs.repeating_maneuvers_maneuver_target - ? 1 : 0, - }; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(translateMap) - .map(([key, value]) => `{{${key}=^{${value}}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - console.log('maneuver values', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); - }); - -/** -**Repeated Triggered display -**/ - on('clicked:repeating_triggered:share', async (event) => { - const abilityAttributeNames = [ - 'triggered_name', 'triggered_cost', 'triggered_description', 'triggered_keywords', - 'triggered_type', 'triggered_distance', 'triggered_target', 'triggered_trigger', - 'has_power_roll', 'triggered_characteristic', - 'triggered_tier_1', 'triggered_tier_2', 'triggered_tier_3', 'triggered_effect', - ]; - const attrs = await getAttrsAsync([ - 'resource_name', - ...abilityAttributeNames.map(x => `repeating_triggered_${x}`), - ]); - const resourceName = attrs.resource_name || getTranslationByKey('resource-name-placeholder'); - - const directMap = { - name: attrs.repeating_triggered_triggered_cost && attrs.repeating_triggered_triggered_cost !== '0' - ? `${attrs.repeating_triggered_triggered_name} (${attrs.repeating_triggered_triggered_cost} ${resourceName})` - : attrs.repeating_triggered_triggered_name, - cost: attrs.repeating_triggered_triggered_cost, - description: attrs.repeating_triggered_triggered_description, - keywords: attrs.repeating_triggered_triggered_keywords, - distance: attrs.repeating_triggered_triggered_distance, - target: attrs.repeating_triggered_triggered_target, - trigger: attrs.repeating_triggered_triggered_trigger, - characteristic: attrs.repeating_triggered_triggered_characteristic, - tier1: attrs.repeating_triggered_triggered_tier_1, - tier2: attrs.repeating_triggered_triggered_tier_2, - tier3: attrs.repeating_triggered_triggered_tier_3, - effect: attrs.repeating_triggered_triggered_effect, - }; - const translateMap = { - type: attrs.repeating_triggered_triggered_type || 'no-action', - }; - const rollValueMap = { - hasTrigger: attrs.repeating_triggered_triggered_type.includes('triggered') - && attrs.repeating_triggered_triggered_trigger - ? 1 : 0, - hasPowerRoll: attrs.repeating_triggered_has_power_roll === 'on' - ? 1 : 0, - hasEffect: attrs.repeating_triggered_triggered_effect - ? 1 : 0, - hasDistance: attrs.repeating_triggered_triggered_distance - ? 1 : 0, - hasTarget: attrs.repeating_triggered_triggered_target - ? 1 : 0, - }; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(translateMap) - .map(([key, value]) => `{{${key}=^{${value}}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - console.log('triggered values', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); - }); - -/** -**Repeated No Action display -**/ - on('clicked:repeating_noaction:share', async (event) => { - const abilityAttributeNames = [ - 'noaction_name', 'noaction_cost', 'noaction_description', 'noaction_keywords', - 'noaction_type', 'noaction_distance', 'noaction_target', 'noaction_trigger', - 'has_power_roll', 'noaction_characteristic', - 'noaction_tier_1', 'noaction_tier_2', 'noaction_tier_3', 'noaction_effect', - ]; - const attrs = await getAttrsAsync([ - 'resource_name', - ...abilityAttributeNames.map(x => `repeating_noaction_${x}`), - ]); - const resourceName = attrs.resource_name || getTranslationByKey('resource-name-placeholder'); - - const directMap = { - name: attrs.repeating_noaction_noaction_cost && attrs.repeating_noaction_noaction_cost !== '0' - ? `${attrs.repeating_noaction_noaction_name} (${attrs.repeating_noaction_noaction_cost} ${resourceName})` - : attrs.repeating_noaction_noaction_name, - cost: attrs.repeating_noaction_noaction_cost, - description: attrs.repeating_noaction_noaction_description, - keywords: attrs.repeating_noaction_noaction_keywords, - distance: attrs.repeating_noaction_noaction_distance, - target: attrs.repeating_noaction_noaction_target, - trigger: attrs.repeating_noaction_noaction_trigger, - characteristic: attrs.repeating_noaction_noaction_characteristic, - tier1: attrs.repeating_noaction_noaction_tier_1, - tier2: attrs.repeating_noaction_noaction_tier_2, - tier3: attrs.repeating_noaction_noaction_tier_3, - effect: attrs.repeating_noaction_noaction_effect, - }; - const translateMap = { - type: attrs.repeating_noaction_noaction_type || 'no-action', - }; - const rollValueMap = { - hasTrigger: attrs.repeating_noaction_noaction_type.includes('noaction') - && attrs.repeating_noaction_noaction_trigger - ? 1 : 0, - hasPowerRoll: attrs.repeating_noaction_has_power_roll === 'on' - ? 1 : 0, - hasEffect: attrs.repeating_noaction_noaction_effect - ? 1 : 0, - hasDistance: attrs.repeating_noaction_noaction_distance - ? 1 : 0, - hasTarget: attrs.repeating_noaction_noaction_target - ? 1 : 0, - }; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(translateMap) - .map(([key, value]) => `{{${key}=^{${value}}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - console.log('noaction values', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); - }); - -/** -**Repeated Moves display -**/ - on('clicked:repeating_moves:share', async (event) => { - const abilityAttributeNames = [ - 'moves_name', 'moves_cost', 'moves_description', 'moves_keywords', - 'moves_type', 'moves_distance', 'moves_target', 'moves_trigger', - 'has_power_roll', 'moves_characteristic', - 'moves_tier_1', 'moves_tier_2', 'moves_tier_3', 'moves_effect', - ]; - const attrs = await getAttrsAsync([ - 'resource_name', - ...abilityAttributeNames.map(x => `repeating_moves_${x}`), - ]); - const resourceName = attrs.resource_name || getTranslationByKey('resource-name-placeholder'); - - const directMap = { - name: attrs.repeating_moves_moves_cost && attrs.repeating_moves_moves_cost !== '0' - ? `${attrs.repeating_moves_moves_name} (${attrs.repeating_moves_moves_cost} ${resourceName})` - : attrs.repeating_moves_moves_name, - cost: attrs.repeating_moves_moves_cost, - description: attrs.repeating_moves_moves_description, - keywords: attrs.repeating_moves_moves_keywords, - distance: attrs.repeating_moves_moves_distance, - target: attrs.repeating_moves_moves_target, - trigger: attrs.repeating_moves_moves_trigger, - characteristic: attrs.repeating_moves_moves_characteristic, - tier1: attrs.repeating_moves_moves_tier_1, - tier2: attrs.repeating_moves_moves_tier_2, - tier3: attrs.repeating_moves_moves_tier_3, - effect: attrs.repeating_moves_moves_effect, - }; - const translateMap = { - type: attrs.repeating_moves_moves_type || 'no-action', - }; - const rollValueMap = { - hasTrigger: attrs.repeating_moves_moves_type.includes('moves') - && attrs.repeating_moves_moves_trigger - ? 1 : 0, - hasPowerRoll: attrs.repeating_moves_has_power_roll === 'on' - ? 1 : 0, - hasEffect: attrs.repeating_moves_moves_effect - ? 1 : 0, - hasDistance: attrs.repeating_moves_moves_distance - ? 1 : 0, - hasTarget: attrs.repeating_moves_moves_target - ? 1 : 0, - }; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(translateMap) - .map(([key, value]) => `{{${key}=^{${value}}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - console.log('moves values', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); - }); - -/** -**Repeated Maneuvers power roll -**/ - on('clicked:repeating_maneuvers:power-roll-share', async (event) => { - const maneuverAttributeNames = [ - 'maneuver_name', 'maneuver_cost', 'maneuver_description', 'maneuver_keywords', - 'maneuver_type', 'maneuver_distance', 'maneuver_target', 'maneuver_trigger', - 'has_power_roll', 'maneuver_characteristic', - 'maneuver_tier_1', 'maneuver_tier_2', 'maneuver_tier_3', 'maneuver_effect', - ]; - const attrs = await getAttrsAsync([ - 'resource_name', - ...maneuverAttributeNames.map(x => `repeating_maneuvers_${x}`), + ...maneuverAttributeNames.map(x => `repeating_maneuvers_${x}`), ]); const resourceName = attrs.resource_name || getTranslationByKey('resource-name-placeholder'); @@ -3013,982 +2777,148 @@
**Knockback Display **/ on('clicked:knockback_share', async (event) => { - const attributeNames = [ - 'knockback_name', - 'knockback_keywords', - 'knockback_distance', - 'knockback_target', - 'knockback_characteristic', - 'knockback_tier_1', - 'knockback_tier_2', - 'knockback_tier_3', - 'knockback_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.knockback_name, - keywords: attrs.knockback_keywords, - distance: attrs.knockback_distance, - target: attrs.knockback_target, - characteristic: attrs.knockback_characteristic, - tier1: attrs.knockback_tier_1, - tier2: attrs.knockback_tier_2, - tier3: attrs.knockback_tier_3, - effect: attrs.knockback_effect - }; - - -const rollValueMap = { - hasPowerRoll: '1', - hasDistance: '1', - hasTarget: '1', - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + '{{type=^{maneuver}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Knockback roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('knockback', ''); }); /** **Grab Display **/ on('clicked:grab_share', async (event) => { - const attributeNames = [ - 'grab_name', - 'grab_keywords', - 'grab_distance', - 'grab_target', - 'grab_characteristic', - 'grab_tier_1', - 'grab_tier_2', - 'grab_tier_3' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.grab_name, - keywords: attrs.grab_keywords, - distance: attrs.grab_distance, - target: attrs.grab_target, - characteristic: attrs.grab_characteristic, - tier1: attrs.grab_tier_1, - tier2: attrs.grab_tier_2, - tier3: attrs.grab_tier_3 - }; - - -const rollValueMap = { - hasPowerRoll: '1', - hasDistance: '1', - hasTarget: '1', -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + '{{type=^{maneuver}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Grab roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('grab', ''); }); /** **Escape Grab Display **/ on('clicked:escape_grab_share', async (event) => { - const attributeNames = [ - 'escape_grab_name', - 'escape_grab_keywords', - 'escape_grab_distance', - 'escape_grab_target', - 'escape_grab_characteristic', - 'escape_grab_tier_1', - 'escape_grab_tier_2', - 'escape_grab_tier_3' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.escape_grab_name, - keywords: attrs.escape_grab_keywords, - distance: attrs.escape_grab_distance, - target: attrs.escape_grab_target, - characteristic: attrs.escape_grab_characteristic, - tier1: attrs.escape_grab_tier_1, - tier2: attrs.escape_grab_tier_2, - tier3: attrs.escape_grab_tier_3 - }; - - -const rollValueMap = { - hasPowerRoll: '1', - hasDistance: '1', - hasTarget: '1', -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + '{{type=^{maneuver}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Escape Grab roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('escape_grab', ''); }); /** **Claw Dirt Display **/ on('clicked:claw_dirt_share', async (event) => { - const attributeNames = [ - 'claw_dirt_name', - 'claw_dirt_keywords', - 'claw_dirt_distance', - 'claw_dirt_target', - 'claw_dirt_characteristic', - 'claw_dirt_tier_1', - 'claw_dirt_tier_2', - 'claw_dirt_tier_3' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.claw_dirt_name, - keywords: attrs.claw_dirt_keywords, - distance: attrs.claw_dirt_distance, - target: attrs.claw_dirt_target, - characteristic: attrs.claw_dirt_characteristic, - tier1: attrs.claw_dirt_tier_1, - tier2: attrs.claw_dirt_tier_2, - tier3: attrs.claw_dirt_tier_3 - }; - - -const rollValueMap = { - hasPowerRoll: '1', - hasDistance: '1', - hasTarget: '1', -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + '{{type=^{maneuver}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Claw Dirt roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('claw_dirt', ''); }); /** **Advance Display **/ on('clicked:advance_share', async (event) => { - const attributeNames = [ - 'advance_name', - 'advance_keywords', - 'advance_distance', - 'advance_target', - 'advance_characteristic', - 'advance_tier_1', - 'advance_tier_2', - 'advance_tier_3', - 'advance_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.advance_name, - keywords: attrs.advance_keywords, - distance: attrs.advance_distance, - target: attrs.advance_target, - characteristic: attrs.advance_characteristic, - tier1: attrs.advance_tier_1, - tier2: attrs.advance_tier_2, - tier3: attrs.advance_tier_3, - effect: attrs.advance_effect - }; - - -const rollValueMap = { - hasDistance: '1', - hasTarget: '1', - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + '{{type=^{move-action}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Advance roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('advance', ''); }); /** **Disengage Display **/ on('clicked:disengage_share', async (event) => { - const attributeNames = [ - 'disengage_name', - 'disengage_keywords', - 'disengage_distance', - 'disengage_target', - 'disengage_characteristic', - 'disengage_tier_1', - 'disengage_tier_2', - 'disengage_tier_3', - 'disengage_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.disengage_name, - keywords: attrs.disengage_keywords, - distance: attrs.disengage_distance, - target: attrs.disengage_target, - characteristic: attrs.disengage_characteristic, - tier1: attrs.disengage_tier_1, - tier2: attrs.disengage_tier_2, - tier3: attrs.disengage_tier_3, - effect: attrs.disengage_effect - }; - - -const rollValueMap = { - hasDistance: '1', - hasTarget: '1', - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + '{{type=^{move-action}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Disengage roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('disengage', ''); }); /** **Ride Display **/ on('clicked:ride_share', async (event) => { - const attributeNames = [ - 'ride_name', - 'ride_keywords', - 'ride_distance', - 'ride_target', - 'ride_characteristic', - 'ride_tier_1', - 'ride_tier_2', - 'ride_tier_3', - 'ride_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.ride_name, - keywords: attrs.ride_keywords, - distance: attrs.ride_distance, - target: attrs.ride_target, - characteristic: attrs.ride_characteristic, - tier1: attrs.ride_tier_1, - tier2: attrs.ride_tier_2, - tier3: attrs.ride_tier_3, - effect: attrs.ride_effect - }; - - -const rollValueMap = { - hasDistance: '1', - hasTarget: '1', - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + '{{type=^{move-action}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Disengage roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('ride', ''); }); /** **Jump Display **/ on('clicked:jump_share', async (event) => { - const attributeNames = [ - 'jump_name', - 'jump_keywords', - 'jump_distance', - 'jump_target', - 'jump_characteristic', - 'jump_tier_1', - 'jump_tier_2', - 'jump_tier_3', - 'jump_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.jump_name, - distance: attrs.jump_distance, - target: attrs.jump_target, - characteristic: attrs.jump_characteristic, - tier1: attrs.jump_tier_1, - tier2: attrs.jump_tier_2, - tier3: attrs.jump_tier_3, - effect: attrs.jump_effect - }; - - -const rollValueMap = { - hasPowerRoll: '1', - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Jump roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('jump', ''); }); /** **Climb Other Creatures Display **/ on('clicked:climb_creature_share', async (event) => { - const attributeNames = [ - 'climb_creature_name', - 'climb_creature_keywords', - 'climb_creature_distance', - 'climb_creature_target', - 'climb_creature_characteristic', - 'climb_creature_tier_1', - 'climb_creature_tier_2', - 'climb_creature_tier_3', - 'climb_creature_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.climb_creature_name, - distance: attrs.climb_creature_distance, - target: attrs.climb_creature_target, - characteristic: attrs.climb_creature_characteristic, - tier1: attrs.climb_creature_tier_1, - tier2: attrs.climb_creature_tier_2, - tier3: attrs.climb_creature_tier_3, - effect: attrs.climb_creature_effect - }; - - -const rollValueMap = { - hasPowerRoll: '1', - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Climb Other Creature roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('climb_creature', ''); }); /** **Charge Display **/ on('clicked:charge_share', async (event) => { - const attributeNames = [ - 'charge_name', - 'charge_keywords', - 'charge_distance', - 'charge_target', - 'charge_characteristic', - 'charge_tier_1', - 'charge_tier_2', - 'charge_tier_3', - 'charge_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.charge_name, - keywords: attrs.charge_keywords, - distance: attrs.charge_distance, - target: attrs.charge_target, - characteristic: attrs.charge_characteristic, - tier1: attrs.charge_tier_1, - tier2: attrs.charge_tier_2, - tier3: attrs.charge_tier_3, - effect: attrs.charge_effect - }; - - -const rollValueMap = { - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + '{{type=^{main-action}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Charge roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('charge', ''); }); /** **Defend Display **/ - on('clicked:defend_share', async (event) => { - const attributeNames = [ - 'defend_name', - 'defend_keywords', - 'defend_distance', - 'defend_target', - 'defend_characteristic', - 'defend_tier_1', - 'defend_tier_2', - 'defend_tier_3', - 'defend_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.defend_name, - keywords: attrs.defend_keywords, - distance: attrs.defend_distance, - target: attrs.defend_target, - characteristic: attrs.defend_characteristic, - tier1: attrs.defend_tier_1, - tier2: attrs.defend_tier_2, - tier3: attrs.defend_tier_3, - effect: attrs.defend_effect - }; - - -const rollValueMap = { - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + '{{type=^{main-action}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Defend roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); - }); - -/** -**Heal Display -**/ - on('clicked:heal_share', async (event) => { - const attributeNames = [ - 'heal_name', - 'heal_keywords', - 'heal_distance', - 'heal_target', - 'heal_characteristic', - 'heal_tier_1', - 'heal_tier_2', - 'heal_tier_3', - 'heal_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.heal_name, - keywords: attrs.heal_keywords, - distance: attrs.heal_distance, - target: attrs.heal_target, - characteristic: attrs.heal_characteristic, - tier1: attrs.heal_tier_1, - tier2: attrs.heal_tier_2, - tier3: attrs.heal_tier_3, - effect: attrs.heal_effect - }; - - -const rollValueMap = { - hasEffect: '1', - hasDistance: '1', - hasTarget: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + '{{type=^{main-action}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); + on('clicked:defend_share', async (event) => { + handleAbilityShare('defend', ''); + }); - console.log('Heal roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); +/** +**Heal Display +**/ + on('clicked:heal_share', async (event) => { + handleAbilityShare('heal', ''); }); /** **Aid Attack Display **/ on('clicked:aid_attack_share', async (event) => { - const attributeNames = [ - 'aid_attack_name', - 'aid_attack_keywords', - 'aid_attack_distance', - 'aid_attack_target', - 'aid_attack_characteristic', - 'aid_attack_tier_1', - 'aid_attack_tier_2', - 'aid_attack_tier_3', - 'aid_attack_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.aid_attack_name, - keywords: attrs.aid_attack_keywords, - distance: attrs.aid_attack_distance, - target: attrs.aid_attack_target, - characteristic: attrs.aid_attack_characteristic, - tier1: attrs.aid_attack_tier_1, - tier2: attrs.aid_attack_tier_2, - tier3: attrs.aid_attack_tier_3, - effect: attrs.aid_attack_effect - }; - - -const rollValueMap = { - hasDistance: '1', - hasTarget: '1', - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}} ' - + '{{type=^{maneuver}}}' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Aid Attack roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('aid_attack', ''); }); /** **Catch Breath Display **/ on('clicked:catch_breath_share', async (event) => { - const attributeNames = [ - 'catch_breath_name', - 'catch_breath_keywords', - 'catch_breath_distance', - 'catch_breath_target', - 'catch_breath_characteristic', - 'catch_breath_tier_1', - 'catch_breath_tier_2', - 'catch_breath_tier_3', - 'catch_breath_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.catch_breath_name, - keywords: attrs.catch_breath_keywords, - distance: attrs.catch_breath_distance, - target: attrs.catch_breath_target, - characteristic: attrs.catch_breath_characteristic, - tier1: attrs.catch_breath_tier_1, - tier2: attrs.catch_breath_tier_2, - tier3: attrs.catch_breath_tier_3, - effect: attrs.catch_breath_effect - }; - - -const rollValueMap = { - hasDistance: '1', - hasTarget: '1', - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}}' - + '{{type=^{maneuver}}}' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Catch Breath roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('catch_breath', ''); }); /** **Hide Display **/ on('clicked:hide_share', async (event) => { - const attributeNames = [ - 'hide_name', - 'hide_keywords', - 'hide_distance', - 'hide_target', - 'hide_characteristic', - 'hide_tier_1', - 'hide_tier_2', - 'hide_tier_3', - 'hide_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.hide_name, - keywords: attrs.hide_keywords, - distance: attrs.hide_distance, - target: attrs.hide_target, - characteristic: attrs.hide_characteristic, - tier1: attrs.hide_tier_1, - tier2: attrs.hide_tier_2, - tier3: attrs.hide_tier_3, - effect: attrs.hide_effect - }; - - -const rollValueMap = { - hasDistance: '1', - hasTarget: '1', - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}}' - + '{{type=^{maneuver}}}' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Hide roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('hide', ''); }); /** **Search Display **/ on('clicked:search_share', async (event) => { - const attributeNames = [ - 'search_name', - 'search_keywords', - 'search_distance', - 'search_target', - 'search_characteristic', - 'search_tier_1', - 'search_tier_2', - 'search_tier_3', - 'search_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.search_name, - keywords: attrs.search_keywords, - distance: attrs.search_distance, - target: attrs.search_target, - characteristic: attrs.search_characteristic, - tier1: attrs.search_tier_1, - tier2: attrs.search_tier_2, - tier3: attrs.search_tier_3, - effect: attrs.search_effect - }; - - -const rollValueMap = { - hasDistance: '1', - hasTarget: '1', - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}}' - + '{{type=^{maneuver}}}' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Search roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('search', ''); }); /** **Stand up Display **/ on('clicked:standup_share', async (event) => { - const attributeNames = [ - 'standup_name', - 'standup_keywords', - 'standup_distance', - 'standup_target', - 'standup_characteristic', - 'standup_tier_1', - 'standup_tier_2', - 'standup_tier_3', - 'standup_effect' - ]; - const directMap = { - name: attrs.standup_name, - keywords: attrs.standup_keywords, - distance: attrs.standup_distance, - target: attrs.standup_target, - characteristic: attrs.standup_characteristic, - tier1: attrs.standup_tier_1, - tier2: attrs.standup_tier_2, - tier3: attrs.standup_tier_3, - effect: attrs.standup_effect - }; -const rollValueMap = { - hasDistance: '1', - hasTarget: '1', - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}}' - + '{{type=^{maneuver}}}' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Standup roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('standup', ''); }); /** **Use Consumable Display **/ on('clicked:consumable_share', async (event) => { - const attributeNames = [ - 'consumable_name', - 'consumable_keywords', - 'consumable_distance', - 'consumable_target', - 'consumable_characteristic', - 'consumable_tier_1', - 'consumable_tier_2', - 'consumable_tier_3', - 'consumable_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - - const directMap = { - name: attrs.consumable_name, - keywords: attrs.consumable_keywords, - distance: attrs.consumable_distance, - target: attrs.consumable_target, - characteristic: attrs.consumable_characteristic, - tier1: attrs.consumable_tier_1, - tier2: attrs.consumable_tier_2, - tier3: attrs.consumable_tier_3, - effect: attrs.consumable_effect - }; - - -const rollValueMap = { - hasDistance: '1', - hasTarget: '1', - hasEffect: '1' -}; - const roll = `&{template:ability} ` - + '{{powerRoll=^{power-roll}}}' - + '{{type=^{maneuver}}}' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Consumable roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + handleAbilityShare('consumable', ''); }); /** **Knockback Power Roll **/ on('clicked:knockback_power_roll_share', async (event) => { - const attributeNames = [ - 'knockback_name', - 'knockback_keywords', - 'knockback_distance', - 'knockback_target', - 'knockback_characteristic', - 'knockback_tier_1', - 'knockback_tier_2', - 'knockback_tier_3', - 'knockback_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - const characteristicValue = attrs['knockback_characteristic']; - const characteristicTranslation = getTranslationByKey(characteristicValue) || characteristicValue; - const edgeOrBaneTranslation = getTranslationByKey('edge-or-bane') || 'edge-or-bane'; - const noEdgeOrBaneTranslation = getTranslationByKey('no-edge-or-bane') || 'no-edge-or-bane'; - const doubleEdgeTranslation = getTranslationByKey('double-edge') || 'double-edge'; - const edgeTranslation = getTranslationByKey('edge') || 'edge'; - const baneTranslation = getTranslationByKey('bane') || 'bane'; - const doubleBaneTranslation = getTranslationByKey('double-bane') || 'double-bane'; - const bonusOrPenaltyTranslation = getTranslationByKey('bonus-or-penalty') || 'bonus-or-penalty'; - - const directMap = { - name: attrs.knockback_name, - keywords: attrs.knockback_keywords, - distance: attrs.knockback_distance, - target: attrs.knockback_target, - characteristic: attrs.knockback_characteristic, - tier1: attrs.knockback_tier_1, - tier2: attrs.knockback_tier_2, - tier3: attrs.knockback_tier_3, - effect: attrs.knockback_effect - }; - -const rollValueMap = { - hasPowerRoll: '1', - hasDistance: '1', - hasTarget: '1', - hasEffect: '1' -}; - const roll = '&{template:ability} ' + - '[[ [[2d10cs>11cf<0]][2d10] ' + - ` + [[${characteristicValue}]] ` + - ' + [[?{' + - edgeOrBaneTranslation + - `|${noEdgeOrBaneTranslation},0` + - `|${doubleEdgeTranslation},0[${doubleEdgeTranslation}]` + - `|${edgeTranslation},2[${edgeTranslation}]` + - `|${baneTranslation},-2[${baneTranslation}]` + - `|${doubleBaneTranslation},0[${doubleBaneTranslation}]` + - `}]][${edgeOrBaneTranslation}] ` + - ` + [[?{${bonusOrPenaltyTranslation}|0}]][${bonusOrPenaltyTranslation}] ` + - ']] ' - + '{{powerRoll=^{power-roll}: $[[4]]}} ' - + '{{type=^{maneuver}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Knockback power roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + const attrs = await getAttrsAsync([ + 'knockback_name', + 'knockback_characteristic', + ]); + rollPower(attrs.knockback_characteristic, attrs.knockback_name); }); /** **Grab Power Roll **/ on('clicked:grab_power_roll_share', async (event) => { - const attributeNames = [ - 'grab_name', - 'grab_keywords', - 'grab_distance', - 'grab_target', - 'grab_characteristic', - 'grab_tier_1', - 'grab_tier_2', - 'grab_tier_3', - 'grab_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - const characteristicValue = attrs['grab_characteristic']; - const characteristicTranslation = getTranslationByKey(characteristicValue) || characteristicValue; - const edgeOrBaneTranslation = getTranslationByKey('edge-or-bane') || 'edge-or-bane'; - const noEdgeOrBaneTranslation = getTranslationByKey('no-edge-or-bane') || 'no-edge-or-bane'; - const doubleEdgeTranslation = getTranslationByKey('double-edge') || 'double-edge'; - const edgeTranslation = getTranslationByKey('edge') || 'edge'; - const baneTranslation = getTranslationByKey('bane') || 'bane'; - const doubleBaneTranslation = getTranslationByKey('double-bane') || 'double-bane'; - const bonusOrPenaltyTranslation = getTranslationByKey('bonus-or-penalty') || 'bonus-or-penalty'; - - const directMap = { - name: attrs.grab_name, - keywords: attrs.grab_keywords, - distance: attrs.grab_distance, - target: attrs.grab_target, - characteristic: attrs.grab_characteristic, - tier1: attrs.grab_tier_1, - tier2: attrs.grab_tier_2, - tier3: attrs.grab_tier_3, - effect: attrs.grab_effect - }; - -const rollValueMap = { - hasPowerRoll: '1', - hasDistance: '1', - hasTarget: '1', - hasEffect: '1' -}; - const roll = '&{template:ability} ' + - '[[ [[2d10cs>11cf<0]][2d10] ' + - ` + [[${characteristicValue}]] ` + - ' + [[?{' + - edgeOrBaneTranslation + - `|${noEdgeOrBaneTranslation},0` + - `|${doubleEdgeTranslation},0[${doubleEdgeTranslation}]` + - `|${edgeTranslation},2[${edgeTranslation}]` + - `|${baneTranslation},-2[${baneTranslation}]` + - `|${doubleBaneTranslation},0[${doubleBaneTranslation}]` + - `}]][${edgeOrBaneTranslation}] ` + - ` + [[?{${bonusOrPenaltyTranslation}|0}]][${bonusOrPenaltyTranslation}] ` + - ']] ' - + '{{powerRoll=^{power-roll}: $[[4]]}} ' - + '{{type=^{maneuver}}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Grab power roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + const attrs = await getAttrsAsync([ + 'grab_name', + 'grab_characteristic', + ]); + rollPower(attrs.grab_characteristic, attrs.grab_name); }); /** @@ -4124,63 +3054,12 @@
**Climb Other Creature Power Roll **/ on('clicked:climb_creature_power_roll_share', async (event) => { - const attributeNames = [ - 'climb_creature_name', - 'climb_creature_keywords', - 'climb_creature_distance', - 'climb_creature_target', - 'climb_creature_characteristic', - 'climb_creature_tier_1', - 'climb_creature_tier_2', - 'climb_creature_tier_3', - 'climb_creature_effect' - ]; - - const attrs = await getAttrsAsync(attributeNames); - const characteristicValue = attrs['climb_creature_characteristic']; - const characteristicTranslation = getTranslationByKey(characteristicValue) || characteristicValue; - const edgeOrBaneTranslation = getTranslationByKey('edge-or-bane') || 'edge-or-bane'; - const noEdgeOrBaneTranslation = getTranslationByKey('no-edge-or-bane') || 'no-edge-or-bane'; - const doubleEdgeTranslation = getTranslationByKey('double-edge') || 'double-edge'; - const edgeTranslation = getTranslationByKey('edge') || 'edge'; - const baneTranslation = getTranslationByKey('bane') || 'bane'; - const doubleBaneTranslation = getTranslationByKey('double-bane') || 'double-bane'; - const bonusOrPenaltyTranslation = getTranslationByKey('bonus-or-penalty') || 'bonus-or-penalty'; - - const directMap = { - name: attrs.climb_creature_name, - characteristic: attrs.climb_creature_characteristic, - tier1: attrs.climb_creature_tier_1, - tier2: attrs.climb_creature_tier_2, - tier3: attrs.climb_creature_tier_3, - effect: attrs.climb_creature_effect - }; - -const rollValueMap = { - hasPowerRoll: '1', - hasEffect: '1' -}; - const roll = '&{template:ability} ' + - '[[ [[2d10cs>11cf<0]][2d10] ' + - ` + [[${characteristicValue}]] ` + - ' + [[?{' + - edgeOrBaneTranslation + - `|${noEdgeOrBaneTranslation},0` + - `|${doubleEdgeTranslation},0[${doubleEdgeTranslation}]` + - `|${edgeTranslation},2[${edgeTranslation}]` + - `|${baneTranslation},-2[${baneTranslation}]` + - `|${doubleBaneTranslation},0[${doubleBaneTranslation}]` + - `}]][${edgeOrBaneTranslation}] ` + - ` + [[?{${bonusOrPenaltyTranslation}|0}]][${bonusOrPenaltyTranslation}] ` + - ']] ' - + '{{powerRoll=^{power-roll}: $[[4]]}} ' - + Object.entries(directMap) - .map(([key, value]) => `{{${key}=${value}}} `) - + Object.entries(rollValueMap) - .map(([key, value]) => `{{${key}=[[${value}]]}} `); - - console.log('Climb Other Creature power roll:', roll); - startRoll(roll, ({ rollId }) => finishRoll(rollId)); + const attrs = await getAttrsAsync([ + 'climb_creature_characteristic', + 'climb_creature_name', + ]); + console.log(attrs); + rollPower(attrs.repeating_abilities_ability_characteristic,attrs.repeating_abilities_ability_name); }); // Share Perk Features @@ -4234,7 +3113,7 @@
// Share Player Repeated Ability on('clicked:repeating_abilities:share', async (event) => { - handleAbilityShare('repeating_abilities'); + handleAbilityShare('repeating_abilities','ability'); }); // Repeated Ability power roll @@ -4249,7 +3128,7 @@
// Share Monster Repeated Abilities on('clicked:repeating_npcabilities:share', async (event) => { - handleAbilityShare("repeating_npcabilities"); + handleAbilityShare('repeating_npcabilities', 'ability'); }); //Melee Free Strike Display