From 497af235972a01cec770d23b65e910404b218679 Mon Sep 17 00:00:00 2001 From: Brett Nash Date: Wed, 25 Sep 2024 23:47:44 -0700 Subject: [PATCH] Rolemaster Official: DB, Creature and skill updates Start work on fully supporting encumbrance and maneuver penalties. So now we calculate load (we did not before), our max pace (been empty forever), change the property name to carried_weight (was set, but never used before). - Creatures: - Handle more attack types - Creature attacks work again with the new maneuver penalties. - Fix issue with creatures without skills failing - Update maxpace and load %s on sheet - Need to update equipment in the compendium to make this effective. - Add a dot to show skills you have a profession bonus in - Update DB: - Add passive block to active dodges and passive dodge to active block - Cap running ranks, not passive DB at 50. --- .../rolemasterunified.css | 3 + .../rolemasterunified.html | 323 +++++++++++------- RolemasterUnified_Official/sheet.json | 2 +- RolemasterUnified_Official/updates.md | 19 +- 4 files changed, 214 insertions(+), 133 deletions(-) diff --git a/RolemasterUnified_Official/rolemasterunified.css b/RolemasterUnified_Official/rolemasterunified.css index ef73d7951a..e672a07162 100644 --- a/RolemasterUnified_Official/rolemasterunified.css +++ b/RolemasterUnified_Official/rolemasterunified.css @@ -853,6 +853,9 @@ button.nodie { .hidenext[value='0'] + * { display: none; } +.hidenext:not([value]) + * { + display: none; +} /* Small attributes: two columns of two items */ .smallattrs { diff --git a/RolemasterUnified_Official/rolemasterunified.html b/RolemasterUnified_Official/rolemasterunified.html index 5c8c3eda60..c11ad70e00 100644 --- a/RolemasterUnified_Official/rolemasterunified.html +++ b/RolemasterUnified_Official/rolemasterunified.html @@ -2565,7 +2565,7 @@ Name
ProfessionRaceLevelCultureRealmReligionAgeSkinEyesHairGenderBuildHeightWeightyWeight allowance -CarriedEnc PenaltyMax PaceyBase Move (BMR) +CarriedLoad (%)Max PaceEnc PenaltyyBase Move (BMR) SizeRecovery MultiplierRoutineEasyLightMediumHardVery HardExt. HardSheer FollyAbsurdNigh Impossible EP @@ -3124,7 +3124,7 @@ Name ag + em
y - Animal Handlingpr + Animal Handling •pr
@@ -3139,7 +3139,7 @@ Name
y - Ridingpr + Riding •pr
@@ -3162,14 +3162,14 @@ Name
- Perceptionsd + Perception •sd
y
- Trackingsd + Tracking •sd
@@ -3183,35 +3183,35 @@ Name
- Maneuvering in Armor + Maneuvering in Armor •
y
- Mounted Combat + Mounted Combat •
y
- Protect + Protect •
y
- Restricted Quarters + Restricted Quarters •
y
- Subduing + Subduing •
@@ -3225,28 +3225,28 @@ Name
- Adrenal Defenseag + Adrenal Defense •ag
y
- Adrenal Focussd + Adrenal Focus •sd
y
- Adrenal Speedqu + Adrenal Speed •qu
y
- Adrenal Strengthst + Adrenal Strength •st
@@ -3260,21 +3260,21 @@ Name
- Body Developmentco + Body Development •co
y
- Fortitudesd + Fortitude •sd
y
- Weight-trainingst + Weight-training •st
@@ -3288,35 +3288,35 @@ Name
- Blind Fighting + Blind Fighting •
y
- Disarm + Disarm •
y
- Footwork + Footwork •
y
- Multiple Attacks + Multiple Attacks •
y
- Reverse Strike + Reverse Strike •
@@ -3329,7 +3329,7 @@ Name ag + st
y - Melee Weaponsst + Melee Weapons •st
@@ -3391,7 +3391,7 @@ Name
y
y - Ranged Weaponsag + Ranged Weapons •ag
@@ -3433,13 +3433,13 @@ Name
y
- Shieldst + Shield •st
y
y - Unarmed + Unarmed •
@@ -3523,21 +3523,21 @@ Name
- Illusion Craftingpr + Illusion Crafting •pr
y
- Musical Compositionpr + Musical Composition •pr
y
- Writingre + Writing •re
@@ -3551,49 +3551,49 @@ Name
- Culinarysd + Culinary •sd
y
- Drawing/Paintingin + Drawing/Painting •in
y
- Fabric Craftsd + Fabric Craft •sd
y
- Leathercraftsd + Leathercraft •sd
y
- Metalcraftst + Metalcraft •st
y
- Stonecraftst + Stonecraft •st
y
- Woodcraftsd + Woodcraft •sd
@@ -3607,14 +3607,14 @@ Name
- Attunementpr + Attunement •pr
y
- Runespr + Runes •pr
@@ -3628,13 +3628,13 @@ Name
- Navigationre + Navigation •re
y
y - Pilotingag + Piloting •ag
@@ -3649,7 +3649,7 @@ Name
y - Survivalre + Survival •re
@@ -3761,21 +3761,21 @@ Name
- Acrobaticsst + Acrobatics •st
y
- Contortionssd + Contortions •sd
y
- Jumpingst + Jumping •st
@@ -3788,7 +3788,7 @@ Name me + me
y - Creature Lorere + Creature Lore •re
@@ -3822,7 +3822,7 @@ Name
y
y - Historic Lorere + Historic Lore •re
@@ -3837,7 +3837,7 @@ Name
y - Languagere + Language •re
@@ -3852,7 +3852,7 @@ Name
y - Materials Lorere + Materials Lore •re
@@ -3900,7 +3900,7 @@ Name
y
y - Racial Lorere + Racial Lore •re
@@ -3915,7 +3915,7 @@ Name
y - Region Lorere + Region Lore •re
@@ -3930,7 +3930,7 @@ Name
y - Religion/Philosophyre + Religion/Philosophy •re
@@ -3946,7 +3946,7 @@ Name
- Spell Lorein + Spell Lore •in
@@ -3959,7 +3959,7 @@ Name
y - Grace + Grace •
@@ -3974,7 +3974,7 @@ Name
y - Spell Trickery + Spell Trickery •
@@ -3990,7 +3990,7 @@ Name
- Transcendence + Transcendence •
@@ -4004,21 +4004,21 @@ Name
- Herbalismre + Herbalism •re
y
- Medicinere + Medicine •re
y
- Poison Masteryre + Poison Mastery •re
@@ -4032,21 +4032,21 @@ Name
- Control Lycanthropysd + Control Lycanthropy •sd
y
- Meditationsd + Meditation •sd
y
- Mental Focussd + Mental Focus •sd
@@ -4060,28 +4060,28 @@ Name
- Climbingco + Climbing •co
y
- Flyingco + Flying •co
y
- Runningco + Running •co
y
- Swimmingco + Swimming •co
@@ -4095,13 +4095,13 @@ Name
- Actingme + Acting •me
y
y - Musicme + Music •me
@@ -4117,7 +4117,7 @@ Name
- Stage Magicag + Stage Magic •ag
@@ -4131,13 +4131,13 @@ Name
- Channelingsd + Channeling •sd
y
y - Directed Spellag + Directed Spell •ag
@@ -4165,14 +4165,14 @@ Name
y
- Power Developmentco + Power Development •co
y
- Power Projectionsd + Power Projection •sd
@@ -4186,28 +4186,28 @@ Name
- Architecturere + Architecture •re
y
- Astronomyre + Astronomy •re
y
- Engineeringre + Engineering •re
y
- Mathematicsre + Mathematics •re
@@ -4220,7 +4220,7 @@ Name em + in
y - Influencepr + Influence •pr
@@ -4248,21 +4248,21 @@ Name
y
- Leadershippr + Leadership •pr
y
- Social Awarenessem + Social Awareness •em
y
- Tradingpr + Trading •pr
@@ -4275,7 +4275,7 @@ Name rs + rs
y - Magical Ritualme + Magical Ritual •me
@@ -4344,7 +4344,7 @@ Name ag + sd
y - Ambushin + Ambush •in
@@ -4386,21 +4386,21 @@ Name
y
- Concealmentin + Concealment •in
y
- Stalkingin + Stalking •in
y
- Trickeryin + Trickery •in
@@ -4414,13 +4414,13 @@ Name
- Locksag + Locks •ag
y
y - Mechanicsme + Mechanics •me
@@ -4441,7 +4441,7 @@ Name
y
- Trapsag + Traps •ag
@@ -4454,7 +4454,7 @@ Name em + me
y - Administrationre + Administration •re
@@ -4502,7 +4502,7 @@ Name
y
y - Servicepr + Service •pr
@@ -4585,7 +4585,7 @@ Name
y
y - Tradere + Trade •re
@@ -5250,7 +5250,9 @@ Name

Total Weight:
Weight Allowance:
- Maneuver Penalty: + Maneuver Penalty:
+ Spell Casting Armor Enc%
+ Spell Casting Metal Armor Enc%

@@ -5425,7 +5427,7 @@ Sheet Version:
-Revision 8b3fd579b9e41d3234142bceeb198bd40759656d +Revision 7b7bb63553cea990739155d94413260b731a34d0
@@ -11079,9 +11081,12 @@ frontpage.updateDB = function () { updates.db_qu = basedb; - const runningranks = parseIntDefault(ev.running_ranks, 0); + const runningranks = Math.min(parseIntDefault(ev.running_ranks, 0), 50); const passivedodgebonus = Math.max(0, runningranks + encump); const passivedodgebonusmissile = Math.floor(passivedodgebonus / 2); + const shield_ranks = Math.max(0, parseIntDefault(ev.shield_ranks, 0)); + const shielddb = parseIntDefault(ev.shield_type_bonus, 0); + const passiveblockbonus = Math.min(50, shielddb + shield_ranks) updates.db_passivedodge = basedb + passivedodgebonus; updates.db_passivedodgemissile = basedb + passivedodgebonusmissile; { @@ -11089,7 +11094,7 @@ frontpage.updateDB = function () { updates.db_passivedodge_info = "Passive Dodge\n" + `${F(basedb)} Base DB\n` + `${F(passivedodgebonus)} Passive Dodge\n` + - ` ${F(runningranks)} Running Ranks\n` + + ` ${F(runningranks)} Running Ranks (Max 50)\n` + ` ${F(encump)} Encumberance penalty\n` + `${F(updates.db_passivedodge)}\n\n` + "Passive Dodge vs Missile\n" + @@ -11098,14 +11103,11 @@ frontpage.updateDB = function () { ` ${F(runningranks)} Running Ranks\n` + ` ${F(encump)} Encumberance penalty\n` + `${T(updates.db_passivedodgemissile)}`; - // FIXME: This message could be in the middle of the text. if (updates.db_passivedodge > 50) { updates.db_passivedodge = 50; updates.db_passivedoge_info += "\nCapped at 50"; } } - const shield_ranks = parseIntDefault(ev.shield_ranks || "0", 0); - const shielddb = parseIntDefault(ev.shield_type_bonus, 0); const running_bonus = +ev.running_bonus; { @@ -11153,32 +11155,29 @@ frontpage.updateDB = function () { { - const shield_ranks = Math.max(0, parseIntDefault(ev.shield_ranks, 0)); - updates.db_passiveblock = basedb + shielddb + shield_ranks; + updates.db_passiveblock = basedb + passiveblockbonus; updates.db_passiveblock_info = "Passive Block\n" + `${F(basedb)} Base DB\n` + `${F(shielddb)} Shield DB\n` + `${F(shield_ranks)} Shield Ranks`; - if (updates.db_passiveblock > 50) { - updates.db_passiveblock = 50; - updates.db_passiveblock_info += "\nCapped at 50"; - } } const shield_bonus = ev.shield_bonus; { const sb2 = Math.floor(shield_bonus / 2); - updates.db_partialblock = basedb + shielddb + Math.max(0, shield_bonus) + passivedodgebonus; + updates.db_partialblock = basedb + shielddb + runningranks + Math.max(0, shield_bonus) + passivedodgebonus; updates.db_partialblock_info = "Partial Block\n" + `${F(basedb)} Base DB\n` + + `${F(runningranks)} Passive dodge\n` + `${F(shielddb)} Shield DB\n` + `${F(shield_bonus)} Shield bonus x ½ (min 0)\n` + `${F(passivedodgebonus)} Passive Dodge`; } { - updates.db_fullblock = basedb + shielddb + Math.max(0, shield_bonus) + passivedodgebonus; + updates.db_fullblock = basedb + shielddb + runningranks + Math.max(0, shield_bonus) + passivedodgebonus; updates.db_fullblock_info = "Full Block\n" + `${F(basedb)} Base DB\n` + + `${F(runningranks)} Passive dodge\n` + `${F(shielddb)} Shield DB\n` + `${F(shield_bonus)} Shield bonus (min 0)\n` + `${F(passivedodgebonus)} Passive Dodge`; @@ -11334,51 +11333,100 @@ let RMUInventory = {} VrmuSetAttrs(update); } + // Returns as { multiplier, maxpace } + RMUInventory.getMaxPace = function(load) { + if (load > 90) { + // What the hell are you doing + return { multiplier: 0.5, maxpace: "Crawl" }; + } else if (load > 60) { + return { multiplier: 1, maxpace: "Walk" }; + } else if (load > 45) { + return { multiplier: 2, maxpace: "Jog" }; + } else if (load > 30) { + return { multiplier: 3, maxpace: "Run" }; + } else if (load > 15) { + return { multiplier: 4, maxpace: "Sprint" }; + } else { + return { multiplier: 5, maxpace: "Dash" }; + } + } + /* Stuff we care about for Weight / Encumberance purposes - weight - count - system - equipped + + Based on gear we need to calculate our weightcarried. + + From this: + - deadload -> % of carried based on gear + - totalload -> % carried including inventory + - maxpace -> based on totalload + - encumberance_penalty + */ const events = [ "itemweight", "itemcount", "itemsystem", "itemequipped" ]; const weight_event_list = events.map( (str) => `change:repeating_stuff:${str}`).join(" "); RMUInventory.updateEncumberance = function() { - getSectionIDs(`repeating_stuff`, ids => { + getSectionIDs("repeating_stuff", ids => { let toget = ['weightallowance', 'weight']; ids.forEach(id => { toget.push(`repeating_stuff_${id}_itemweight`); toget.push(`repeating_stuff_${id}_itemcount`); toget.push(`repeating_stuff_${id}_itemequipped`); + toget.push(`repeating_stuff_${id}_itemmaterial`); }); getAttrsPending(toget, (stuff) => { - let encum = 0; + console.log(stuff); + let carried = 0; let chweight = parseIntDefault(stuff.weight, 200); let chwa = parseIntDefault(stuff.weightallowance, 10); + let enc = 0; + let encmetal = 0; ids.forEach(id => { const weightstr = stuff[`repeating_stuff_${id}_itemweight`] || ""; let weight = 0; if (typeof(weightstr) == 'string' && weightstr.endsWith('%')) { - let weightp = parseIntDefault(weightstr.match(/\d+/)[0],0); - weight = Math.floor(weightp * chweight / 100); + let weightp = parseIntDefault(weightstr.match(/\d+/)[0],0); + weight = Math.floor(weightp * chweight / 100); + enc += weightp; + if (stuff[`repeating_stuff_${id}_itemmaterial`] == 'metal') { + encmetal += weightp; + } } else { weight = parseNumberDefault(weightstr, 0); } const count = parseIntDefault(stuff[`repeating_stuff_${id}_itemcount`], 1); - encum += weight * count; + carried += weight * count; }); // Now round - encum = Math.floor(encum); - setAttrs({total_weight: encum}); - let weightincrements = Math.floor(encum / chwa); + carried = Math.floor(carried); + let updates = {}; + + // Start with load -> % carried based wieght. No modifiers + updates.load = Math.floor((carried / chweight) * 100); + console.log(`Carried: ${carried} ${chweight} ${updates.load}`); + // Get our Max Pace + const pace = RMUInventory.getMaxPace(updates.load); + updates.maxpace = pace.maxpace; + updates.armorenc = enc; + updates.armorencmetal = encmetal; + + // Old ones + setAttrs({total_weight: carried}); + let weightincrements = Math.floor(carried / chwa); if (weightincrements < 0) { setAttrs({encumberance_penalty: 0}); } else { // 5 for every weight increment basically setAttrs({encumberance_penalty: weightincrements * -5}); } + + setAttrsPending(updates); }); }); @@ -12613,6 +12661,7 @@ J E + C + B } attacks.startAttack = function(cdata) { + console.log("start attack", cdata); let attackmoddescription = ''; let attackmod = 0; @@ -13566,20 +13615,28 @@ weaponcodes = { ho: "Horn", ra: "Ram", sw: "Unarmed Sweeps", - un: "Unarmed Strikes", + un: "Unarmed Strike", si: "Stinger", tr: "Trample", + // FXIME: Hacky + we: "Arming Sword", + da: "Dagger", + rp: "Rapier", + as: "Arming Sword", + bs: "Broadsword", + sc: "Scimitar", + fa: "Falchion", + ma: "Mace", + cu: "Club", + sb: "Bow, Short", + lb: "Bow, Long", + + /* -Dagger da Short Sword ss -Rapier rp -Arming sword as Longsword ls -Broadsword bs -Scimitar sc Falchion fa Two-handed Sword ts -Mace ma Club cu Two-handed Club tc Shield sh @@ -13596,8 +13653,6 @@ Spear sp Halberd ha Pole Axe px Sling sl -Short Bow sb -Long Bow lb Light Crossbow lc Heavy Crossbow hc Bola bo @@ -13634,11 +13689,13 @@ Tongue wi So take a look, it's string, parse it as JSON. If an object, just return directly. */ -creature.parseJSONMaybe = function(jdata) { +creature.parseJSONMaybe = function(jdata, def) { if (typeof(jdata) == 'string') { return JSON.parse(jdata); - } else { + } else if (jdata) { return jdata; + } else { + return def; } } @@ -13747,9 +13804,7 @@ creature.newCreature = function(name, jdata) { updates[`${prefix}_type`] = type; } - console.log('move is', cdata['data-move']); - const moves = creature.parseJSONMaybe(cdata['data-move']); - + const moves = creature.parseJSONMaybe(cdata['data-move'], []); for (const { type, pace, bmr } of moves) { console.log("move", type, pace, bmr); const rowid = generateRowID(); @@ -13760,7 +13815,7 @@ creature.newCreature = function(name, jdata) { } // "data-skills": [ { "skill": "Running", "bonus": 43 } ], - const skills = creature.parseJSONMaybe(cdata['data-skills']) + const skills = creature.parseJSONMaybe(cdata['data-skills'], []) for (const { skill, bonus } of skills) { const rowid = generateRowID(); const prefix = `repeating_creatureskill_${rowid}`; @@ -13809,7 +13864,8 @@ onCheck('clicked:repeating_creatureattack:creaturemakeattack', (ev) => { 'target_at', 'target_size', 'target_crit', - + 'maneuver_penalty', + 'statuseffect', ]; getAttrs(toget, (values) => { console.log("Attack data", toget, values); @@ -13818,7 +13874,7 @@ onCheck('clicked:repeating_creatureattack:creaturemakeattack', (ev) => { cdata.max = +values[`${basename}_attackmax`]; cdata.fumblerange = +values[`${basename}_attackfumble`] || 1; cdata.character = values.character_name; - cdata.attackbonus = +values[`${basename}_ob`]; + cdata.attackbonus = parseIntDefault(values[`${basename}_ob`], 0); cdata.attackdata = values[`${basename}_attackdata`]; cdata.attacksize = sizeToNumeric(values[`${basename}_attacksize`] || 'M'); cdata.attackersize = sizeToNumeric(values.size || 'M'); @@ -13829,6 +13885,11 @@ onCheck('clicked:repeating_creatureattack:creaturemakeattack', (ev) => { cdata.targetdb = parseIntDefault(values.target_db, 0); cdata.targetsize = parseIntDefault(values.target_size, 5); cdata.targetcrit = parseIntDefault(values.target_crit, 0); + cdata.statuseffect = parseIntDefault(values.statuseffect, 0); + cdata.maneuver_penalty = parseIntDefault(values.maneuver_penalty, 0); + // FIXME: + cdata.parrymod = 0; + cdata.othermod = 0; console.log(cdata); attacks.startAttack(cdata); }); diff --git a/RolemasterUnified_Official/sheet.json b/RolemasterUnified_Official/sheet.json index 28ff7c11bd..c1cf42fb97 100644 --- a/RolemasterUnified_Official/sheet.json +++ b/RolemasterUnified_Official/sheet.json @@ -8,5 +8,5 @@ "legacy": false, "printable": true, "compendium": "RMU", - "version": "1727157576" + "version": "1727333132" } diff --git a/RolemasterUnified_Official/updates.md b/RolemasterUnified_Official/updates.md index 3106f0f41a..6cddd50c64 100644 --- a/RolemasterUnified_Official/updates.md +++ b/RolemasterUnified_Official/updates.md @@ -1,3 +1,20 @@ +# 2024-9-26 + +Start work on fully supporting encumbrance and maneuver penalties. So now we +calculate load (we did not before), our max pace (been empty forever), change +the property name to carried_weight (was set, but never used before). + +- Creatures: + - Handle more attack types + - Creature attacks work again with the new maneuver penalties. + - Fix issue with creatures without skills failing +- Update maxpace and load %s on sheet + - Need to update equipment in the compendium to make this effective. +- Add a dot to show skills you have a profession bonus in +- Update DB: + - Add passive block to active dodges and passive dodge to active block + - Cap running ranks, not passive DB at 50. + # 2024-9-24 A number of small updates this week. Starting some work to fix a mumber of other wierd bugs; but nothing yet. @@ -6,7 +23,7 @@ Thank you to all who have reported problems. Please let me know if there are mo - Dark mode tweaks for side panel, and the crit box. Dark mode is still a long way from complete on the main sheet; but the side panel should be usual. - Spell rank modifier when casting; missed that in the other massive improvements. -- Don't barf AP updates on New Combat. +- Don't barf AP updates on New Combat. - Fix for weight allowance (thanks spaturno80). I totally misread those rules. Like totally. - Creature sheet improvements for skills and other items. - Async: Recover is a few more wierd situations (thanks major__havoc).