Skip to content

Commit

Permalink
v13.1.11 fix Wild Shape attack calculation
Browse files Browse the repository at this point in the history
•	Added better error handling for malformed choice/extrachoice/variant/subclass entries of classes, races, backgrounds, feats, and magic items. Now this will no longer cause the source selection dialog to error out. When selecting one of the above with such an erroneous sub-choice, a warning will display in the console.
•	Added `notes` as an optional attribute to the CreatureList object.
•	Added support for composite AC of the CreatureList object on the Wild Shape pages (e.g. `ac : "10+Dex"`).
•	Changed how wild shapes attacks are calculated to fix a bug (see below) and adhere to the other attack sections so that more complex modifiers and non-numeric damage die entries work correctly.
•	Made wild shapes recalculate when changing mental stats using the ability score dialog.
•	Fixed ability save DCs on the first page using the wrong ability modifier when the corresponding entry on the spell sheet page uses a different ability score to determine the DC (MBUG-122).
•	Fixed the listing of the “Additional Sheet” in the print dialog to be clearer.
•	Fixed wild shapes attacks not listening to the right syntax for attacks and not being backwards-compatible.
•	Fixed wild shapes not recalculating when used without the druid class being selected.
•	Fixed wild shapes recalculating using the correct proficiency bonus when changing level.
•	Fixed field filling issue for creatures, feats, and magic items that themselves add another of the same type using `eval` (e.g. a feat that adds another feat upon selection). Before, this could overwrite the first selection with one added through `eval`.
  • Loading branch information
morepurplemorebetter committed Nov 15, 2023
1 parent e80667b commit 94100e9
Show file tree
Hide file tree
Showing 11 changed files with 314 additions and 188 deletions.
22 changes: 19 additions & 3 deletions _functions/AbilityScores.js
Original file line number Diff line number Diff line change
Expand Up @@ -456,21 +456,37 @@ function AbilityScores_Button(onlySetTooltip) {
var res = dialog.store();
// Save to the global variable
this.setCurrentStats(dialog);
// See if any stats changed
var statChange = { any : false, con : false, mental : false };
for (var s = 0; s < 7; s++) {
var abbr2 = asab2[s];
if (res["ol"+abbr2] != res["to"+abbr2]) {
statChange.any = true;
if (abbr2 == "Cn") {
statChange.con = true;
} else if (!statChange.mental && /In|Ws|Ch/.test(abbr2)) {
statChange.mental = true;
}
}
}
if (!statChange.any) return; // no totals changed
// Start progress bar and stop calculations
var thermoTxt = thermoM("Applying stats...");
calcStop();
// Set the new ability scores to the fields (and their mods, so functions use the new one)
for (var s = 0; s < 7; s++) {
var theAbi = res["to"+asab2[s]];
var theAbi = Number(res["to"+asab2[s]]);
Value(asab3[s], theAbi);
Value(asab3[s] + " Mod", Math.round((Number(theAbi) - 10.5) * 0.5));
Value(asab3[s] + " Mod", Math.round((theAbi - 10.5) * 0.5));
}
// Update the Honor/Sanity
if (this.fieldHoS !== curHoS) ShowHonorSanity(this.fieldHoS);
// Apply HP tooltips if Con changed
if (res["olCn"] != res["toCn"]) CurrentUpdates.types.push("hp");
if (statChange.con) CurrentUpdates.types.push("hp");
// Recalculate attack entries, as they might have changed (Finesse)
CurrentUpdates.types.push("attacks");
// Recalculate wild shapes, if the mental stats changed
if (statChange.mental) WildshapeRecalc();
thermoM(thermoTxt, true); // Stop progress bar
},

