From 94e36d302894de95551cb5f70bd2b229ba9d280b Mon Sep 17 00:00:00 2001 From: Brett Nash Date: Mon, 31 Mar 2025 21:04:12 -0700 Subject: [PATCH] RolemasterUnified: Where i hunt bugs and wolves - Fix for the stat abbrievations used in skill summaries - Add test too - Spell message nits: - Remove the trailing . in the PP message - Fix unbalanced brace in message for grace - Uses; clear per level count on level up - Skills: - forEachSkill has a completion callback - Remove old (unused) purchase module - Was used before we had Compendium integration. - Generate default tokens for creatures - Incorporate talents in talen file for Creature law. --- .../rolemasterunified.html | 151 +++++++++++++----- RolemasterUnified_Official/sheet.json | 2 +- RolemasterUnified_Official/updates.md | 12 ++ 3 files changed, 123 insertions(+), 42 deletions(-) diff --git a/RolemasterUnified_Official/rolemasterunified.html b/RolemasterUnified_Official/rolemasterunified.html index 28ed923776..8dd45e1187 100644 --- a/RolemasterUnified_Official/rolemasterunified.html +++ b/RolemasterUnified_Official/rolemasterunified.html @@ -5716,7 +5716,7 @@ Sheet Version:
-Revision 86a2b8652cc8f655eb565f1d85085bac9a1ade4e +Revision ceec0b05fe360cc519d2ffba9e5f0dcdc8b5d16c
@@ -5752,35 +5752,6 @@ function cherror(message) { } } -const StatInfo = [ - { display: "Agility", aname: "agility", attr: "ag", will: false }, - { display: "Constitution", aname: "constitution", attr: "co", will: false }, - { display: "Empathy", aname: "empathy", attr: "em", will: true }, - { display: "Intuition", aname: "intuition", attr: "in", will: true }, - { display: "Memory", aname: "memory", attr: "me", will: true }, - { display: "Presence", aname: "presence", attr: "pr", will: true }, - { display: "Quickness", aname: "quickness", attr: "qu", will: false }, - { display: "Reasoning", aname: "reasoning", attr: "re", will: true }, - { display: "Self Discipline", aname: "selfdiscipline", attr: "sd", will: true }, - { display: "Strength", aname: "strength", attr: "st", will: false }, - -] - -function getStatNameFromAbbr(abbr) { - if (abbr == 'rs') { - return "Realm Stat"; - } - for (let i = 0 ; i < StatInfo.length ; i ++) { - if (StatInfo[i].abbr == abbr){ - // Use the translated version - return getTranslationByKey(StatInfo[i].aname); - } - } - console.log("Could not find stat " + abbr); - return null; -} - - function parseIntDefault(str, def) { if (typeof(str) == 'number') { @@ -7883,13 +7854,21 @@ function lookupSkillResult(skill, skillinfo, umroll, total) { // Each is called with skill structure and then the category // If the skill is a specialisation, a third argument is present - the // actual 'skill' - function forEachSkill(func) { + function forEachSkill(func, donefn) { + let catcount = categories.length + categories.forEach(cat => { - catForEachSkill(cat, func); + catForEachSkill(cat, func, () => { + catcount --; + if (catcount == 0) { + donefn(); + } + }); }); } RMUSkills.forEachSkill = forEachSkill; - function catForEachSkill(cat, func) { + function catForEachSkill(cat, func, donefn) { + let outstanding = 1; cat.skills.forEach(skill => { if (skill.specializations) { skill.specializations.forEach( @@ -7898,6 +7877,7 @@ function lookupSkillResult(skill, skillinfo, umroll, total) { } ); } else if (skill.dynamicspecializations) { + outstanding ++; getSectionIDs(`repeating_specialization${skill.aname}`, idarray => { for (const id of idarray) { @@ -7905,6 +7885,11 @@ function lookupSkillResult(skill, skillinfo, umroll, total) { let subskill = { aname: `repeating_specialization${skill.aname}_${id}` }; func(subskill, cat, skill) } + outstanding --; + console.log("for each", outstanding); + if (outstanding == 0 && donefn) { + donefn(); + } } ); } else { @@ -7912,6 +7897,10 @@ function lookupSkillResult(skill, skillinfo, umroll, total) { func(skill, cat); } }); + outstanding --; + if (outstanding == 0 && donefn) { + donefn(); + } } RMUSkills.catForEachSkill = catForEachSkill; @@ -8346,7 +8335,20 @@ RMUSkills.usesspecialisation = function(name, specialisation) { }); }); +} +/* */ +RMUSkills.usesClear = function() { + // Clear all the non-specialised ones + toclear = {} + RMUSkills.forEachSkill((subskill, cat, skill) => { + toclear[`${subskill.aname}_usecount`] = 0; + }, + () => { + console.log("to clear done", toclear); + setAttrs(toclear); + } + ); } @@ -8964,7 +8966,7 @@ onCheck(spellcastevents.join(" "), (ev) => { mlog += ` -0 [Overcast ${overcast} levels (${overpenalty} + ${grace} Grace (0 capped))]`; } else if (grace > 0) { const modified = overpenalty - grace; - mlog += ` -${modified} [Overcast ${overcast} levels ({${overpenalty} + ${grace} Grace)]` + mlog += ` -${modified} [Overcast ${overcast} levels (${overpenalty} + ${grace} Grace)]` mod -= modified; } else { // FIXME: add grace here @@ -9024,7 +9026,7 @@ onCheck(spellcastevents.join(" "), (ev) => { if (nopp) { ppmsg = 'No PP cost'; } else { - ppmsg = `${level} PP.`; + ppmsg = `${level} PP`; pp -= level; RMUSkills.uses('powerdevelopment'); } @@ -10270,6 +10272,7 @@ onCheck("mancerfinish:levelup", (ev) => { setAttrsPending(updates); }); }); + addPendingFunction("LevelupFinish: Clear Uses count", RMUSkills.usesClear); addPendingFunction("LevelupFinish: Front page", updateFrontPage); addPendingFunction("LevelupFinish: Finish cmancer (roll20)", finishCharactermancer) pendingInfo(); @@ -10329,8 +10332,6 @@ let RMUPurchase = {}; }); // Add a handler for each category, then each category add each of the skills - on('sheet:opened', () => { - categories.forEach(cat => { let skills = [] // FIXME: Subskills/specializations @@ -10364,7 +10365,6 @@ let RMUPurchase = {}; }); }); }); - }); on("clicked:completebuy", (ev) => { let level = `Level ${Math.floor(Math.random() * 50)}`; @@ -10396,6 +10396,10 @@ let RMUPurchase = {}; + + + + RMUStats = {} RMUStats.statnames = ["ag", "co", "em", "in", "me", "pr", "qu", "re", "sd", "st"]; @@ -10459,6 +10463,39 @@ RMUStats.statgainroll = function(temp, pot) { return gain; } + +const StatInfo = [ + { display: "Agility", aname: "agility", abbr: "Ag", attr: "ag", will: false }, + { display: "Constitution", aname: "constitution", abbr: "Co", attr: "co", will: false }, + { display: "Empathy", aname: "empathy", abbr: "Em", attr: "em", will: true }, + { display: "Intuition", aname: "intuition", abbr: "In", attr: "in", will: true }, + { display: "Memory", aname: "memory", abbr: "Me", attr: "me", will: true }, + { display: "Presence", aname: "presence", abbr: "Pr", attr: "pr", will: true }, + { display: "Quickness", aname: "quickness", abbr: "Qu", attr: "qu", will: false }, + { display: "Reasoning", aname: "reasoning", abbr: "Re", attr: "re", will: true }, + { display: "Self Discipline", aname: "selfdiscipline", abbr: "SD", attr: "sd", will: true }, + { display: "Strength", aname: "strength", abbr: "St", attr: "st", will: false }, + +] + +function getStatNameFromAbbr(abbr) { + if (abbr == 'rs') { + return "Realm Stat"; + } + for (let i = 0 ; i < StatInfo.length ; i ++) { + console.log(i, abbr, StatInfo[i].abbr); + if (StatInfo[i].attr == abbr.toLowerCase()){ + // Use the translated version + return getTranslationByKey(StatInfo[i].aname); + } + } + console.log("Could not find stat " + abbr); + return null; +} + + + + // Super async - takes name of stat. Respects pending // Shoukd be the fullname 'constitution'. // Does not update bonuses. @@ -13747,6 +13784,30 @@ function sizeFromNumeric(value) { /* 100 */ { location: "Head", armorlocation: 2, rollindex: 19, down: 81 }, ]; + const downByIndex = [ + /* 0 */ 0, + /* 1 */ 1, + /* 2 */ 1, + /* 3 */ 1, + /* 4 */ 1, + /* 5 */ 1, + /* 6 */ 1, + /* 7 */ 2, + /* 8 */ 3, + /* 9 */ 4, + /* 10 */ 9, + /* 11 */ 7, + /* 12 */ 8, + /* 13 */ 6, + /* 14 */ 5, + /* 15 */ 10, + /* 16 */ 12, + /* 17 */ 11, + /* 18 */ 13, + /* 19 */ 14, + ]; + + /* Returns an obj of location, side, at */ attacks.getLocation = function(roll) { if (typeof(roll) != 'Number') { @@ -13778,8 +13839,7 @@ function sizeFromNumeric(value) { attacks.resolveCriticalList = function(critlist, index, donfn) { const allresults = [] - for (const {sev, type} of critlist) { - console.log("iter", sev, type); + for (const {sev, type, origsev} of critlist) { let sevcode = numericToCritCode(sev); const crit = attacks.knownCrits[type][index] const results = {} @@ -13815,6 +13875,13 @@ function sizeFromNumeric(value) { */ attacks.getCritical = function(severity, type, index, overflow, additional, donefn) { const crits = []; + let origsev = severity; + + while (severity < 0) { + index = downByIndex[index]; + severity ++; + } + // Move to known sizes: if (severity > 4) { crits.push({ sev: 4, type: type }); // Start with an E, then append some @@ -13833,7 +13900,8 @@ function sizeFromNumeric(value) { } console.log(crits); } else { - crits.push({ sev: severity, type: type }); // Start with an E, then append some + // We only use origsev here; + crits.push({ sev: severity, type: type, origsev: origsev }); // Start with an E, then append some } if (type.length > 1) { @@ -14099,6 +14167,7 @@ function sizeFromNumeric(value) { } // If we are less than 'A'/1 walk index down + // FIXME: This is now handled by resolve crit - should use that instead. if (critinfo.severitynumeric < 0) { let sev = critinfo.severitynumeric; // hit.roll contains the sanitised roll (1-100) diff --git a/RolemasterUnified_Official/sheet.json b/RolemasterUnified_Official/sheet.json index 4a2a26a2ba..2dff7275df 100644 --- a/RolemasterUnified_Official/sheet.json +++ b/RolemasterUnified_Official/sheet.json @@ -19,5 +19,5 @@ "descriptiontranslationkey": "DefaultCurrency" } ], - "version": "1742883768" + "version": "1743481215" } diff --git a/RolemasterUnified_Official/updates.md b/RolemasterUnified_Official/updates.md index 16533e147f..5dab9f92ba 100644 --- a/RolemasterUnified_Official/updates.md +++ b/RolemasterUnified_Official/updates.md @@ -1,3 +1,14 @@ +# 2025-4-1 + +- Fix for the stat abbrievations used in skill summaries + - Add test too +- Spell message nits: + - Remove the trailing . in the PP message + - Fix unbalanced brace in message for grace +- Uses; clear per level count on level up +- Skills: + - forEachSkill has a completion callback + # 2025-3-25 - Tracker now shows skills correctly. @@ -12,6 +23,7 @@ - Casting a spell tickles a use of 'powerdevelopment' - Total uses >= Current uses (for new ones)t - Display correct global counter for uses. +- Roll/Lookup crit: Handle scaled crits a lot better. # 2025-3-18