diff --git a/RolemasterUnified_Official/rolemasterunified.html b/RolemasterUnified_Official/rolemasterunified.html
index e6619ee55e1..0c55409b6d8 100644
--- a/RolemasterUnified_Official/rolemasterunified.html
+++ b/RolemasterUnified_Official/rolemasterunified.html
@@ -2426,8 +2426,8 @@
Creature
- Maneuver Penalty:
-
+ Status Penalty:
+
@@ -2459,12 +2459,14 @@ Creature
Skills
+
+
+ name='act_creatureskillrollmod'>
- j
-
+ ,
@@ -2720,8 +2722,8 @@ Status
- Maneuver Penalty:
-
+ Status Penalty:
+
@@ -3150,6 +3152,12 @@ Talents
+
+
+
+ Manuever Penalty:
+
+
Skills
@@ -5111,6 +5119,9 @@
Carried
Pack
Store
+
+ p
#
@@ -5120,11 +5131,16 @@ Carried
- Total Weight:
- Weight Allowance:
- Maneuver Penalty:
- Spell Casting Armor Enc%
- Spell Casting Metal Armor Enc%
+
Total Weight:
+ Weight Allowance:
+
+ Encumberance Penalty:
+
+ Perception Penalty:
+
+ Ranged Penalty:
+ Spell Casting Armor Enc%
+ Spell Casting Metal Armor Enc%
Backpack
@@ -5358,7 +5374,7 @@ Custom Spell List
-Revision 0e32e4dbcd10426972eb1499037242f2c1e9fae3
+Revision 26977e485a7d748c3ae34fc47c676bfabc128473
@@ -5378,6 +5394,13 @@ Custom Spell List
}
}
+function rmuwarn(message) {
+ console.log("** Warning: ")
+ for (var i = 0; i < arguments.length; i++) {
+ console.log('>', arguments[i]);
+ }
+}
+
// Something character related is wrong
// Should surface to the user.
function cherror(message) {
@@ -6607,7 +6630,7 @@ Custom Spell List
}
asyncTimeout = setTimeout(checkPending, 500, item);
- console.log(`Calling pending ${item.name}`, item);
+ console.log(`>> Calling pending ${item.name}`, item);
try {
item.cb();
} catch (e) {
@@ -6996,6 +7019,15 @@ Custom Spell List
}
}
+ RMUSkills.updateSingleCategory = function(catname) {
+ const cat = getCatByDisplayName(catname)
+ if (!cat) {
+ rmuerror("Unable to find category", catname);
+ return;
+ }
+ updateCategory(cat, statCache_);
+ }
+
function updateSkill(skill, catbonus, catlog) {
const aname = skill.aname;
getAttrs([aname + "_ranks_misc", aname + "_pbonus", aname + "_misc", aname + "_ranks"], (attrs) => {
@@ -7271,7 +7303,7 @@ Custom Spell List
RMUSkills.startSkillRoll = function(prefix, usemod = false) {
getAttrs([
prefix + '_name', prefix + '_favskill', prefix + '_bonus',
- 'character_name', 'maneuver_penalty',
+ 'character_name', 'statuspenalty',
'statuseffect'],
(cdata) => {
const simplified = {};
@@ -7284,7 +7316,7 @@ Custom Spell List
}
}
if (!simplified.name) {
- // Look it up by anamee -> use the prefix
+ // Look it up by aname -> use the prefix
const skill = RMUSkills.getSkillByName(prefix);
if (skill) {
simplified.name = skill.fulldisplay ? skill.fulldisplay : skill.display;
@@ -7311,9 +7343,9 @@ Custom Spell List
let mlog = `${mod} [Skill Bonus]`
{
- const manp = parseIntDefault(cdata.maneuver_penalty, 0);
+ const manp = parseIntDefault(cdata.statuspenalty, 0);
if (manp < 0) {
- mlog += ` ${manp} [Maneuver Penalty]`;
+ mlog += ` ${manp} [Status Penalty]`;
mod += manp;
}
}
@@ -7445,7 +7477,6 @@ Custom Spell List
RMUSkills.startSkillRoll(basename, true);
});
-
onCheck(`clicked:repeating_specializationanimalhandling:rollskilldirect`, (ev) => {
const basename = ev.sourceAttribute.replace(/_rollskilldirect\d*$/, "");
RMUSkills.startSkillRoll(basename);
@@ -7597,6 +7628,19 @@ Custom Spell List
});
}
+onCheck("clicked:repeating_creatureskill:creatureskillroll", (ev) => {
+ const basename = ev.sourceAttribute.replace(/_creatureskillroll$/, "");
+ RMUSkills.startSkillRoll(basename, false);
+});
+
+onCheck("clicked:repeating_creatureskill:creatureskillrollmod", (ev) => {
+ const basename = ev.sourceAttribute.replace(/_creatureskillrollmod$/, "");
+ RMUSkills.startSkillRoll(basename, true);
+});
+
+
+
+
@@ -7614,27 +7658,57 @@ Custom Spell List
return;
}
+ // Looping though the lists we got.
for (let list of lists) {
- // Filter is currently on ListType
+ // Filter is currently on ListType - this filtesr out healer/layhealer
if (filter && filter.length > 0) {
if (list.data.ListType == filter) {
continue;
}
}
- addRepeatingSectionPending(`cmspelllistspell${subtarget}`, 'spelllist',
- `${subtarget}spelllist`,
- (sectionname) => {
- cmPopulateListOptions(`${sectionname}_cmranks`, costarray,
- prevranks[list.name] || costarray[0]);
- setAttrsPending({[`${sectionname}_listname`]: list.name,
- [`${sectionname}_listranks`]: listranks[list.name]?.ranks || '-'
- });
+ addRepeatingSectionPending(`cmspelllistspell${subtarget}`, 'spelllist', `${subtarget}spelllist`,
+ (sectionname) => {
+ cmPopulateListOptions(`${sectionname}_cmranks`, costarray,
+ prevranks[list.name] || costarray[0]);
+ setAttrsPending({[`${sectionname}_listname`]: list.name,
+ [`${sectionname}_listranks`]: listranks[list.name]?.ranks || '-'});
});
}
});
}
+
+// Base lists are different to other lists. No matter what we only show 6.
+// So do the query to get the base lists. Then we get the characters selected
+// base lists and display that.
+function _spellDoBaseListQuery(selectedbase, profession, cost, previousranks) {
+ const costarray = generateCostArray(cost);
+ var data = getCharmancerData();
+
+ if (selectedbase.length == 0) {
+ return;
+ }
+
+ for (let name in selectedbase) {
+ let details = selectedbase[name];
+ if (!details.prefix.match(/^repeating_spelllistspellownbase_/)) {
+ continue;
+ }
+
+ addRepeatingSectionPending("cmspelllistspellownbase", 'spelllist', "ownbasespelllist",
+ (sectionname) => {
+ cmPopulateListOptions(`${sectionname}_cmranks`, costarray,
+ previousranks[name] || costarray[0]);
+ setAttrsPending({[`${sectionname}_listname`]: name,
+ [`${sectionname}_listranks`]: details.ranks || '-'});
+ });
+ }
+}
+
+
+
+// Initialise the spell lists in the Charactermancer
// listranks is a dictionary of ranks indexed by the spell list name
function initSpellListsCM(savedlists, profession, realm, costs, listranks) {
const cmdata = getCharmancerData();
@@ -7663,17 +7737,17 @@ Custom Spell List
console.log("Pensing for base");
addPendingFunction("Base lists",()=> {
- _spellDoQuery(previousranks, `ListType:*${profession} Base*`, '', 'ownbase', costs['Base'], listranks);
+ _spellDoBaseListQuery(listranks, profession, costs.Base, previousranks);
});
if (realm.indexOf('/') > -1) {
// Hybrid: Two realms
realms = realm.split('/');
addPendingFunction("Hybrid realm 1 open lists",()=> {
- _spellDoQuery(previousranks, `ListType:*${realms[0]} Open*`, '', 'open', costs['Open'], listranks );
+ _spellDoQuery(previousranks, `ListType:*${realms[0]} Open*`, '', 'open', costs.Open, listranks );
});
addPendingFunction("Hybrid realm 2 open lists",()=> {
- _spellDoQuery(previousranks, `ListType:*${realms[1]} Open*`, '', 'open', costs['Open'], listranks );
+ _spellDoQuery(previousranks, `ListType:*${realms[1]} Open*`, '', 'open', costs.Open, listranks );
});
addPendingFunction("Hybid realm 1 closed lists",()=> {
_spellDoQuery(previousranks, `ListType:*${realms[0]} Closed*`, '', 'closed',
@@ -8058,7 +8132,7 @@ Custom Spell List
// AP
'castinguseap', 'aptrack_spell',
// Maneuver Penalty
- 'maneuver_penalty', 'statuseffect',
+ 'statuspenalty', 'statuseffect',
],
(spelldata) => {
console.log("Casting a spell", spelldata);
@@ -8127,9 +8201,9 @@ Custom Spell List
}
{
- const manp = parseIntDefault(spelldata.maneuver_penalty, 0);
+ const manp = parseIntDefault(spelldata.statuspenalty, 0);
if (manp < 0) {
- mlog += ` ${manp} [Maneuver Penalty]`;
+ mlog += ` ${manp} [Status Penalty]`;
mod += manp;
}
}
@@ -8760,40 +8834,9 @@ Custom Spell List
onCheck("mancerchange:cmskilloperationranks", changeSkillPurchase);
onCheck("mancerchange:cmskillrepairconstructionranks", changeSkillPurchase);
onCheck("mancerchange:cmskilltrapsranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillbookkeeperranks", changeSkillPurchase);
-onCheck("mancerchange:cmskilllibrarianranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillofficerranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillmanagerranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillquartermasterranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillseneschalranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillbodyguardranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillbonesetterranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillcasinodealercroupierranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillguardsmanranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillguideranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillinnkeeperranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillpurserranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillresearcherranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillshamanranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillteacherranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillvaletranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillblacksmithranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillcarpenterranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillfarmerranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillfenceranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillgamblerranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillherdsmanranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillhunterranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillmerchantranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillminerranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillpirateranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillsailorranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillscriberanks", changeSkillPurchase);
-onCheck("mancerchange:cmskillsoldierranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillthiefranks", changeSkillPurchase);
-onCheck("mancerchange:cmskilltinkerranks", changeSkillPurchase);
-onCheck("mancerchange:cmskilltrapperranks", changeSkillPurchase);
-onCheck("mancerchange:cmskillweaverranks", changeSkillPurchase);
+onCheck("mancerchange:repeating_cmskill_administration_specializations_cmskillranks", changeSkillPurchase);
+onCheck("mancerchange:repeating_cmskill_service_specializations_cmskillranks", changeSkillPurchase);
+onCheck("mancerchange:repeating_cmskill_trade_specializations_cmskillranks", changeSkillPurchase);
@@ -9186,7 +9229,7 @@ Custom Spell List
});
- // FIXME: THis is duplicated below. I hsould make it function
+ // FIXME: This is duplicated below. I hsould make it function
const listRanks = {};
{
const spellRanks = {}
@@ -9378,7 +9421,7 @@ Custom Spell List
{
const spellRanks = {}
const listIdsToGet = [];
- addPendingFunction('Levelup: Get Ranks for spells', () => {
+ addPendingFunction('LevelupFinish: Get Ranks for spells', () => {
// So two pieces here. Get all the lists with ranks. Put in an array indexed
// by spell name.
// FIXME: This is in RMUSkills.lua, should sync
@@ -10902,26 +10945,26 @@ Custom Spell List
// FIXME: This needs to die
RMUCultures.cultures = {
- reaver : { skills : {
- survival: '1', regionneighbour: '1', rangedweapons: '1', riding: '1', craftingvocation: '3', jumping: '1', perception: '1', bodydevelopment: '2', lores: '3', animalhandling: '1', maneuveringinarmor: '2', unarmed: '2', tracking: '1', running: '2', medicine: '1', stalking: '1', meleeweapons: '1', climbing: '1', regionown: '5', languages: '11', } },
- urban : { skills : {
- lores: '7', animalhandling: '1', unarmed: '1', trading: '2', running: '1', influence: '2', craftingvocation: '7', socialawareness: '2', compositionperf: '3', religionphilosophy: '1', perception: '2', bodydevelopment: '1', regionneighbour: '3', regionown: '5', languages: '17', } },
- highland : { skills : {
- survival: '2', craftingvocation: '4', jumping: '1', compositionperf: '1', perception: '1', bodydevelopment: '2', lores: '4', animalhandling: '1', maneuveringinarmor: '1', unarmed: '1', tracking: '1', running: '2', medicine: '1', stalking: '1', socialawareness: '1', swimming: '1', meleeweapons: '1', climbing: '1', regionown: '5', languages: '13', } },
cosmopolitan : { skills : {
- lores: '7', languages: '19', unarmed: '1', trading: '1', influence: '2', craftingvocation: '6', socialawareness: '3', compositionperf: '4', running: '1', perception: '2', bodydevelopment: '1', religionphilosophy: '2', regionneighbour: '2', regionown: '5', } },
- nomad : { skills : {
- survival: '1', regionneighbour: '2', riding: '3', craftingvocation: '4', navigation: '1', compositionperf: '1', perception: '1', bodydevelopment: '1', lores: '4', animalhandling: '4', herbalism: '1', unarmed: '1', tracking: '1', running: '2', medicine: '1', trading: '1', socialawareness: '1', regionown: '5', languages: '14', } },
- harsh : { skills : {
- survival: '3', languages: '8', maneuveringinarmor: '1', unarmed: '1', tracking: '1', stalking: '2', concealment: '1', craftingvocation: '4', navigation: '1', running: '2', medicine: '2', perception: '2', bodydevelopment: '3', lores: '2', regionown: '5', meleeweapons: '1', } },
+ languages: '19', perception: '2', trading: '1', regionown: '5', bodydevelopment: '1', influence: '2', regionneighbour: '2', socialawareness: '3', lores: '7', running: '1', unarmed: '1', religionphilosophy: '2', craftingvocation: '6', compositionperf: '4', } },
sylvan : { skills : {
- survival: '2', rangedweapons: '1', craftingvocation: '4', socialawareness: '1', perception: '1', bodydevelopment: '1', lores: '4', animalhandling: '2', herbalism: '1', unarmed: '1', tracking: '1', running: '2', medicine: '1', stalking: '2', concealment: '1', climbing: '2', regionown: '5', languages: '13', } },
+ tracking: '1', perception: '1', regionown: '5', herbalism: '1', animalhandling: '2', unarmed: '1', medicine: '1', concealment: '1', climbing: '2', bodydevelopment: '1', running: '2', stalking: '2', socialawareness: '1', lores: '4', languages: '13', survival: '2', craftingvocation: '4', rangedweapons: '1', } },
+ mariner : { skills : {
+ languages: '15', perception: '2', regionown: '5', navigation: '1', regionneighbour: '2', socialawareness: '1', lores: '5', unarmed: '1', medicine: '1', weighttraining: '1', climbing: '1', bodydevelopment: '1', swimming: '2', running: '1', trading: '1', acrobatics: '1', influence: '1', jumping: '1', survival: '1', craftingvocation: '4', compositionperf: '1', } },
+ urban : { skills : {
+ languages: '17', perception: '2', trading: '2', running: '1', regionown: '5', bodydevelopment: '1', influence: '2', regionneighbour: '3', socialawareness: '2', animalhandling: '1', lores: '7', unarmed: '1', religionphilosophy: '1', craftingvocation: '7', compositionperf: '3', } },
underground : { skills : {
- survival: '2', languages: '13', stalking: '3', unarmed: '1', concealment: '1', socialawareness: '1', running: '1', weighttraining: '1', medicine: '2', climbing: '1', lores: '4', perception: '2', bodydevelopment: '2', regionown: '5', craftingvocation: '5', meleeweapons: '1', } },
+ stalking: '3', languages: '13', perception: '2', meleeweapons: '1', climbing: '1', regionown: '5', bodydevelopment: '2', concealment: '1', running: '1', socialawareness: '1', lores: '4', medicine: '2', unarmed: '1', survival: '2', craftingvocation: '5', weighttraining: '1', } },
+ reaver : { skills : {
+ tracking: '1', perception: '1', regionown: '5', regionneighbour: '1', animalhandling: '1', unarmed: '2', medicine: '1', riding: '1', meleeweapons: '1', climbing: '1', bodydevelopment: '2', running: '2', maneuveringinarmor: '2', stalking: '1', lores: '3', languages: '11', jumping: '1', survival: '1', craftingvocation: '3', rangedweapons: '1', } },
rural : { skills : {
- swimming: '1', influence: '1', regionneighbour: '1', riding: '2', weighttraining: '1', socialawareness: '1', compositionperf: '1', perception: '1', bodydevelopment: '1', lores: '4', animalhandling: '3', herbalism: '1', trading: '1', running: '1', medicine: '1', climbing: '1', regionown: '5', languages: '13', craftingvocation: '4', piloting: '1', } },
- mariner : { skills : {
- survival: '1', influence: '1', regionneighbour: '2', weighttraining: '1', navigation: '1', compositionperf: '1', perception: '2', bodydevelopment: '1', lores: '5', languages: '15', unarmed: '1', trading: '1', running: '1', medicine: '1', socialawareness: '1', swimming: '2', acrobatics: '1', climbing: '1', regionown: '5', jumping: '1', craftingvocation: '4', } },
+ languages: '13', perception: '1', regionown: '5', regionneighbour: '1', herbalism: '1', animalhandling: '3', medicine: '1', weighttraining: '1', riding: '2', piloting: '1', climbing: '1', bodydevelopment: '1', swimming: '1', running: '1', trading: '1', socialawareness: '1', influence: '1', lores: '4', craftingvocation: '4', compositionperf: '1', } },
+ nomad : { skills : {
+ tracking: '1', perception: '1', regionown: '5', navigation: '1', regionneighbour: '2', herbalism: '1', animalhandling: '4', unarmed: '1', medicine: '1', riding: '3', bodydevelopment: '1', running: '2', trading: '1', socialawareness: '1', lores: '4', languages: '14', survival: '1', craftingvocation: '4', compositionperf: '1', } },
+ harsh : { skills : {
+ running: '2', tracking: '1', perception: '2', meleeweapons: '1', concealment: '1', regionown: '5', bodydevelopment: '3', navigation: '1', maneuveringinarmor: '1', stalking: '2', lores: '2', medicine: '2', unarmed: '1', survival: '3', languages: '8', craftingvocation: '4', } },
+ highland : { skills : {
+ tracking: '1', perception: '1', regionown: '5', socialawareness: '1', animalhandling: '1', unarmed: '1', medicine: '1', meleeweapons: '1', climbing: '1', running: '2', bodydevelopment: '2', swimming: '1', maneuveringinarmor: '1', stalking: '1', lores: '4', languages: '13', jumping: '1', survival: '2', craftingvocation: '4', compositionperf: '1', } },
};
@@ -11483,12 +11526,13 @@ Custom Spell List
const shield_bonus = ev.shield_bonus;
{
const sb2 = Math.floor(shield_bonus / 2);
- updates.db_partialblock = basedb + shielddb + runningranks + Math.max(0, shield_bonus) + passivedodgebonus;
+ updates.db_partialblock = basedb + shielddb + runningranks +
+ Math.round(Math.max(0, sb2) / 2) + 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(sb2)} Shield bonus x ½ (min 0)\n` +
`${F(passivedodgebonus)} Passive Dodge`;
}
@@ -11844,7 +11888,9 @@ Custom Spell List
*/
RMUInventory.addSpecialEquipment = function() {
getSectionIDsPending(`repeating_stuff`, ids => {
- let toget = ['base_at_misc']
+ let percept = 0;
+ let rangedpenalty = 0;
+ let toget = ['base_at_misc', 'perception_misc']
ids.forEach(id => {
toget.push(`repeating_stuff_${id}_itemname`);
toget.push(`repeating_stuff_${id}_itemequipped`);
@@ -11916,10 +11962,22 @@ Custom Spell List
if (json['Attack Table']) {
RMUInventory.updateWeapon(name, json);
}
-
+ percept += parseIntDefault(json['Perception Penalty'], 0);
+ rangedpenalty += parseIntDefault(json['Ranged Penalty'], 0);
+ maneuver_penalty += parseIntDefault(json['Maneuver Penalty'], 0);
});
+
+ // Adjust due to perception penalty
+ updates.perception_misc = miscBonusSet(updates.perception_misc,
+ "Armor Perception Penalty", percept);
+ updates.perception_penalty = percept;
+ updates.ranged_penalty = rangedpenalty;
+ updates.maneuver_penalty = maneuver_penalty;
+
console.log("equipment update", updates);
- setAttrsPending(updates);
+ setAttrsPending(updates, () => {
+ RMUSkills.updateSingleCategory("Awareness");
+ });
});
});
}
@@ -12017,13 +12075,17 @@ Custom Spell List
const range = json['RI'] || json['short'] || '-';
getCompendiumPagePending("AttackTable:" + json['Attack Table'], (cdata) => {
- console.log("Attack data for", json['Attack Table'], cdata);
if (!cdata.data['data-attack']) {
rmuerror("Data attack missing in ", json['Attack Table']);
+ return;
}
let min = cdata.data.min.match(/\d+/)[0] || 0;
let max = cdata.data.max.match(/\d+/)[0] || 0;
let attack_table = cdata.data['data-attack'] || "";
+ let attacktype = 'melee';
+ if (cdata.RI && parseIntDefault(cdata.RI, 0) > 0) {
+ attacktype = 'ranged';
+ }
setAttrsPending({
[`${prefix}_attackname`]: name,
[`${prefix}_attacksize`]: size,
@@ -12192,10 +12254,20 @@ Custom Spell List
console.log(fullnames);
setAttrs(fullnames);
});
+ });
-
+ onCheck("clicked:repeating_stuff:edititem", (ev) => {
+ console.log(ev);
+ const basename = ev.sourceAttribute.replace("_edititem", "");
+ console.log(basename);
+ // Don't need count - you can edit that directly
+ getAttrs([`${basename}_name`, `${basename}_itemweight`,
+ `${basename}_itemsystem`, `${basename}_itemnotes`,
+ `${basename}_itemmaterial`], (item) => {
+ console.log(item);
+ });
});
-
+
} // End 'cheap-module' scope
@@ -12917,7 +12989,7 @@ Custom Spell List
// - cdata.targetcrit = values.target_crit || '';
// - cdata.attackmod = The numeric attack modifer - all mods
// - cdata.attackmoddescription = Description of the above
- // - cdata.maneuver_penalty = values.maneuver_penalty || 0;
+ // - cdata.statuspenalty = values.statuspenalty || 0;
//
// Results are:
@@ -13113,9 +13185,9 @@ Custom Spell List
attackmod += cdata.attackbonus;
attackmoddescription = ` +${cdata.attackbonus} [Attack Bonus]`;
- if (cdata.maneuver_penalty < 0) {
- attackmod += cdata.maneuver_penalty;
- attackmoddescription += ` ${cdata.maneuver_penalty} [Maneuver Penalty]`;
+ if (cdata.statuspenalty < 0) {
+ attackmod += cdata.statuspenalty;
+ attackmoddescription += ` ${cdata.statuspenalty} [Status Penalty]`;
}
if (cdata.targetsize < cdata.attackersize) {
@@ -13172,6 +13244,11 @@ Custom Spell List
attackmod -= cdata.parrymod;
}
+ if (cdata.ranged_penalty) {
+ attackmoddescription += ` -${cdata.ranged_penalty} [Armor Ranged Penalty]`;
+ attackmod -= cdata.ranged_penalty;
+ }
+
attackmod += cdata.othermod;
if (cdata.othermod > 0) {
attackmoddescription += ` +${cdata.othermod} [Other]`;
@@ -13193,7 +13270,7 @@ Custom Spell List
`{\{target=${cdata.targetname}}} ` +
`{\{targetescaped=${cdata.targetescaped}}} ` +
`{\{weapon=${cdata.attackname}}} ` +
- `{\{maneuverpenalty=${cdata.maneuver_penalty}}} ` +
+ `{\{statuspenalty=${cdata.status_penalty}}} ` +
`{\{attackmoddescription=[[0]]}} ` +
`{\{targetname=[[0]]}} ` +
"{\{hitlocation=[[1d7]] }} " +
@@ -13223,10 +13300,12 @@ Custom Spell List
`${basename}_attackfumble`,
`${basename}_attacktype`,
'size', `${basename}_attacksize`,
- 'maneuver_penalty', 'statuseffect',
+ 'statuspenalty', 'statuseffect',
'target_name', 'target_db', 'target_at',
'target_size', 'target_crit',
'parrymod', 'othermod',
+ // Ranged Penalty from armor
+ 'ranged_penalty',
// Used depending on type: So get melee, missile and spell
'attackuseap', 'aptrack_melee', 'aptrack_missile', 'aptrack_spell',
'token_id'
@@ -13255,16 +13334,19 @@ Custom Spell List
cdata.statuseffect = parseIntDefault(values.statuseffect, 0);
cdata.parrymod = parseIntDefault(values.parrymod, 0);
cdata.othermod = parseIntDefault(values.othermod, 0);
- cdata.maneuver_penalty = parseIntDefault(values.maneuver_penalty, 0);
+ cdata.statuspenalty = parseIntDefault(values.statuspenalty, 0);
cdata.useap = (values.attackuseap == 'on') ? true : false;
// Use the attack type to get the right AP
cdata.attacktype = values[`${basename}_attacktype`];
if (cdata.attacktype == 'melee') {
cdata.apused = parseIntDefault(values.aptrack_melee, 0);
+ cdata.ranged_penalty = 0;
} else if (cdata.attacktype == 'ranged') {
cdata.apused = parseIntDefault(values.aptrack_missile, 0);
+ cdata.ranged_penalty = parseIntDefault(values.ranged_penalty, 0);
} else if (cdata.attacktype == 'directed') {
cdata.apused = parseIntDefault(values.aptrack_spell, 0);
+ cdata.ranged_penalty = 0;
} else {
cdata.apused = 0;
}
@@ -13534,6 +13616,10 @@ Custom Spell List
const actionevents = actions.map(name => `change:aptrack_${name}`).join(" ");
onCheck(actionevents, (ev) => {
+ if (ev.newValue == null) {
+ rmuwarn("Action new value is null/undefined - ignoring");
+ return;
+ }
var select = ev.sourceAttribute.match(/aptrack_(.*)/)[1];
toclear = {}
for (var action of actions) {
@@ -14069,7 +14155,7 @@ Custom Spell List
let total = parseIntDefault(ev.fatigue, 0) +
parseIntDefault(ev.hppenalty, 0) +
parseIntDefault(ev.injurypenalty, 0);
- setAttrs({maneuver_penalty: total, bar3_value: total});
+ setAttrs({statuspenalty: total, bar3_value: total});
});
}
@@ -14108,7 +14194,7 @@ Custom Spell List
onCheck("clicked:rollinitiative", () => {
// roll20 treats floor as round to negative infinity, so ceil since they should be neagtive
- startRoll('&{template:rmuinit} [[ [[ 2d10 ]] + @{initiative} + [[ceil(@{maneuver_penalty} / 10)]] &{tracker}]] ' +
+ startRoll('&{template:rmuinit} [[ [[ 2d10 ]] + @{initiative} + [[ceil(@{statuspenalty} / 10)]] &{tracker}]] ' +
'{\{actor=@{character_name} }} ' +
'{\{bonus=@{initiative} }} ' +
'{\{total=$[[2]]}} {\{roll=$[[0]]}} ' +
@@ -14145,35 +14231,37 @@ Custom Spell List
// Weapon (we) and ranged weapon are special (rw)
// Require table and size for each.
creature.weaponcodes = {
- be: { table: "Beak", size: 0 },
- bi: { table: "Bite", size: 0 },
- cl: { table: "Claw", size: 0 },
- cr: { table: "Crush", size: 0 },
- gr: { table: "Grapple", size: 0 },
- ho: { table: "Horn", size: 0 },
- ra: { table: "Ram", size: 0 },
- sw: { table: "Unarmed Sweeps", size: 0 },
- un: { table: "Unarmed Strike", size: 0 },
- si: { table: "Stinger", size: 0 },
- tr: { table: "Trample", size: 0 },
+ be: { table: "Beak", size: 0, type: "melee" },
+ bi: { table: "Bite", size: 0, type: "melee" },
+ cl: { table: "Claw", size: 0, type: "melee" },
+ cr: { table: "Crush", size: 0, type: "melee" },
+ gr: { table: "Grapple", size: 0, type: "melee" },
+ ho: { table: "Horn", size: 0, type: "melee" },
+ ra: { table: "Ram", size: 0, type: "melee" },
+ sw: { table: "Unarmed Sweeps", size: 0, type: "melee" },
+ un: { table: "Unarmed Strike", size: 0, type: "melee" },
+ si: { table: "Stinger", size: 0, type: "melee" },
+ tr: { table: "Trample", size: 0, type: "melee" },
// FXIME: Hacky
- we: { table: "Arming Sword", size: 0 },
- da: { table: "Dagger", size: 0 },
- rp: { table: "Rapier", size: 0 },
- as: { table: "Arming Sword", size: 0 },
- bs: { table: "Broadsword", size: 0 },
- sc: { table: "Scimitar", size: 0 },
- fa: { table: "Falchion", size: 0 },
- ma: { table: "Mace", size: 0 },
- cu: { table: "Club", size: 0 },
- lc: { table: "Club", size: 1 },
- sb: { table: "Bow, Short", size: 0 },
- lb: { table: "Bow, Long", size: 0 },
- ss: { table: "Arming Sword", size: -1 },
- ls: { table: "Arming Sword", size: 1 },
- fa: { table: "Falchion", size: 0 },
-
-
+ we: { table: "Arming Sword", size: 0, type: "melee" },
+ da: { table: "Dagger", size: 0, type: "melee" },
+ rp: { table: "Rapier", size: 0, type: "melee" },
+ as: { table: "Arming Sword", size: 0, type: "melee" },
+ bs: { table: "Broadsword", size: 0, type: "melee" },
+ sc: { table: "Scimitar", size: 0, type: "melee" },
+ fa: { table: "Falchion", size: 0, type: "melee" },
+ ma: { table: "Mace", size: 0, type: "melee" },
+ cu: { table: "Club", size: 0, type: "melee" },
+ lc: { table: "Club", size: 1, type: "melee" },
+ sb: { table: "Bow, Short", size: 0, type: "ranged" },
+ lb: { table: "Bow, Long", size: 0, type: "ranged", },
+ ss: { table: "Arming Sword", size: -1, type: "melee" },
+ ls: { table: "Arming Sword", size: 1, type: "melee" },
+ fa: { table: "Falchion", size: 0, type: "melee" },
+
+ lc: { table: "Crossbow", size: 0, type: "ranged" },
+ hc: { table: "Crossbow", size: 1, type: "ranged" },
+ hx: { table: "Crossbow", size: -1, type: "ranged" },
/*
Two-handed Sword ts
@@ -14192,8 +14280,6 @@ Custom Spell List
Halberd ha
Pole Axe px
Sling sl
-Light Crossbow lc
-Heavy Crossbow hc
Bola bo
Javelin ja
Dagger (Thrown) td
@@ -14289,7 +14375,7 @@ Custom Spell List
updates.injurypenalty = 0;
updates.endurance = cdata.Fatigue;
updates.fatigue = 0;
- updates.maneuver_penalty = 0;
+ updates.status_penalty = 0;
updates.rr_channeling_bonus = cdata.Ch;
updates.rr_essence_bonus = cdata.Ess;
@@ -14421,7 +14507,7 @@ Custom Spell List
'target_at',
'target_size',
'target_crit',
- 'maneuver_penalty',
+ 'status_penalty',
'statuseffect',
];
getAttrs(toget, (values) => {
@@ -14443,7 +14529,7 @@ Custom Spell List
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);
+ cdata.status_penalty = parseIntDefault(values.status_penalty, 0);
// FIXME:
cdata.parrymod = 0;
cdata.othermod = 0;
@@ -14940,6 +15026,14 @@ Custom Spell List
version = 7;
}
+ if (version == 7) {
+ // updatePenalties in in status; old value will be updateed by equipment update
+ addPendingFunction("Upgrade to 8: Manuever_penalty -> statuspenalty", updatePenalties);
+ addPendingFunction("Upgrade to 8: Update Equipement", RMUInventory.updateEquiopement);
+ version = 8;
+ }
+
+
if (oldversion != version) {
addPendingFunction(`Version update to ${version}`, () => {
setAttrsPending({version: version});
diff --git a/RolemasterUnified_Official/sheet.json b/RolemasterUnified_Official/sheet.json
index 8971e7fd878..9f59ea6e196 100644
--- a/RolemasterUnified_Official/sheet.json
+++ b/RolemasterUnified_Official/sheet.json
@@ -8,5 +8,5 @@
"legacy": false,
"printable": true,
"compendium": "RMU",
- "version": "1733207371"
+ "version": "1733856892"
}
diff --git a/RolemasterUnified_Official/updates.md b/RolemasterUnified_Official/updates.md
index d964a847fe3..79bc75bf09f 100644
--- a/RolemasterUnified_Official/updates.md
+++ b/RolemasterUnified_Official/updates.md
@@ -1,3 +1,22 @@
+# 2024-12-10
+
+- Finalise handling of Professions with selectable Base lists
+ - Alchemists are the first users
+- Creatures: Add hx for Hand Crossbows, and a few other attacks
+- Half shield bonus skill for partial block - not the full one.
+- Try and squash the super long list of errors when you first update stateud
+- Compendium data: Move a long bow to Bow, Long for the table.
+- Creatures: Creatures can now roll skills.
+- Equipment:
+ - Perception Penalties are now applied
+ - Ranged Penalties are now applied.
+- Take a terrible guess if it's a ranged or melee weapon when adding attacks
+- Creatures now have framework for type of attack (melee, ranged, directed)
+ - Does not (yet) change attack
+ - Add test to validate attack types
+- Change 'maneuver_penalty' -> status_penalty
+ - Update everywhere except inventory; it was a collision of names before.
+
# 2024-12-3
- Initiative modified by maneuver penalty
@@ -5,6 +24,7 @@
- Add tests and validations for creatures.
- All creature weapons now have a size (usually 0)
- Display a message when an injury takes a character to negative hits.
+- Fix a stupid misplaced class for RRs
# 2024-11-26