Expand Down
48 changes: 34 additions & 14 deletions _functions/Functions1.js
Original file line number Diff line number Diff line change
Expand Up @@ -2372,20 +2372,23 @@ function ParseRace(input) {
if (kObj.variants) {
var foundLen2 = 0;
var foundDat2 = 0;
for (var sub = 0; sub < kObj.variants.length; sub++) { // scan string for all variants of the race
var theR = key + "-" + kObj.variants[sub];
for (var i = 0; i < kObj.variants.length; i++) { // scan string for all variants of the race
var theR = key + "-" + kObj.variants[i];
var rVars = RaceSubList[theR];
if (!rVars) {
console.println("The racial variant '" + kObj.variants[sub] + "' for the '" + kObj.name + "' race is not found in the RaceSubList. Please contact the author of this race to have this issue corrected. The variant will be ignored for now.");
console.println("The racial variant '" + kObj.variants[i] + "' for the '" + kObj.name + "' race missing from the RaceSubList object. Please contact its author to have this issue corrected. The variant will be ignored for now.");
console.show();
// Remove this array entry, but make sure we don't skip an entry
kObj.variants.splice(i, 1);
i--;
continue;
}
var theRname = rVars.name ? rVars.name : kObj.variants[sub];
var theRname = rVars.name ? rVars.name : kObj.variants[i];

// test if the racial variant or its source isn't excluded
if (testSource(theR, rVars, "racesExcl")) continue;

resultArray[2].push(kObj.variants[sub]);
resultArray[2].push(kObj.variants[i]);

// see if racial variant regex matches
if (!(rVars.regExpSearch).test(input)) continue;
Expand All @@ -2397,7 +2400,7 @@ function ParseRace(input) {
if ((!ignoreSearchLength && theRname.length < foundLen2) || (!ignoreSearchLength && theRname.length == foundLen2 && tempDate < foundDat) || (ignoreSearchLength && tempDate <= foundDat)) continue;

// we have a match, set the values
resultArray[1] = kObj.variants[sub];
resultArray[1] = kObj.variants[i];
foundLen2 = theRname.length;
foundDat2 = tempDate;
}
Expand Down Expand Up @@ -3977,12 +3980,19 @@ function ParseBackground(input) {
// first we look for background variants
if (kObj.variant) {
var matchedThisSub = false;
var BackOpt = kObj.variant;
for (var sub = 0; sub < BackOpt.length; sub++) { // scan string for all variants of the background
var bVars = BackgroundSubList[BackOpt[sub]];
for (var i = 0; i < kObj.variant.length; i++) { // scan string for all variants of the background
var bVars = BackgroundSubList[kObj.variant[i]];
if (!bVars) {
console.println("The variant '" + kObj.variant[i] + "' for the background '" + kObj.name + "' is missing from the BackgroundSubList object. Please contact its author to have this issue corrected. The variant will be ignored for now.");
console.show();
// Remove this array entry, but make sure we don't skip an entry
kObj.variant.splice(i, 1);
i--;
continue;
}

if (!(bVars.regExpSearch).test(input) // see if background variant regex matches
|| testSource(BackOpt[sub], bVars, "backgrExcl") // test if the background variant or its source isn't excluded
|| testSource(kObj.variant[i], bVars, "backgrExcl") // test if the background variant or its source isn't excluded
) continue;

// only go on with this entry if:
Expand All @@ -3992,7 +4002,7 @@ function ParseBackground(input) {
if ((!ignoreSearchLength && bVars.name.length < foundLen) || (!ignoreSearchLength && bVars.name.length == foundLen && tempDate < foundDat) || (ignoreSearchLength && tempDate <= foundDat)) continue;

// we have a match, set the values
resultArray = [key, BackOpt[sub]];
resultArray = [key, kObj.variant[i]];
foundLen = bVars.name.length;
foundDat = tempDate;
matchedThisSub = true;
Expand Down Expand Up @@ -4773,7 +4783,15 @@ function ParseFeat(input) {
for (var i = 0; i < kObj.choices.length; i++) {
var keySub = kObj.choices[i].toLowerCase();
var sObj = kObj[keySub];
if (!sObj || testSource(key + "-" + keySub, sObj, "featsExcl")) continue;
if (!sObj) {
console.println("The subchoice '" + kObj.choices[i] + "' for the feat '" + kObj.name + "' doesn't have a corresponding object entry. Please contact its author to have this issue corrected. The choice will be ignored for now.");
console.show();
// Remove this array entry, but make sure we don't skip an entry
kObj.choices.splice(i, 1);
i--;
continue;
}
if (testSource(key + "-" + keySub, sObj, "featsExcl")) continue;
varArr.push(kObj.choices[i]);
var isMatchSub = false;
if (sObj.name) {
Expand Down Expand Up @@ -5316,7 +5334,9 @@ function AddFeat(sFeat) {
var RegExFeat = RegExp("\\b" + sFeat.RegEscape() + "\\b", "i");
for (var n = 1; n <= 2; n++) {
for (var i = 1; i <= FieldNumbers.feats; i++) {
// first check if a selection made in this field wasn't the one initiating this function, because then it should be skipped
var sFldNm = "Feat Name " + i;
if (event.target && event.target.name === sFldNm) continue;
var sCurFeat = What(sFldNm);
if (n === 1 && (RegExFeat.test(sCurFeat) || sCurFeat.toLowerCase() === sFeatLC)) {
return; // the feat already exists
Expand Down Expand Up @@ -5756,7 +5776,7 @@ function UpdateLevelFeatures(Typeswitch, newLvlForce) {
for (var i = 1; i <= 4; i++) {
var theFld = What(prefixA[p] + "Wildshape.Race." + i);
if (!theFld || theFld.toLowerCase() === "make a selection") continue;
if (!theFld && theFld.toLowerCase() !== "make a selection" && ParseCreature(theFld)) {
if (theFld && theFld.toLowerCase() !== "make a selection" && ParseCreature(theFld)) {
WSinUse = true;
p = prefixA.length;
break;
Expand Down Expand Up @@ -6730,7 +6750,7 @@ function CalcAbilityDC() {
useSSDC = false;
break;
}
if (aSpCast && aSpCast.calcSpellScores && aSpCast.calcSpellScores.dc !== undefined) {
if (aSpCast && aSpCast.abilityToUse[0] === Indx && aSpCast.calcSpellScores && aSpCast.calcSpellScores.dc !== undefined) {
useSSDC = true;
foundSSDC.push(aSpCast.calcSpellScores.dc);
if (!foundSSDCref[aSpCast.calcSpellScores.dc]) foundSSDCref[aSpCast.calcSpellScores.dc] = [];
Expand Down
Loading

0 comments on commit 94100e9

Please sign in to comment.