From 7c6c2b2ec3d7b09474a4df0097d6b7c97957b96d Mon Sep 17 00:00:00 2001 From: phBalance Date: Fri, 23 Feb 2024 18:03:30 -0700 Subject: [PATCH 1/9] refactor(determineExtraDiceDamage): don't use --- module/item/item-attack.js | 8 ++++---- module/utility/adjustment.js | 19 ++++++++++++------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/module/item/item-attack.js b/module/item/item-attack.js index 1aace1b4..a0d54f21 100644 --- a/module/item/item-attack.js +++ b/module/item/item-attack.js @@ -6,7 +6,6 @@ import { calculateDiceFormulaParts, CombatSkillLevelsForAttack, convertToDcFromItem, - determineExtraDiceDamage, } from "../utility/damage.js"; import { performAdjustment, @@ -1766,14 +1765,15 @@ async function _performAbsorptionForToken( let maxAbsorption; if (actor.system.is5e) { const dice = absorptionItem.system.dice; - const extraDice = determineExtraDiceDamage(absorptionItem); + const extraDice = absorptionItem.system.extraDice; // Absorption allowed based on a roll with the usual requirements const absorptionRoller = new HeroRoller() .makeAdjustmentRoll() .addDice(dice) - .addHalfDice(extraDice === "+1d3" ? 1 : 0) - .addNumber(extraDice === "+1" ? 1 : 0); + .addHalfDice(extraDice === "half" ? 1 : 0) + .addDiceMinus1(extraDice === "one-pip" ? 1 : 0) + .addNumber(extraDice === "pip" ? 1 : 0); await absorptionRoller.roll(); maxAbsorption = absorptionRoller.getAdjustmentTotal(); diff --git a/module/utility/adjustment.js b/module/utility/adjustment.js index 2b8aae11..f9f4ab0c 100644 --- a/module/utility/adjustment.js +++ b/module/utility/adjustment.js @@ -1,5 +1,4 @@ import { getPowerInfo } from "./util.js"; -import { determineExtraDiceDamage } from "./damage.js"; import { RoundFavorPlayerUp } from "./round.js"; /** @@ -139,14 +138,17 @@ export function determineMaxAdjustment(item) { // Max pips in a roll is starting max base. let maxAdjustment = item.system.dice * 6; - const extraDice = determineExtraDiceDamage(item); + const extraDice = item.system.extraDice; switch (extraDice) { - case "+1": + case "pip": maxAdjustment = maxAdjustment + 1; break; - case "+1d3": + case "half": maxAdjustment = maxAdjustment + 3; break; + case "one-pip": + maxAdjustment = maxAdjustment + 5; + break; default: break; } @@ -175,14 +177,17 @@ export function determineMaxAdjustment(item) { let maxAdjustment = item.system.dice * 6; - const extraDice = determineExtraDiceDamage(item); + const extraDice = item.system.extraDice; switch (extraDice) { - case "+1": + case "pip": maxAdjustment = maxAdjustment + 1; break; - case "+1d3": + case "half": maxAdjustment = maxAdjustment + 3; break; + case "one-pip": + maxAdjustment = maxAdjustment + 5; + break; default: break; } From 8014bfb6ad350c9d3f5d900cd8d80515f3c671b4 Mon Sep 17 00:00:00 2001 From: phBalance Date: Fri, 23 Feb 2024 18:05:29 -0700 Subject: [PATCH 2/9] refactor(determineExtraDiceDamage): remove now unused function --- module/testing/testing-damage-functions.js | 42 ---------------------- module/utility/damage.js | 16 --------- 2 files changed, 58 deletions(-) diff --git a/module/testing/testing-damage-functions.js b/module/testing/testing-damage-functions.js index 49be896d..a9167580 100644 --- a/module/testing/testing-damage-functions.js +++ b/module/testing/testing-damage-functions.js @@ -2,7 +2,6 @@ import { HeroSystem6eActor } from "../actor/actor.js"; import { HeroSystem6eItem } from "../item/item.js"; import { determineStrengthDamage, - determineExtraDiceDamage, convertFromDC, addTerms, convertToDcFromItem, @@ -113,47 +112,6 @@ export function registerDamageFunctionTests(quench) { }); }); - describe("Extra Damage", function () { - it("Extra Dice- Zero", function () { - const item = new HeroSystem6eItem({ - name: "Test", - type: "attack", - system: { - extraDice: "zero", - }, - parent: actor, - }); - - assert.equal(determineExtraDiceDamage(item), ""); - }); - - it("Extra Dice - Pip", function () { - const item = new HeroSystem6eItem({ - name: "Test", - type: "attack", - system: { - extraDice: "pip", - }, - parent: actor, - }); - - assert.equal(determineExtraDiceDamage(item), "+1"); - }); - - it("Extra Dice - Half", function () { - const item = new HeroSystem6eItem({ - name: "Test", - type: "attack", - system: { - extraDice: "half", - }, - parent: actor, - }); - - assert.equal(determineExtraDiceDamage(item), "+1d3"); - }); - }); - describe("convertFromDC", function () { describe("invalid inputs", function () { const item = new HeroSystem6eItem({ diff --git a/module/utility/damage.js b/module/utility/damage.js index 0c53be4e..af7ffb3a 100644 --- a/module/utility/damage.js +++ b/module/utility/damage.js @@ -1,5 +1,3 @@ -import { HEROSYS } from "../herosystem6e.js"; - // DAMAGE CLASS (DC) // // Different dice of damage are not the same – 2d6 of Killing @@ -57,20 +55,6 @@ export function determineStrengthDamage(item, effectiveStr) { return strTag; } -export function determineExtraDiceDamage(item) { - switch (item.system.extraDice) { - case "zero": - return ""; - case "pip": - return "+1"; - case "half": - return "+1d3"; - default: - HEROSYS.log(false, "Failed to get extra dice"); - break; - } -} - // Determine DC solely from item/attack export function convertToDcFromItem(item, options) { let actor = item.actor; From 680de7346907e14ab1b19fd4a61136750265f3f7 Mon Sep 17 00:00:00 2001 From: phBalance Date: Fri, 23 Feb 2024 18:06:50 -0700 Subject: [PATCH 3/9] fix(extraDice): 1d6-1 is now a valid extraDice value of "one-pip" --- module/config.js | 3 ++- module/item/item.js | 5 ++--- module/migration.js | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/module/config.js b/module/config.js index d100a583..5125a033 100644 --- a/module/config.js +++ b/module/config.js @@ -8,7 +8,8 @@ HERO.bool = { HERO.extraDice = { zero: "+0", pip: "+1", - half: "+1/2D6", + half: "+½D6", + "one-pip": "+1D6-1", }; HERO.attacksWith = { diff --git a/module/item/item.js b/module/item/item.js index aa3367a1..fb79cac3 100644 --- a/module/item/item.js +++ b/module/item/item.js @@ -3184,9 +3184,8 @@ export class HeroSystem6eItem extends Item { } if (this.findModsByXmlid("MINUSONEPIP")) { - // Typically only allowed for killing attacks. - // Appears that +1d6-1 is roughly equal to +1/2 d6 - this.system.extraDice = "half"; + // +1d6-1 is equal to +1/2 d6 DC-wise but is uncommon. + this.system.extraDice = "one-pip"; } const aoeModifier = this.getAoeModifier(); diff --git a/module/migration.js b/module/migration.js index e366199b..2b2a8d20 100644 --- a/module/migration.js +++ b/module/migration.js @@ -355,6 +355,7 @@ export async function migrateWorld() { // if lastMigration < 3.0.59 // Active Effects for adjustments changed format + // d6-1 and 1/2d6 are now distinctly different extra dice if (foundry.utils.isNewerVersion("3.0.59", lastMigration)) { const queue = getAllActorsInGame(); let dateNow = new Date(); @@ -370,6 +371,7 @@ export async function migrateWorld() { } await migrate_actor_active_effects_to_3_0_59(actor); + await migrate_actor_items_to_3_0_59(actor); } } @@ -432,6 +434,25 @@ async function migrateActorCostDescription(actor) { } } +// 1/2 d6 and 1d6-1 are not the same roll but are the same DC - make them distinct +async function migrate_actor_items_to_3_0_59(actor) { + for (const item of actor.items) { + let newValue; + if (item.findModsByXmlid("PLUSONEHALFDIE")) { + newValue = "half"; + } else if (item.findModsByXmlid("MINUSONEPIP")) { + // +1d6-1 is equal to +1/2 d6 DC-wise but is uncommon. + newValue = "one-pip"; + } + + if (item.system.extraDice && newValue) { + await item.update({ + "system.extraDice": newValue, + }); + } + } +} + async function migrate_actor_active_effects_to_3_0_59(actor) { for (const activeEffect of actor.temporaryEffects) { if ( From 77aa9bcf73b43fdba352dd89f8efb95efa54e6c1 Mon Sep 17 00:00:00 2001 From: phBalance Date: Fri, 23 Feb 2024 21:21:25 -0700 Subject: [PATCH 4/9] fix(1d6-1): support the display of 1d6-1 terms --- module/testing/testing-damage-functions.js | 94 +++++++++++----------- module/testing/testing-upload.js | 78 ++++++++++++++++-- module/utility/damage.js | 69 +++++++--------- 3 files changed, 149 insertions(+), 92 deletions(-) diff --git a/module/testing/testing-damage-functions.js b/module/testing/testing-damage-functions.js index a9167580..c164cfdf 100644 --- a/module/testing/testing-damage-functions.js +++ b/module/testing/testing-damage-functions.js @@ -3,7 +3,6 @@ import { HeroSystem6eItem } from "../item/item.js"; import { determineStrengthDamage, convertFromDC, - addTerms, convertToDcFromItem, } from "../utility/damage.js"; @@ -143,7 +142,7 @@ export function registerDamageFunctionTests(quench) { }); it("2", function () { - assert.equal(convertFromDC(killingItem, 2), "1d3"); + assert.equal(convertFromDC(killingItem, 2), "½d6"); }); it("3", function () { @@ -151,14 +150,11 @@ export function registerDamageFunctionTests(quench) { }); it("4", function () { - assert.equal(convertFromDC(killingItem, 4), "1d6 + 1"); + assert.equal(convertFromDC(killingItem, 4), "1d6+1"); }); it("5", function () { - assert.equal( - convertFromDC(killingItem, 5), - "1d6 + 1d3", - ); + assert.equal(convertFromDC(killingItem, 5), "1½d6"); }); it("6", function () { @@ -166,7 +162,47 @@ export function registerDamageFunctionTests(quench) { }); it("7", function () { - assert.equal(convertFromDC(killingItem, 7), "2d6 + 1"); + assert.equal(convertFromDC(killingItem, 7), "2d6+1"); + }); + }); + + describe("killing attacks with 1d6-1 rather than 1/2d6", function () { + const killingItem = new HeroSystem6eItem({ + name: "Test", + type: "attack", + system: { + killing: true, + extraDice: "one-pip", + }, + parent: actor, + }); + + it("1", function () { + assert.equal(convertFromDC(killingItem, 1), "1"); + }); + + it("2", function () { + assert.equal(convertFromDC(killingItem, 2), "1d6-1"); + }); + + it("3", function () { + assert.equal(convertFromDC(killingItem, 3), "1d6"); + }); + + it("4", function () { + assert.equal(convertFromDC(killingItem, 4), "1d6+1"); + }); + + it("5", function () { + assert.equal(convertFromDC(killingItem, 5), "2d6-1"); + }); + + it("6", function () { + assert.equal(convertFromDC(killingItem, 6), "2d6"); + }); + + it("7", function () { + assert.equal(convertFromDC(killingItem, 7), "2d6+1"); }); }); @@ -188,21 +224,21 @@ export function registerDamageFunctionTests(quench) { it("1.2", function () { assert.equal( convertFromDC(nonKillingItem, 1.2), - "1d6 + 1", + "1d6+1", ); }); it("1.5", function () { assert.equal( convertFromDC(nonKillingItem, 1.5), - "1d6 + 1d3", + "1½d6", ); }); it("13.2", function () { assert.equal( convertFromDC(nonKillingItem, 13.2), - "13d6 + 1", + "13d6+1", ); }); @@ -213,46 +249,12 @@ export function registerDamageFunctionTests(quench) { it("1234567890.2", function () { assert.equal( convertFromDC(nonKillingItem, 1234567890.2), - "1234567890d6 + 1", + "1234567890d6+1", ); }); }); }); - describe("Add Terms", function () { - it("'' ''", function () { - assert.equal(addTerms("", ""), ""); - }); - - it("null null", function () { - assert.equal(addTerms(null, null), ""); - }); - - it("1d6 null", function () { - assert.equal(addTerms("1d6", null), "1d6"); - }); - - it("null 1d6", function () { - assert.equal(addTerms(null, "1d6"), "1d6"); - }); - - it("1d6 1d6", function () { - assert.equal(addTerms("1d6", "1d6"), "1d6 + 1d6"); - }); - - it("1d6 ''", function () { - assert.equal(addTerms("1d6", ""), "1d6"); - }); - - it("'' 1d6", function () { - assert.equal(addTerms("", "1d6"), "1d6"); - }); - - it("1d6 1d6", function () { - assert.equal(addTerms("1d6", "1d6"), "1d6 + 1d6"); - }); - }); - describe("convertToDcFromItem", function () { const item = new HeroSystem6eItem({ name: "Test", diff --git a/module/testing/testing-upload.js b/module/testing/testing-upload.js index 1126ad12..c230232b 100644 --- a/module/testing/testing-upload.js +++ b/module/testing/testing-upload.js @@ -1261,7 +1261,7 @@ export function registerUploadTests(quench) { it("description", function () { assert.equal( item.system.description, - "Killing Attack - Ranged 2 1/2d6 (ED) (40 Active Points); OAF (-1), 8 Charges (-1/2)", + "Killing Attack - Ranged 2½d6 (ED) (40 Active Points); OAF (-1), 8 Charges (-1/2)", ); }); @@ -1298,6 +1298,70 @@ export function registerUploadTests(quench) { }); }); + describe("2d6-1 RKA", async function () { + const contents = ` + + + + + + + `; + let item; + + before(async () => { + const actor = new HeroSystem6eActor( + { + name: "Quench Actor", + type: "pc", + }, + { temporary: true }, + ); + item = await new HeroSystem6eItem( + HeroSystem6eItem.itemDataFromXml(contents), + { temporary: true, parent: actor }, + ); + await item._postUpload(); + actor.items.set(item.system.XMLID, item); + item.skillRollUpdateValue(); + }); + + it("description", function () { + assert.equal( + item.system.description, + "Killing Attack - Ranged 2d6-1 (ED; +1d6 -1)", + ); + }); + + it("realCost", function () { + assert.equal(item.system.realCost, 25); + }); + + it("activePoints", function () { + assert.equal(item.system.activePoints, 25); + }); + + it("dice", function () { + assert.equal(item.system.dice, 1); + }); + + it("extraDice", function () { + assert.equal(item.system.extraDice, "one-pip"); + }); + + it("end", function () { + assert.equal(item.system.end, 2); + }); + + it("charges", function () { + assert.equal(item.system.charges, undefined); + }); + + it("doesn't use strength", function () { + assert.equal(item.system.usesStrength, false); + }); + }); + describe("MINDCONTROL", async function () { const contents = ` @@ -2409,7 +2473,7 @@ export function registerUploadTests(quench) { it("description", function () { assert.equal( item.system.description, - "1/2 Phase, -2 OCV, +0 DCV, HKA 1d6 +1", + "1/2 Phase, -2 OCV, +0 DCV, HKA 1d6+1", ); }); @@ -2737,7 +2801,7 @@ export function registerUploadTests(quench) { it("description", function () { assert.equal( item.system.description, - "Sight, Hearing and Mental Groups, Normal Smell, Danger Sense and Combat Sense Flash 5 1/2d6", + "Sight, Hearing and Mental Groups, Normal Smell, Danger Sense and Combat Sense Flash 5½d6", ); }); @@ -2982,7 +3046,7 @@ export function registerUploadTests(quench) { it("description", function () { assert.equal( item.system.description, - "1d6 + 1 Mind Scan (Animal; +1 pip; +9 OMCV; Additional Class Of Minds; Additional Class Of Minds; Additional Class Of Minds), Cumulative (+1/2) (60 Active Points); Cannot Attack Through Link (neither the character nor his target can use the link to attack each other mentally, but they can communicate; -1/2)", + "1d6+1 Mind Scan (Animal; +1 pip; +9 OMCV; Additional Class Of Minds; Additional Class Of Minds; Additional Class Of Minds), Cumulative (+1/2) (60 Active Points); Cannot Attack Through Link (neither the character nor his target can use the link to attack each other mentally, but they can communicate; -1/2)", ); }); @@ -3091,7 +3155,7 @@ export function registerUploadTests(quench) { it("description", async function () { assert.equal( item.system.description, - "Absorption 2 1/2d6 (energy) to STUN", + "Absorption 2½d6 (energy) to STUN", ); }); @@ -3783,7 +3847,7 @@ export function registerUploadTests(quench) { it("description", function () { assert.equal( item.system.description, - "Suppress Flight 5 1/2d6, Armor Piercing (+1/2) (42 Active Points); Range Based On Strength (-1/4)", + "Suppress Flight 5½d6, Armor Piercing (+1/2) (42 Active Points); Range Based On Strength (-1/4)", ); }); @@ -3846,7 +3910,7 @@ export function registerUploadTests(quench) { it("description", function () { assert.equal( item.system.description, - "Aid CON 3d6 + 1 (+1 pip; Increased Maximum (+8 points) (27 total points)), Continuous (+1) (74 Active Points); Crew-Served (2 people; -1/4)", + "Aid CON 3d6+1 (+1 pip; Increased Maximum (+8 points) (27 total points)), Continuous (+1) (74 Active Points); Crew-Served (2 people; -1/4)", ); }); diff --git a/module/utility/damage.js b/module/utility/damage.js index af7ffb3a..1312bd2f 100644 --- a/module/utility/damage.js +++ b/module/utility/damage.js @@ -71,6 +71,7 @@ export function convertToDcFromItem(item, options) { dc += 1; break; case "half": + case "one-pip": dc += 2; break; } @@ -242,7 +243,13 @@ export function convertToDcFromItem(item, options) { return { dc: dc, tags: tags, end: end }; } +/** + * This is not perfect as it has to make a guess at if the 2 DC chunks are a 1/2d6 or 1d6-1. Make a guess by looking + * at the extraDice for a hint if available. Otherwise default to 1/2d6 + */ +// TODO: Does 0.2, 0.5, and 1 as partials for 5AP/DC scale correctly when the costs are > 5AP/die?/ export function calculateDiceFormulaParts(item, dc) { + const usesDieLessOne = item.system.extraDice === "one-pip"; let d6Count = 0; let halfDieCount = 0; let constant = 0; @@ -277,52 +284,36 @@ export function calculateDiceFormulaParts(item, dc) { return { isKilling: item.system.killing, d6Count, - halfDieCount, + halfDieCount: usesDieLessOne ? 0 : halfDieCount, + d6Less1DieCount: usesDieLessOne ? halfDieCount : 0, constant, }; } -// TODO: Consider removing this as it's primarily for old behaviour as 1d3 is not the same as a 1/2d6 when counting BODY for a normal attack. export function convertFromDC(item, DC) { - if (DC === 0) { - return ""; - } - - let output = ""; - const formulaParts = calculateDiceFormulaParts(item, DC); - if (formulaParts.d6Count !== 0) { - output = addTerms(output, formulaParts.d6Count.toString() + "d6"); - } - - if (formulaParts.halfDieCount !== 0) { - output = addTerms(output, formulaParts.halfDieCount.toString() + "d3"); - } - - if (formulaParts.constant !== 0) { - output = addTerms(output, formulaParts.constant); - } - - return output; -} - -export function addTerms(term1, term2) { - function isValid(term) { - return term !== "" && term !== null; - } - - let output = isValid(term1) ? term1 : ""; - - if (isValid(term1) && isValid(term2)) { - output += " + "; - } - - if (isValid(term2)) { - output += term2; - } - - return output; + return `${ + formulaParts.d6Count + + formulaParts.d6Less1DieCount + + formulaParts.halfDieCount > + 0 + ? `${ + formulaParts.d6Count + formulaParts.d6Less1DieCount + ? `${formulaParts.d6Count + formulaParts.d6Less1DieCount}` + : "" + }${formulaParts.halfDieCount ? `½` : ""}d6` + : "" + }${ + formulaParts.constant + ? formulaParts.d6Count + + formulaParts.d6Less1DieCount + + formulaParts.halfDieCount > + 0 + ? "+1" + : "1" + : `${formulaParts.d6Less1DieCount > 0 ? "-1" : ""}` + }`; } export function CombatSkillLevelsForAttack(item) { From c8ea9ac729923d89c85b392c0ca72ca0e3b269dc Mon Sep 17 00:00:00 2001 From: phBalance Date: Fri, 23 Feb 2024 21:25:56 -0700 Subject: [PATCH 5/9] fix(damage): apply 1d6-1 damage terms to rolls --- module/item/item-attack.js | 1 + 1 file changed, 1 insertion(+) diff --git a/module/item/item-attack.js b/module/item/item-attack.js index a0d54f21..e958cf98 100644 --- a/module/item/item-attack.js +++ b/module/item/item-attack.js @@ -1045,6 +1045,7 @@ export async function _onRollDamage(event) { ) .addDice(formulaParts.d6Count) .addHalfDice(formulaParts.halfDieCount) + .addDiceMinus1(formulaParts.d6Less1DieCount) .addNumber(formulaParts.constant) .modifyToStandardEffect(useStandardEffect) .modifyToNoBody( From 8d488b9c36dce9104bddef7edd7cc344d6380f9a Mon Sep 17 00:00:00 2001 From: phBalance Date: Fri, 23 Feb 2024 21:36:05 -0700 Subject: [PATCH 6/9] fix(convertFromDC): no longer requires post processing of formulas --- module/actor/actor-sheet.js | 2 +- module/item/item.js | 49 +++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/module/actor/actor-sheet.js b/module/actor/actor-sheet.js index d22f29d2..3e8cb077 100644 --- a/module/actor/actor-sheet.js +++ b/module/actor/actor-sheet.js @@ -140,7 +140,7 @@ export class HeroSystemActorSheet extends ActorSheet { ); // text description of damage - item.system.damage = convertFromDC(item, dc).replace(/ /g, ""); + item.system.damage = convertFromDC(item, dc); // Standard Effect if (item.system.USESTANDARDEFFECT) { diff --git a/module/item/item.js b/module/item/item.js index fb79cac3..25177cd9 100644 --- a/module/item/item.js +++ b/module/item/item.js @@ -1867,11 +1867,11 @@ export class HeroSystem6eItem extends Item { case "MINDSCAN": { - const dice = convertFromDC( + const diceFormula = convertFromDC( this, convertToDcFromItem(this).dc, - ).replace("d6 + 1d3", " 1/2d6"); - system.description = `${dice} ${system.ALIAS}`; + ); + system.description = `${diceFormula} ${system.ALIAS}`; } break; @@ -1926,13 +1926,13 @@ export class HeroSystem6eItem extends Item { { const reduceAndEnhanceTargets = this.splitAdjustmentSourceAndTarget(); - const dice = convertFromDC( + const diceFormula = convertFromDC( this, convertToDcFromItem(this).dc, - ).replace("d6 + 1d3", " 1/2d6"); + ); system.description = `${system.ALIAS} ${ - is5e ? `${dice}` : `${system.value} BODY` + is5e ? `${diceFormula}` : `${system.value} BODY` } (${system.OPTION_ALIAS}) to ${ reduceAndEnhanceTargets.valid ? reduceAndEnhanceTargets.enhances || @@ -1950,17 +1950,17 @@ export class HeroSystem6eItem extends Item { { const reduceAndEnhanceTargets = this.splitAdjustmentSourceAndTarget(); - const dice = convertFromDC( + const diceFormula = convertFromDC( this, convertToDcFromItem(this).dc, - ).replace("d6 + 1d3", " 1/2d6"); + ); system.description = `${system.ALIAS} ${ reduceAndEnhanceTargets.valid ? reduceAndEnhanceTargets.enhances || reduceAndEnhanceTargets.reduces : "unknown" - } ${dice}`; + } ${diceFormula}`; } break; @@ -1968,12 +1968,12 @@ export class HeroSystem6eItem extends Item { { const reduceAndEnhanceTargets = this.splitAdjustmentSourceAndTarget(); - const dice = convertFromDC( + const diceFormula = convertFromDC( this, convertToDcFromItem(this).dc, - ).replace("d6 + 1d3", " 1/2d6"); + ); - system.description = `${system.ALIAS} ${dice} from ${ + system.description = `${system.ALIAS} ${diceFormula} from ${ reduceAndEnhanceTargets.valid ? reduceAndEnhanceTargets.reduces : "unknown" @@ -2121,11 +2121,11 @@ export class HeroSystem6eItem extends Item { case "MINDCONTROL": case "HANDTOHANDATTACK": { - const dice = convertFromDC( + const diceFormula = convertFromDC( this, convertToDcFromItem(this).dc, - ).replace("d6 + 1d3", " 1/2d6"); - system.description = `${system.ALIAS} ${dice}`; + ); + system.description = `${system.ALIAS} ${diceFormula}`; } break; @@ -2180,8 +2180,8 @@ export class HeroSystem6eItem extends Item { if (system.EFFECT) { let dc = convertToDcFromItem(this).dc; if (dc) { - let damageDice = convertFromDC(this, dc); - if (damageDice) { + const damageDiceFormula = convertFromDC(this, dc); + if (damageDiceFormula) { system.description += `,`; if ( @@ -2192,11 +2192,8 @@ export class HeroSystem6eItem extends Item { } system.description += ` ${system.EFFECT.replace( "[NORMALDC]", - damageDice, - ).replace( - "[KILLINGDC]", - damageDice.replace("+ 1", "+1"), - )}`; + damageDiceFormula, + ).replace("[KILLINGDC]", damageDiceFormula)}`; } } else { system.description += ", " + system.EFFECT; @@ -2286,7 +2283,7 @@ export class HeroSystem6eItem extends Item { } // singles - let _singles = []; + const _singles = []; for (let addr of (system.ADDER || []).filter( (o) => o.XMLID.indexOf("GROUP") === -1 && @@ -2304,11 +2301,11 @@ export class HeroSystem6eItem extends Item { system.description += " and " + _singles.slice(-1); } - const dice = convertFromDC( + const diceFormula = convertFromDC( this, convertToDcFromItem(this).dc, - ).replace("d6 + 1d3", " 1/2d6"); - system.description += ` ${system.ALIAS} ${dice}`; + ); + system.description += ` ${system.ALIAS} ${diceFormula}`; } break; From 18d5a3236761ff7ccef434cc2589692e6394ff05 Mon Sep 17 00:00:00 2001 From: phBalance Date: Fri, 23 Feb 2024 21:55:28 -0700 Subject: [PATCH 7/9] fix(description): don't show +1 pip, +1/2d6 or +1d6-1 as modifiers --- module/item/item.js | 5 ++++- module/testing/testing-upload.js | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/module/item/item.js b/module/item/item.js index 25177cd9..7a4632ea 100644 --- a/module/item/item.js +++ b/module/item/item.js @@ -2475,8 +2475,10 @@ export class HeroSystem6eItem extends Item { } break; + case "PLUSONEPIP": + case "MINUSONEPIP": case "PLUSONEHALFDIE": - //system.description = system.description.replace(/d6$/, " ") + adder.ALIAS.replace("+", "").replace(" ", ""); + // Don't show the +1, 1/2d6, 1d6-1 modifier as it's already included in the description's dice formula break; case "COMMONMOTORIZED": @@ -3190,6 +3192,7 @@ export class HeroSystem6eItem extends Item { this.buildAoeAttackParameters(aoeModifier); } + // TODO: Investigate why this is required. It is wrong for 1/2d6 vs d6-1. if (xmlid === "HKA" || this.system.EFFECT?.indexOf("KILLING") > -1) { this.system.killing = true; diff --git a/module/testing/testing-upload.js b/module/testing/testing-upload.js index c230232b..55dc97bd 100644 --- a/module/testing/testing-upload.js +++ b/module/testing/testing-upload.js @@ -1329,7 +1329,7 @@ export function registerUploadTests(quench) { it("description", function () { assert.equal( item.system.description, - "Killing Attack - Ranged 2d6-1 (ED; +1d6 -1)", + "Killing Attack - Ranged 2d6-1 (ED)", ); }); @@ -3046,7 +3046,7 @@ export function registerUploadTests(quench) { it("description", function () { assert.equal( item.system.description, - "1d6+1 Mind Scan (Animal; +1 pip; +9 OMCV; Additional Class Of Minds; Additional Class Of Minds; Additional Class Of Minds), Cumulative (+1/2) (60 Active Points); Cannot Attack Through Link (neither the character nor his target can use the link to attack each other mentally, but they can communicate; -1/2)", + "1d6+1 Mind Scan (Animal; +9 OMCV; Additional Class Of Minds; Additional Class Of Minds; Additional Class Of Minds), Cumulative (+1/2) (60 Active Points); Cannot Attack Through Link (neither the character nor his target can use the link to attack each other mentally, but they can communicate; -1/2)", ); }); @@ -3910,7 +3910,7 @@ export function registerUploadTests(quench) { it("description", function () { assert.equal( item.system.description, - "Aid CON 3d6+1 (+1 pip; Increased Maximum (+8 points) (27 total points)), Continuous (+1) (74 Active Points); Crew-Served (2 people; -1/4)", + "Aid CON 3d6+1 (Increased Maximum (+8 points) (27 total points)), Continuous (+1) (74 Active Points); Crew-Served (2 people; -1/4)", ); }); From 694e9ace74e463f5156edbb610921a95a9e41be3 Mon Sep 17 00:00:00 2001 From: phBalance Date: Fri, 23 Feb 2024 21:59:51 -0700 Subject: [PATCH 8/9] fix(standard effect): support 1d6-1 --- module/actor/actor-sheet.js | 1 + module/item/item.js | 1 + 2 files changed, 2 insertions(+) diff --git a/module/actor/actor-sheet.js b/module/actor/actor-sheet.js index 3e8cb077..74ded163 100644 --- a/module/actor/actor-sheet.js +++ b/module/actor/actor-sheet.js @@ -147,6 +147,7 @@ export class HeroSystemActorSheet extends ActorSheet { let stun = parseInt(item.system.value * 3); if ( item.findModsByXmlid("PLUSONEHALFDIE") || + item.findModsByXmlid("MINUSONEPIP") || item.findModsByXmlid("PLUSONEPIP") ) { stun += 1; diff --git a/module/item/item.js b/module/item/item.js index 7a4632ea..23529625 100644 --- a/module/item/item.js +++ b/module/item/item.js @@ -2592,6 +2592,7 @@ export class HeroSystem6eItem extends Item { if ( this.findModsByXmlid("PLUSONEHALFDIE") || + this.findModsByXmlid("MINUSONEPIP") || this.findModsByXmlid("PLUSONEPIP") ) { stun += 1; From f118c54468f1df2e03aab9e8e7c65e2ed1b8b0d4 Mon Sep 17 00:00:00 2001 From: phBalance Date: Fri, 23 Feb 2024 22:07:58 -0700 Subject: [PATCH 9/9] docs(changelog): support for 1d6-1 damage adder --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 376a0d62..6b784df6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Implement basic automatic absorption. - Fix combat tracker where changing combatant SPD caused issues. Initiative is now DEX.SPD instead of DEX.INT. [#736](https://github.com/dmdorman/hero6e-foundryvtt/issues/736) - Adjustment powers now prefer characteristics over powers with the same name. [#747](https://github.com/dmdorman/hero6e-foundryvtt/issues/747) +- Add support for the 1d6-1 damage adder. ## Version 3.0.58