diff --git a/_functions/Functions1.js b/_functions/Functions1.js index 74dcbf23..307c5a9b 100644 --- a/_functions/Functions1.js +++ b/_functions/Functions1.js @@ -494,7 +494,7 @@ function ResetAll(GoOn, noTempl, deleteImports) { CurrentUpdates = {types : []}; GetStringifieds(keepImports); - if (keepImports) { // remove the imports and reset the sources + if (keepImports) { // keep the imports and reset the sources SetStringifieds("sources"); SetStringifieds("scriptfiles"); Value("User Script", userScriptString); @@ -2939,7 +2939,9 @@ function ReCalcWeapons(justProfs, force) { }; }; -function SetWeaponsdropdown(forceTooltips) { +// Fill the attack drop-down boxes. +// `aCompPrefixes` - Optional - Pass (array of) prefix of companion pages to update drop-down boxes. Omit to update every drop-down. +function SetWeaponsdropdown(forceTooltips, aCompPrefixes) { var tempString = "Type in the name of the attack (or select it from the drop-down menu) and all its attributes will be filled out automatically, provided that its a recognized attack."; tempString += "\n\n" + toUni("Magic bonus") + '\nAny magical bonus you type in this field is added to both the to hit and damage (e.g. type " +2Longsword").'; tempString += "\n\n" + toUni("Off-hand weapons") + '\nIf the name or description fields include the word "off-hand", "secondary", "spell", or "cantrip", the ability modifier will only be added to the to hit bonus, and not to the damage.'; @@ -2988,47 +2990,67 @@ function SetWeaponsdropdown(forceTooltips) { } }; + if (CurrentVars.extraWeaponsDisplay) { + for (var key in CurrentVars.extraWeaponsDisplay) { + weaponlists.startlist.push(CurrentVars.extraWeaponsDisplay[key]); + } + }; + // make the definitive list of weapons for the dropdown box var setweapons = []; - var addWeaList = function (weArr, addFirst, noSort, addAtStart) { + var addWeaList = function (setweapons, weArr, addFirst, noSort, addAtStart) { + if (!weArr) return setweapons; if (!noSort) weArr.sort(); if (addFirst) weArr.unshift(addFirst); if (weArr.length) { weArr.unshift(""); setweapons = !addAtStart ? setweapons.concat(weArr) : weArr.concat(setweapons); } + return setweapons; }; - addWeaList(weaponlists.melee.concat(weaponlists.ranged), "Unarmed Strike"); // add the natural weapons - addWeaList(weaponlists.improvised, "Improvised Weapon"); // add the improvised weapons - addWeaList(weaponlists.spell, "Spell Attack"); // add the spells/cantrips - addWeaList(weaponlists.endlist, false, true); // add the endlist weapons + setweapons = addWeaList(setweapons, weaponlists.melee.concat(weaponlists.ranged), "Unarmed Strike"); // add the natural weapons + setweapons = addWeaList(setweapons, weaponlists.improvised, "Improvised Weapon"); // add the improvised weapons + setweapons = addWeaList(setweapons, weaponlists.spell, "Spell Attack"); // add the spells/cantrips + // now add any lists that are not preset otherLists.sort(); for (var i = 0; i < otherLists.length; i++) addWeaList(weaponlists[otherLists[i]]); + setweapons = addWeaList(setweapons, weaponlists.endlist, false, true); // add the endlist weapons + + var listToSource = setweapons.toSource(); + // first set the companion sheets attack dropdowns var AScompA = What("Template.extras.AScomp").split(","); - var listToSource = setweapons.toSource(); + if (aCompPrefixes && !isArray(aCompPrefixes)) aCompPrefixes = [aCompPrefixes]; for (var i = 0; i < AScompA.length; i++) { var prefix = AScompA[i]; + if (aCompPrefixes && aCompPrefixes.indexOf(prefix) === -1) continue; // only do selected + // Create new list of attacks, at the start + var compAtkList = !CurrentCompRace[prefix] || !CurrentCompRace[prefix].attacks ? false : CurrentCompRace[prefix].attacks.map(function (atk) { return atk.name; }) + var setweaponsComp = addWeaList(setweapons, compAtkList, false, true, true); + var listToSourceComp = !compAtkList ? listToSource : setweaponsComp.toSource(); + // Apply list to drop-downs for (var c = 1; c <= 3; c++) { var theFld = prefix + "Comp.Use.Attack." + c + ".Weapon Selection"; var theFldSuNm = prefix + "Comp.Use.Attack." + c + ".Proficiency"; - if (tDoc.getField(theFldSuNm).submitName === listToSource) { + if (tDoc.getField(theFldSuNm).submitName === listToSourceComp) { if (forceTooltips) AddTooltip(theFld, tempString); continue; // no changes, so no reason to set this field } - tDoc.getField(theFldSuNm).submitName = listToSource; + tDoc.getField(theFldSuNm).submitName = listToSourceComp; var theFldVal = What(theFld); IsNotWeaponMenu = false; - tDoc.getField(theFld).setItems(setweapons); + tDoc.getField(theFld).setItems(setweaponsComp); IsNotWeaponMenu = true; if (theFldVal !== What(theFld)) Value(theFld, theFldVal, tempString); }; } + if (aCompPrefixes) return; // Only doing a specific companion page, so stop here + // now add the special weapons added by features, as we only want those on the first page - addWeaList(weaponlists.startlist, false, false, true); + setweapons = addWeaList(setweapons, weaponlists.startlist, false, false, true); listToSource = setweapons.toSource(); // lastly set this array for the attack dropdowns on the first page @@ -3075,6 +3097,12 @@ function SetArmordropdown(forceTooltips) { } }; + if (CurrentVars.extraArmourDisplay) { + for (var key in CurrentVars.extraArmourDisplay) { + aLists.startlist.push(CurrentVars.extraArmourDisplay[key]); + } + }; + // now create the final array element to set to the armour field var setarmours = []; @@ -3215,7 +3243,7 @@ function ParseGear(input) { if (!input) return false; var foundLen = 0, testLen = 0; var result = false; - var tempString = removeDiacritics(input.toLowerCase()); + var tempString = clean(input.toLowerCase(), false, true); var tempStrLen = tempString.length; //see if it is a magic item @@ -4941,7 +4969,6 @@ function ApplyFeat(input, FldNmbr) { var ArrayNmbr = FldNmbr - 1; var oldFeat = CurrentFeats.known[ArrayNmbr]; var oldFeatVar = CurrentFeats.choices[ArrayNmbr]; - var setFieldValueTo; var failedChoice = false; var doNotCommit = function(toSetVal) { @@ -4974,7 +5001,7 @@ function ApplyFeat(input, FldNmbr) { if (!selectFeatVar) selectFeatVar = AskUserOptions("Select " + aFeat.name + " Type", "The '" + aFeat.name + "' feat has several forms. Select which form you want to add to the sheet at this time.\n\nYou can change the selected form with the little square button in the feat line that this feat is in.", parseResult[2], "radio", true); newFeatVar = selectFeatVar.toLowerCase(); aFeatVar = aFeat[newFeatVar]; - setFieldValueTo = aFeatVar.name ? aFeatVar.name : aFeat.name + " [" + selectFeatVar + "]"; + event.target.setValPrepared = aFeatVar.name ? aFeatVar.name : aFeat.name + " [" + selectFeatVar + "]"; } } else if (!IsNotImport) { failedChoice = true; @@ -5001,7 +5028,7 @@ function ApplyFeat(input, FldNmbr) { } if (oldFeat === newFeat && oldFeatVar === newFeatVar) { - if (setFieldValueTo) event.target.setVal = setFieldValueTo; + if (event.target.setValPrepared) event.target.setVal = event.target.setValPrepared; return; // No changes were made } @@ -5015,7 +5042,7 @@ function ApplyFeat(input, FldNmbr) { aFeatVar = ""; } else { var theFeat = { - name : aFeatVar.name ? aFeatVar.name : setFieldValueTo ? setFieldValueTo : input + name : aFeatVar.name ? aFeatVar.name : event.target.setValPrepared ? event.target.setValPrepared : input } var FeatAttr = ["source", "description", "descriptionFull", "calculate", "prerequisite", "prereqeval"]; for (var a = 0; a < FeatAttr.length; a++) { @@ -5089,9 +5116,6 @@ function ApplyFeat(input, FldNmbr) { }; }; - // if a feat variant was chosen, make sure this field will show that selection, now that it can't be cancelled anymore due to not meeting a prerequisite - if (setFieldValueTo) event.target.setVal = setFieldValueTo; - calcStop(); // Now stop the calculations // Remove previous feat at the same field @@ -5160,6 +5184,9 @@ function ApplyFeat(input, FldNmbr) { ); } + // if a feat variant was chosen, make sure this field will show that selection (important that this is the last step) + if (event.target.setValPrepared) event.target.setVal = event.target.setValPrepared; + thermoM(thermoTxt, true); // Stop progress bar }; diff --git a/_functions/Functions2.js b/_functions/Functions2.js index 50693675..5048a8e8 100644 --- a/_functions/Functions2.js +++ b/_functions/Functions2.js @@ -544,6 +544,7 @@ function ApplyCompRace(newRace, prefix, sCompType) { thermoM(3/10); //increment the progress dialog's progress //add any weapons the creature possesses + SetWeaponsdropdown(false, prefix); for (var a = 0; a < aCrea.attacks.length; a++) { AddWeapon(aCrea.attacks[a].name, undefined, prefix); } @@ -4619,13 +4620,12 @@ function UpdateDropdown(type, weapon) { if (minVer || !IsNotUserScript) return; IsSetDropDowns = true; type = type ? type.toLowerCase() : "all"; - var notAll, forceTT = false; + var forceTT = false; calcStop(); switch (type) { case "tooltips" : forceTT = true; case "resources" : - notAll = true; case "all" : SetRacesdropdown(forceTT); SetBackgrounddropdown(forceTT); @@ -4636,10 +4636,8 @@ function UpdateDropdown(type, weapon) { SetWildshapeDropdown(forceTT); SetArmordropdown(forceTT); SetAmmosdropdown(forceTT); - if (notAll) { - SetWeaponsdropdown(forceTT); - break; - } + SetWeaponsdropdown(forceTT); + break; case "attack" : case "attacks" : case "weapon" : @@ -4693,9 +4691,9 @@ function UpdateDropdown(type, weapon) { case "creatures" : case "wildshape" : case "wildshapes" : + SetWildshapeDropdown(); case "companiononly" : SetCompDropdown(); - if (type !== "companiononly") SetWildshapeDropdown(); break; }; IsSetDropDowns = false; @@ -5668,19 +5666,21 @@ function ApplyWeapon(inputText, fldName, isReCalc, onlyProf, forceRedo) { for (var attr in aWea) theWea[attr] = aWea[attr]; thermoTxt = thermoM("Applying the weapon's features...", false); //change the progress dialog text - var curDescr = What(fldBase + "Description"); - var curRange = What(fldBase + "Range"); fields.Description = theWea.description ? theWea.description : ""; //add description fields.Description_Tooltip = theWea.tooltip ? theWea.tooltip : ""; //add the tooltip for the description fields.Range = theWea.range; //add range fields.Damage_Type = theWea.damage[2]; //add Damage Type + //add proficiency checkmark + fields.Proficiency = !QI ? true : isProficientWithWeapon(WeaponName, theWea); + //add Weight fields.Weight = isReCalc ? What(fldBaseBT + "Weight") : theWea.weight ? theWea.weight : ""; //add Damage Die - fields.Damage_Die = theWea.damage[0] + (parseFloat(theWea.damage[1]) ? "d" + theWea.damage[1] : ""); + var weaponDamageDie = theWea.damage[0] + (parseFloat(theWea.damage[1]) ? "d" + theWea.damage[1] : ""); + fields.Damage_Die = weaponDamageDie; //add To Hit Bonus fields.To_Hit_Bonus = isReCalc ? What(fldBaseBT + "To Hit Bonus") : @@ -5691,14 +5691,9 @@ function ApplyWeapon(inputText, fldName, isReCalc, onlyProf, forceRedo) { fields.Damage_Bonus = isReCalc ? What(fldBaseBT + "Damage Bonus") : theWea.modifiers && theWea.modifiers[1] ? theWea.modifiers[1] : 0; - //add proficiency checkmark - fields.Proficiency = !QI ? true : isProficientWithWeapon(WeaponName, theWea); - //add mod var StrDex = What(QI ? "Str" : prefix + "Comp.Use.Ability.Str.Score") < What(QI ? "Dex" : prefix + "Comp.Use.Ability.Dex.Score") ? 2 : 1; - fields.Mod = isReCalc && !theWea.ability ? tDoc.getField(fldBase + "Mod").currentValueIndices : - (/finesse/i).test(theWea.description) ? StrDex : theWea.ability; - + var weaponMod = /finesse/i.test(theWea.description) ? StrDex : theWea.ability; //change mod if this is concerning a spell/cantrip var forceUseSpellcastingMod = theWea.useSpellcastingAbility === undefined ? false : theWea.useSpellcastingAbility ? "y" : "n"; if ((thisWeapon[3] || forceUseSpellcastingMod == "y") && forceUseSpellcastingMod != "n") { @@ -5719,10 +5714,11 @@ function ApplyWeapon(inputText, fldName, isReCalc, onlyProf, forceRedo) { if (!abiArr[i] || abiDone.indexOf(abiArr[i]) !== -1) continue; abiDone.push(abiArr[i]); var thisMod = What(AbilityScores.abbreviations[abiArr[i] - 1]); - if (thisMod > Math.max.apply(Math, abiModArr)) fields.Mod = abiArr[i]; + if (thisMod > Math.max.apply(Math, abiModArr)) weaponMod = abiArr[i]; abiModArr.push(thisMod); } } + fields.Mod = weaponMod; if (theWea.ammo) fields.Ammo = theWea.ammo; //add ammo @@ -5777,10 +5773,20 @@ function ApplyWeapon(inputText, fldName, isReCalc, onlyProf, forceRedo) { } } }; - // if this is a field recalculation and no custom eval changed the description or range, just use the one from the field so that manual changes are preserved + // if this is a field recalculation and no custom eval changed specific parts, just use the one from the field so that manual changes are preserved if (isReCalc && !forceRedo) { - if (fields.Description === theWea.description) fields.Description = curDescr; - if (fields.Range === theWea.range) fields.Range = curRange; + if (fields.Description === theWea.description) { + fields.Description = What(fldBase + "Description"); } + if (fields.Range === theWea.range) { + fields.Range = What(fldBase + "Range"); } + if (fields.Damage_Type === theWea.damage[2]) { + fields.Damage_Type = What(fldBase + "Damage Type"); } + if (fields.Range === theWea.range) { + fields.Range = What(fldBase + "Range"); } + if (fields.Damage_Die === weaponDamageDie) { + fields.Damage_Die = What(fldBaseBT + "Damage Die"); } + if (fields.Mod === weaponMod) { + fields.Mod = tDoc.getField(fldBase + "Mod").currentValueIndices; } } }; @@ -5863,7 +5869,8 @@ function CalcAttackDmgHit(fldName) { var thisWeapon = QI ? CurrentWeapons.known[ArrayNmbr] : CurrentWeapons.compKnown[prefix][ArrayNmbr]; var WeaponName = thisWeapon[0]; var aWea = QI || isNaN(parseFloat(WeaponName)) ? WeaponsList[WeaponName] : !QI && !isNaN(parseFloat(WeaponName)) && CurrentCompRace[prefix] && CurrentCompRace[prefix].attacks ? CurrentCompRace[prefix].attacks[WeaponName] : false; - var WeaponText = QI ? CurrentWeapons.field[ArrayNmbr] : CurrentWeapons.compField[prefix][ArrayNmbr]; + var WeaponTextName = QI ? CurrentWeapons.field[ArrayNmbr] : CurrentWeapons.compField[prefix][ArrayNmbr]; + var WeaponText = WeaponText + (fields.Description ? " " + fields.Description : ""); var theWea = {}; if (aWea && aWea.baseWeapon && WeaponsList[aWea.baseWeapon]) { for (var attr in WeaponsList[aWea.baseWeapon]) theWea[attr] = WeaponsList[aWea.baseWeapon][attr]; @@ -5872,16 +5879,13 @@ function CalcAttackDmgHit(fldName) { var fixedCaster = theWea.useSpellMod && CurrentSpells[theWea.useSpellMod] ? CurrentSpells[theWea.useSpellMod] : false; var aWeaNoAbi = theWea.ability === 0 || (fixedCaster && fixedCaster.fixedDC && fixedCaster.abilityToUse && !fixedCaster.abilityToUse[0]); - if (!WeaponText || ((/^(| |empty)$/).test(fields.Mod) && !aWeaNoAbi)) { + if (!WeaponTextName || ((/^(| |empty)$/).test(fields.Mod) && !aWeaNoAbi)) { Value(fldBase + "Damage", ""); Value(fldBase + "To Hit", ""); if (QI) CurrentWeapons.offHands[ArrayNmbr] = false; return; }; - // only add the description part now, so we don't test against it above - if (fields.Description) WeaponText += " " + fields.Description; - // get the damage bonuses from the selected modifier, magic, and the blueText field var output = { prof : !fields.Proficiency ? 0 : (QI ? (tDoc.getField("Proficiency Bonus Dice").isBoxChecked(0) ? 0 : Number(How("Proficiency Bonus"))) : (tDoc.getField(prefix + "BlueText.Comp.Use.Proficiency Bonus Dice").isBoxChecked(0) ? 0 : What(prefix + "Comp.Use.Proficiency Bonus"))), @@ -5907,7 +5911,7 @@ function CalcAttackDmgHit(fldName) { var isThrownWeapon = isWeapon && /\bthrown\b/i.test(fields.Description) && /\d ?(ft|m)\.?($|[^)])/i.test(fields.Range); // see if this is a off-hand attack and the modToDmg shouldn't be use - var isOffHand = isMeleeWeapon && (/^(?!.*(spell|cantrip))(?=.*(off.{0,3}hand|secondary)).*$/i).test(WeaponText); + var isOffHand = /^(?!.*(spell|cantrip))(?=.*(off.{0,3}hand|secondary)).*$/i.test(WeaponText); if (isOffHand) output.modToDmg = output.mod < 0; // Add the off-hand attack action (only for attacks on the first page) if (QI && CurrentWeapons.offHands[ArrayNmbr] !== isOffHand) { @@ -5920,7 +5924,7 @@ function CalcAttackDmgHit(fldName) { var gatherVars = { WeaponText : WeaponText, - WeaponTextName : WeaponText.replace(" " + fields.Description, ""), + WeaponTextName : WeaponTextName, isDC : isDC, isSpell : isSpell, isWeapon : isWeapon, diff --git a/_functions/Functions3.js b/_functions/Functions3.js index 3524ab3f..12be2145 100644 --- a/_functions/Functions3.js +++ b/_functions/Functions3.js @@ -262,9 +262,9 @@ function ApplyFeatureAttributes(type, fObjName, lvlA, choiceA, forceNonCurrent) // --- backwards compatibility --- // // armor, shield, and weapon additions var aWeaponsAdd = uObj.weaponsAdd ? uObj.weaponsAdd : type == "race" && uObj.weapons ? uObj.weapons : false; - if (aWeaponsAdd) processAddWeapons(addIt, aWeaponsAdd); + if (aWeaponsAdd) processAddWeapons(addIt, aWeaponsAdd, tipNm); var anArmorAdd = uObj.armorAdd ? uObj.armorAdd : uObj.addarmor ? uObj.addarmor : false; - if (anArmorAdd) processAddArmour(addIt, anArmorAdd); + if (anArmorAdd) processAddArmour(addIt, anArmorAdd, tipNm); if (uObj.shieldAdd) processAddShield(addIt, uObj.shieldAdd, uObj.weight); if (uObj.ammoAdd) processAddAmmo(addIt, uObj.ammoAdd); @@ -1138,26 +1138,53 @@ function processSpellcastingBonusElsewhere(bAddRemove, sType, sSrcNm, sUniqueSrc } // set the armour (if more AC than current armour) or remove the armour -function processAddArmour(AddRemove, armour) { - if (!armour || typeof armour != "string") return; - if (!AddRemove) { // remove - RemoveArmor(armour); - } else { // add - if (!ParseArmor(armour)) return; - var remCurArm = What("AC Armor Description"); - var remAC = Number(What("AC")); - Value("AC Armor Description", armour); - if (remCurArm && remAC) { // there was a previous armor, so check if this new armor is better or not - // calculate all the field values, or the AC field will not be updated - var isStoppedCalc = calcStartSet != false; - if (isStoppedCalc) calcCont(true); - if (remAC > Number(What("AC"))) { - Value("AC Armor Description", remCurArm); - } else if (isStoppedCalc) { - calcStop(); +function processAddArmour(AddRemove, armorAdd, srcNm) { + if (!armorAdd || isArray(armorAdd)) return; + if (typeof armorAdd === "string") { + armorAdd = { select : armorAdd }; + } + srcNm = srcNm ? srcNm.toLowerCase() : 'unknownSource'; + if (armorAdd.options) { + if (!CurrentVars.extraArmourDisplay) CurrentVars.extraArmourDisplay = {}; + for (var i = 0; i < armorAdd.options.length; i++) { + var armOption = armorAdd.options[i]; + var newName = srcNm + "-" + armOption.toLowerCase(); + if (AddRemove) { + CurrentVars.extraArmourDisplay[newName] = armOption; + } else { + delete CurrentVars.extraArmourDisplay[newName]; + } + } + // if adding, update the dropdown before adding selection + if (AddRemove) UpdateDropdown("armour"); + } + if (armorAdd.select) { + if (!AddRemove) { // remove + RemoveArmor(armorAdd.select); + } else if (ParseArmor(armorAdd.select)) { // add, but only if a recognized armour + var remCurArm = What("AC Armor Description"); + var remAC = Number(What("AC")); + Value("AC Armor Description", armorAdd.select); + if (remCurArm && remAC) { // there was a previous armor, so check if this new armor is better or not + // calculate all the field values, or the AC field will not be updated + var isStoppedCalc = calcStartSet != false; + if (isStoppedCalc) calcCont(true); + if (remAC > Number(What("AC"))) { + Value("AC Armor Description", remCurArm); + } else if (isStoppedCalc) { + calcStop(); + } } } } + if (armorAdd.options) { + // if removing, update the armour dropdown after removing the selection + if (!AddRemove) { + UpdateDropdown("armour"); + if (!ObjLength(CurrentVars.extraArmourDisplay)) delete CurrentVars.extraArmourDisplay; + } + SetStringifieds("vars"); // Save the new settings to a field + } } // set the shield (if more AC than current shield) or remove the shield @@ -1171,8 +1198,6 @@ function processAddShield(AddRemove, shield, weight) { if (weight !== undefined && !isNaN(weight)) shield[2] = weight; } - // grab current fields - var shieldFld = What("AC Shield Bonus Description"); if (AddRemove) { // add // see what the new AC will be var newACdefined = shield[1] !== undefined && !isNaN(shield[1]) ? shield[1] : undefined; @@ -1195,11 +1220,40 @@ function processAddShield(AddRemove, shield, weight) { } // set attacks or remove the attacks -function processAddWeapons(AddRemove, weapons) { - if (!weapons) return; - if (!isArray(weapons)) weapons = [weapons]; - for (var w = 0; w < weapons.length; w++) { - tDoc[(AddRemove ? "Add" : "Remove") + "Weapon"](weapons[w]); +function processAddWeapons(AddRemove, weaponsAdd, srcNm) { + if (!weaponsAdd ) return; + if (typeof weaponsAdd === "string") { + weaponsAdd = { select : [weaponsAdd] }; + } else if (isArray(weaponsAdd)) { + weaponsAdd = { select : weaponsAdd }; + } + srcNm = srcNm ? srcNm.toLowerCase() : 'unknownSource'; + if (weaponsAdd.options) { + if (!CurrentVars.extraWeaponsDisplay) CurrentVars.extraWeaponsDisplay = {}; + for (var i = 0; i < weaponsAdd.options.length; i++) { + var weaOption = weaponsAdd.options[i]; + var newName = srcNm + "-" + weaOption.toLowerCase(); + if (AddRemove) { + CurrentVars.extraWeaponsDisplay[newName] = weaOption; + } else { + delete CurrentVars.extraWeaponsDisplay[newName]; + } + } + // if adding, update the dropdowns before adding selection + if (AddRemove) UpdateDropdown("weapons"); + } + if (weaponsAdd.select) { + for (var w = 0; w < weaponsAdd.select.length; w++) { + tDoc[(AddRemove ? "Add" : "Remove") + "Weapon"](weaponsAdd.select[w]); + } + } + if (weaponsAdd.options) { + // if removing, update the weapon dropdowns after removing the selection + if (!AddRemove) { + UpdateDropdown("weapons"); + if (!ObjLength(CurrentVars.extraWeaponsDisplay)) delete CurrentVars.extraWeaponsDisplay; + } + SetStringifieds("vars"); // Save the new settings to a field } } @@ -1239,6 +1293,7 @@ function processArmorOptions(AddRemove, srcNm, itemArr, magical) { // if adding things but the variable doesn't exist if (AddRemove && !CurrentVars.extraArmour) CurrentVars.extraArmour = {}; + var setSelection = []; srcNm = srcNm.toLowerCase(); for (var i = 0; i < itemArr.length; i++) { var newName = srcNm + "-" + itemArr[i].name.toLowerCase(); @@ -1248,17 +1303,26 @@ function processArmorOptions(AddRemove, srcNm, itemArr, magical) { if (magical) itemArr[i].isMagicArmor = true; CurrentVars.extraArmour[newName] = itemArr[i]; ArmourList[newName] = itemArr[i]; + if (itemArr[i].selectNow) setSelection.push(itemArr[i].name); } else { + // remove as current armour if selected + if (CurrentArmour.known === newName) tDoc.resetForm(["AC Armor Description"]); // remove the entries if they exist if (CurrentVars.extraArmour[newName]) delete CurrentVars.extraArmour[newName]; if (ArmourList[newName]) delete ArmourList[newName]; } } - // if removing things and the variable is now empty + // if removing things and the variable is now empty, delete it if (!AddRemove && !ObjLength(CurrentVars.extraArmour)) delete CurrentVars.extraArmour; UpdateDropdown("armour"); // update the armour dropdown SetStringifieds("vars"); // Save the new settings to a field + if (AddRemove && setSelection.length) { + // when adding, add the armour after changing the drop-down box + for (var i = 0; i < setSelection.length; i++) { + processAddArmour(true, { select : setSelection[i] }, srcNm); + } + } } // set or remove attack options @@ -1269,6 +1333,7 @@ function processWeaponOptions(AddRemove, srcNm, itemArr, magical) { // if adding things but the variable doesn't exist if (AddRemove && !CurrentVars.extraWeapons) CurrentVars.extraWeapons = {}; + var setSelection = []; srcNm = srcNm.toLowerCase(); for (var i = 0; i < itemArr.length; i++) { var newName = srcNm + "-" + itemArr[i].name.toLowerCase(); @@ -1278,6 +1343,7 @@ function processWeaponOptions(AddRemove, srcNm, itemArr, magical) { if (magical) itemArr[i].isMagicWeapon = true; CurrentVars.extraWeapons[newName] = itemArr[i]; WeaponsList[newName] = itemArr[i]; + if (itemArr[i].selectNow) setSelection.push(itemArr[i].name); } else { // remove the entries if they exist and delete any weapons like it for (var j = FieldNumbers.attacks - 1; j >= 0; j--) { @@ -1288,10 +1354,14 @@ function processWeaponOptions(AddRemove, srcNm, itemArr, magical) { } } - // if removing things and the variable is now empty + // if removing things and the variable is now empty, delete it if (!AddRemove && !ObjLength(CurrentVars.extraWeapons)) delete CurrentVars.extraWeapons; - UpdateDropdown("weapons"); // update the weapons dropdown + UpdateDropdown("weapons"); // update the weapons dropdowns SetStringifieds("vars"); // Save the new settings to a field + if (AddRemove && setSelection.length) { + // when adding, add the weapons after changing the drop-down box + processAddWeapons(true, { select : setSelection }, srcNm); + } } // set or remove ammo options @@ -1440,6 +1510,7 @@ function applyClassFeatureText(act, fldA, oldTxtA, newTxtA, prevTxt) { // a function to recalculate the weapon entries after a change in weapon proficiencies or CurrentEvals function UpdateSheetWeapons() { + if (!CurrentUpdates.types.length) return; // some atkAdd eval might be level-dependent, so force updating the weapons when changing level and such an eval is present var isLvlDepAtkAdd = false; // iterate through all the atkAdd evals to see if any are level-dependent, but only when changing level @@ -1454,8 +1525,7 @@ function UpdateSheetWeapons() { } } - var CUflat = CurrentUpdates.types.toString(); - if (!isLvlDepAtkAdd && (!CurrentUpdates.types.length || !IsNotReset || !IsNotImport || CUflat.indexOf("attacks") == -1)) return; + if (!isLvlDepAtkAdd && (!IsNotReset || !IsNotImport || CurrentUpdates.types.toString().indexOf("attacks") == -1)) return; ReCalcWeapons(CurrentUpdates.types.indexOf("attacksprofs") !== -1, isLvlDepAtkAdd || CurrentUpdates.types.indexOf("attacksforce") !== -1); } @@ -2280,6 +2350,7 @@ function doDropDownValCalcWithChoices() { case "Validate": if (event.target.setVal !== undefined) { delete event.target.setVal; + delete event.target.setValPrepared; return; } // only in case of a validation event and not changing the value @@ -2448,7 +2519,6 @@ function ApplyMagicItem(input, FldNmbr) { var ArrayNmbr = FldNmbr - 1; var oldMI = CurrentMagicItems.known[ArrayNmbr]; var oldMIvar = CurrentMagicItems.choices[ArrayNmbr]; - var setFieldValueTo; var failedChoice = false; var doNotCommit = function(toSetVal) { @@ -2482,7 +2552,7 @@ function ApplyMagicItem(input, FldNmbr) { if (!selectMIvar) selectMIvar = AskUserOptions("Select " + aMI.name + " Type", "The '" + aMI.name + "' magic item exists in several forms. Select which form you want to add to the sheet at this time.\n\nYou can change the selected form with the little square button in the magic item line that this item is in.", parseResult[2], "radio", true); newMIvar = selectMIvar.toLowerCase(); aMIvar = aMI[newMIvar]; - setFieldValueTo = aMIvar.name ? aMIvar.name : aMI.name + " [" + selectMIvar + "]"; + event.target.setValPrepared = aMIvar.name ? aMIvar.name : aMI.name + " [" + selectMIvar + "]"; } } else if (!IsNotImport) { failedChoice = true; @@ -2509,7 +2579,7 @@ function ApplyMagicItem(input, FldNmbr) { } if (oldMI === newMI && oldMIvar === newMIvar && (!aMI || !aMI.chooseGear) && (!aMIvar || !aMIvar.chooseGear)) { - if (setFieldValueTo) event.target.setVal = setFieldValueTo; + if (event.target.setValPrepared) event.target.setVal = event.target.setValPrepared; return; // No changes were made } @@ -2523,7 +2593,7 @@ function ApplyMagicItem(input, FldNmbr) { newMIvar = ""; } else { var theMI = { - name : aMIvar.name ? aMIvar.name : setFieldValueTo ? setFieldValueTo : input + name : aMIvar.name ? aMIvar.name : event.target.setValPrepared ? event.target.setValPrepared : input } var MIattr = ["source", "type", "rarity", "attunement", "magicItemTable", "weight", "description", "descriptionLong", "descriptionFull", "calculate", "prerequisite", "prereqeval", "chooseGear", "extraTooltip", "storyItemAL"]; for (var a = 0; a < MIattr.length; a++) { @@ -2597,9 +2667,6 @@ function ApplyMagicItem(input, FldNmbr) { }; }; - // if a magic item variant was chosen, make sure this field will show that selection, now that it can't be cancelled anymore due to not meeting a prerequisite - if (setFieldValueTo) event.target.setVal = setFieldValueTo; - calcStop(); // Now stop the calculations // Remove previous magic item at the same field @@ -2733,6 +2800,9 @@ function ApplyMagicItem(input, FldNmbr) { // Set the visibility of the attuned checkbox setMIattunedVisibility(FldNmbr); + // if a magic item variant was chosen, make sure this field will show that selection (important that this is the last step) + if (event.target.setValPrepared) event.target.setVal = event.target.setValPrepared; + thermoM(thermoTxt, true); // Stop progress bar }; @@ -3642,7 +3712,7 @@ function selectMagicItemGearType(AddRemove, FldNmbr, typeObj, oldChoice, correct isItem = itemRefs[userSelected]; selectedItem = baseList[isItem].name; } else { - if (isApplyFld && event.target.setVal) selectedItem = baseList[isItem].name; + if (isApplyFld && event.target.setValPrepared) selectedItem = baseList[isItem].name; var theItemName = baseList[isItem].name.toLowerCase(); } // ammunitions are often written as plural, but we don't want that here @@ -3664,10 +3734,12 @@ function selectMagicItemGearType(AddRemove, FldNmbr, typeObj, oldChoice, correct processAddAmmo(AddRemove, [[itemToProcess ? itemToProcess : newMIname.replace(/ammunition (\+\d+)/i, "$1").replace(/(\+\d+) *\((.*?)\)/i, "$1 $2"), typeObj.ammoAmount && !isNaN(typeObj.ammoAmount) ? typeObj.ammoAmount : 1]]); break; case "weapon": - processAddWeapons(AddRemove, itemToProcess ? itemToProcess : newMIname.replace(/weapon (\+\d+)/i, "$1").replace(/(\+\d+) *\((.*?)\)/i, "$1 $2")); + var weaponName = itemToProcess ? itemToProcess : newMIname.replace(/weapon (\+\d+)/i, "$1").replace(/(\+\d+) *\((.*?)\)/i, "$1 $2"); + processAddWeapons(AddRemove, {select : [weaponName], options : [weaponName]}); break; case "armor": - processAddArmour(AddRemove, itemToProcess ? itemToProcess : newMIname.replace(/armou?r (\+\d+)/i, "$1").replace(/(\+\d+) *\((.*?)\)/i, "$1 $2")); + var armourName = itemToProcess ? itemToProcess : newMIname.replace(/armou?r (\+\d+)/i, "$1").replace(/(\+\d+) *\((.*?)\)/i, "$1 $2"); + processAddArmour(AddRemove, {select : armourName, options : [armourName]}); break; } } @@ -3692,7 +3764,7 @@ function selectMagicItemGearType(AddRemove, FldNmbr, typeObj, oldChoice, correct Value(MIflds[3], RoundTo(baseList[isItem].weight * massMod, 0.001, true)); } // set the changed name of the magic item (always do this last!) - if (newMIname !== event.value) event.target.setVal = newMIname; + if (newMIname !== event.value) event.target.setValPrepared = newMIname; } } diff --git a/_variables/ListsClasses.js b/_variables/ListsClasses.js index 896c1911..c29973e5 100644 --- a/_variables/ListsClasses.js +++ b/_variables/ListsClasses.js @@ -72,6 +72,30 @@ var FightingStyles = { } }; +var GenericClassFeatures = { + "potent spellcasting" : { + name : "Potent Spellcasting", + description : desc("I add my Wisdom modifier to the damage I deal with my cleric cantrips"), + calcChanges : { + atkCalc : [ + function (fields, v, output) { + if (v.thisWeapon[3] && /\bcleric\b/.test(v.thisWeapon[4]) && SpellsList[v.thisWeapon[3]].level === 0 && /\d/.test(fields.Damage_Die)) { + output.extraDmg += What('Wis Mod'); + }; + }, + "My cleric cantrips get my Wisdom modifier added to their damage." + ], + spellAdd : [ + function (spellKey, spellObj, spName) { + if (spellObj.psionic || spellObj.level !== 0 || spName.indexOf("cleric") == -1 || !What("Wis Mod") || Number(What("Wis Mod")) <= 0) return; + return genericSpellDmgEdit(spellKey, spellObj, "\\w+\\.?", "Wis"); + }, + "My cleric cantrips get my Wisdom modifier added to their damage." + ] + } + } +} + var Base_ClassList = { "barbarian" : { regExpSearch : /^((?=.*(marauder|barbarian|viking|(norse|tribes?|clans?)(wo)?m(a|e)n))|((?=.*(warrior|fighter))(?=.*(feral|tribal)))).*$/i, @@ -135,13 +159,13 @@ var Base_ClassList = { minlevel : 1, description : desc("Without armor, my AC is 10 + Dexterity modifier + Constitution modifier + shield"), armorOptions : [{ - regExpSearch : /justToAddToDropDown/, + regExpSearch : /justToAddToDropDownAndEffectWildShape/, name : "Unarmored Defense (Con)", source : [["SRD", 8], ["P", 48]], ac : "10+Con", - affectsWildShape : true - }], - armorAdd : "Unarmored Defense (Con)" + affectsWildShape : true, + selectNow : true + }] }, "reckless attack" : { name : "Reckless Attack", @@ -740,13 +764,13 @@ var Base_ClassList = { minlevel : 1, description : desc("Without armor and no shield, my AC is 10 + Dexterity modifier + Wisdom modifier"), armorOptions : [{ - regExpSearch : /justToAddToDropDown/, + regExpSearch : /justToAddToDropDownAndEffectWildShape/, name : "Unarmored Defense (Wis)", source : [["SRD", 26], ["P", 78]], ac : "10+Wis", - affectsWildShape : true - }], - armorAdd : "Unarmored Defense (Wis)" + affectsWildShape : true, + selectNow : true + }] }, "martial arts" : { name : "Martial Arts", @@ -2025,14 +2049,19 @@ var Base_ClassList = { function (fields, v) { if (v.baseWeaponName == 'eldritch blast') fields.Range = 300 * (v.rangeM ? v.rangeM : 1) + ' ft'; }, - "My Eldritch Blast cantrip has a range of 300 ft." + "My Eldritch Blast cantrip has a range of 300 ft.", + 50 + ], + spellAdd : [ + function (spellKey, spellObj, spName) { + if (spellKey == 'eldritch blast') { + spellObj.range = '300 ft'; + if (What("Unit System") === "metric") spellObj.range = ConvertToMetric(spellObj.range, 0.5); + } + }, + "My Eldritch Blast cantrip has a range of 300 ft.", + 50 ] - }, - spellChanges : { - "eldritch blast" : { - range : "300 ft", - changes : "My Eldritch Blast cantrip has a range of 300 ft." - } } }, "eyes of the rune keeper" : { @@ -2203,16 +2232,20 @@ var Base_ClassList = { function (fields, v) { if (v.baseWeaponName == 'eldritch blast') fields.Description += '; Target pushed back 10 ft'; }, - "When I hit a creature with my Eldritch Blast cantrip, it is pushed 10 ft away from me." + "When I hit a creature with my Eldritch Blast cantrip, it is pushed 10 ft away from me.", + 51 + ], + spellAdd : [ + function (spellKey, spellObj, spName) { + if (spellKey == 'eldritch blast') { + spellObj.description = "Spell attack beam 1d10 Force damage \u0026 push 10 ft; beams can be combined; +1 beam at CL5,11,17"; + spellObj.descriptionShorter = "Spell atk beam 1d10 Force damage \u0026 push 10 ft; can combine beams; +1 beam at CL5,11,17"; + spellObj.descriptionCantripDie = "Spell atk for `CD` beam(s), each 1d10 Force damage \u0026 push 10 ft; can combine/split beams"; + } + }, + "When I hit a creature with my Eldritch Blast cantrip, it is pushed 10 ft away from me.", + 51 ] - }, - spellChanges : { - "eldritch blast" : { - description : "Spell attack beam 1d10 Force damage \u0026 push 10 ft; beams can be combined; +1 beam at CL5,11,17", - descriptionShorter : "Spell atk beam 1d10 Force damage \u0026 push 10 ft; can combine beams; +1 beam at CL5,11,17", - descriptionCantripDie : "Spell atk for `CD` beam(s), each 1d10 Force damage \u0026 push 10 ft; can combine/split beams", - changes : "When I hit a creature with my Eldritch Blast cantrip, it is pushed 10 ft away from me." - } } }, "sculptor of flesh (prereq: level 7 warlock)" : { @@ -2712,7 +2745,7 @@ var Base_ClassSubList = { calcChanges : { atkAdd : [ function (fields, v) { - if (classes.known.cleric && classes.known.cleric.level > 7 && !v.isSpell) { + if (classes.known.cleric && v.isWeapon) { fields.Description += (fields.Description ? '; ' : '') + 'Once per turn +' + (classes.known.cleric.level < 14 ? 1 : 2) + 'd8 radiant damage'; } }, @@ -3307,9 +3340,9 @@ var Base_ClassSubList = { name : "Draconic Resilience", source : [["SRD", 45], ["P", 102]], ac : 13, - affectsWildShape : true - }], - armorAdd : "Draconic Resilience" + affectsWildShape : true, + selectNow : true + }] }, "subclassfeature6" : { name : "Elemental Affinity", diff --git a/_variables/ListsMagicItems.js b/_variables/ListsMagicItems.js index d9af546a..77a1b304 100644 --- a/_variables/ListsMagicItems.js +++ b/_variables/ListsMagicItems.js @@ -239,7 +239,6 @@ var Base_MagicItemsList = { recovery: "dawn", action : [["action", " (immunity)"]], dmgres : [ ["All", "All (nonmagical)"] ], - armorAdd : "Armor of Invulnerability", armorOptions : [{ regExpSearch : /^(?=.*armor)(?=.*invulnerability).*$/i, name : "Armor of Invulnerability", @@ -248,7 +247,8 @@ var Base_MagicItemsList = { ac : 18, stealthdis : true, weight : 65, - strReq : 15 + strReq : 15, + selectNow : true }] }, "armor of resistance" : { @@ -329,7 +329,6 @@ var Base_MagicItemsList = { allowDuplicates : true, weight: 65, cursed: true, - armorAdd : "Armor of Vulnerability", armorOptions : [{ regExpSearch : /^(?=.*armor)(?=.*vulnerability).*$/i, name : "Armor of Vulnerability", @@ -338,7 +337,8 @@ var Base_MagicItemsList = { ac : 18, stealthdis : true, weight : 65, - strReq : 15 + strReq : 15, + selectNow : true }], choices : ["Bludgeoning", "Piercing", "Slashing"], choicesNotInMenu : true, @@ -425,7 +425,7 @@ var Base_MagicItemsList = { rarity : "uncommon", magicItemTable : ["A", "B"], description : "This bag is 2 ft in diameter at the mouth, 4 ft deep, and 15 lb regardless of content. It can hold up to 500 lb, not exceeding a volume of 64 cu ft. Retrieving an item from it requires an action. If it's overloaded, pierced, or torn, it's destroyed with its contents in the Astral plane. If turned inside out, all its contents spill forth.", - descriptionLong : "This bag is 2 ft in diameter at the mouth, 4 ft deep, and 15 lb regardless of content. It can hold up to 500 lb, not exceeding a volume of 64 cu ft. Retrieving an item from it requires an action. If it is overloaded, pierced, or torn, it is destroyed, leaving its contents in the Astral plane. If it is turned inside out, all its contents spill forth unharmed. Breathing creatures inside the bag can breath for 10 minutes divided by the number of creatures in it (minimum 1 minute), after which they begin to suffocate. Placing the bag in an other extradimensional space instantly destroys both and opens a gate to the Astral Plane.", + descriptionLong : "This bag is 2 ft in diameter at the mouth, 4 ft deep, and 15 lb regardless of content. It can hold up to 500 lb, not exceeding a volume of 64 cu ft. Retrieving an item from it requires an action. If it is overloaded, pierced, or torn, it is destroyed, leaving its contents in the Astral plane. If it is turned inside out, all its contents spill forth unharmed. Breathing creatures inside the bag can breath for 10 minutes divided by the number of creatures in it (minimum 1 minute), after which they begin to suffocate. Placing the bag in another extradimensional space instantly destroys both and opens a gate to the Astral Plane.", descriptionFull : "This bag has an interior space considerably larger than its outside dimensions, roughly 2 feet in diameter at the mouth and 4 feet deep. The bag can hold up to 500 pounds, not exceeding a volume of 64 cubic feet. The bag weighs 15 pounds, regardless of its contents. Retrieving an item from the bag requires an action.\n If the bag is overloaded, pierced, or torn, it ruptures and is destroyed, and its contents are scattered in the Astral Plane. If the bag is turned inside out, its contents spill forth, unharmed, but the bag must be put right before it can be used again. Breathing creatures inside the bag can survive up to a number of minutes equal to 10 divided by the number of creatures (minimum 1 minute), after which time they begin to suffocate.\n Placing a bag of holding inside an extradimensional space created by a Heward's handy haversack, portable hole, or similar item instantly destroys both items and opens a gate to the Astral Plane. The gate originates where the one item was placed inside the other. Any creature within 10 feet of the gate is sucked through it to a random location on the Astral Plane. The gate then closes. The gate is one-way only and can't be reopened.", weight : 15, action : [["action", " (retrieve item)"]] @@ -483,7 +483,7 @@ var Base_MagicItemsList = { type : "wondrous item", rarity : "rare", magicItemTable : "G", - description : "While wearing this belt, my Con increases by 2 (to max 20), I get adv. on Cha (Persuasion) checks to interact with dwarves, adv. on saves vs. poison, resistance to poison damage, darkvision 60 ft, and known Dwarvish. Each day at dawn, there is a 50% chance I grow a full beard or my current beard becomes visibly thicker.", + description : "While wearing this belt, my Con increases by 2 (to max 20), I get adv. on Cha (Persuasion) checks to interact with dwarves, adv. on saves vs. poison, resistance to poison damage, darkvision 60 ft, and know Dwarvish. Each day at dawn, there is a 50% chance I grow a full beard or my current beard becomes visibly thicker.", descriptionFull : "While wearing this belt, you gain the following benefits:\n \u2022 Your Constitution score increases by 2, to a maximum of 20.\n \u2022 You have advantage on Charisma (Persuasion) checks made to interact with dwarves.\n\nIn addition, while attuned to the belt, you have a 50% chance each day at dawn of growing a full beard if you're capable of growing one, or a visibly thicker beard if you already have one.\n\nIf you aren't a dwarf, you gain the following additional benefits while wearing the belt:\n \u2022 You have advantage on saving throws against poison, and you have resistance against poison damage.\n \u2022 You have darkvision out to a range of 60 feet.\n \u2022 You can speak, read, and write Dwarvish.", attunement : true, languageProfs : ["Dwarvish"], @@ -1243,15 +1243,15 @@ var Base_MagicItemsList = { weight : 1, usages : 1, recovery : "dawn", - weaponsAdd : ["Dagger of Venom"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "dagger", regExpSearch : /^(?=.*dagger)(?=.*venom).*$/i, name : "Dagger of Venom", source : [["SRD", 215], ["D", 161]], description : "Finesse, light, thrown; If coated, DC 15 Con save or +2d10 poison damage \u0026 1 min poisoned", - modifiers : [1, 1] - } + modifiers : [1, 1], + selectNow : true + }] }, "dancing sword" : { name : "Dancing Sword", @@ -1532,7 +1532,6 @@ var Base_MagicItemsList = { cursed : true, languageProfs : ["Abyssal"], savetxt : { text : ["Disadv. on saves vs. demons"] }, - armorAdd : "Demon Armor", armorOptions : [{ regExpSearch : /^(?=.*demon)(?=.*armor).*$/i, name : "Demon Armor", @@ -1541,16 +1540,17 @@ var Base_MagicItemsList = { ac : "18+1", stealthdis : true, weight : 65, - strReq : 15 + strReq : 15, + selectNow : true }], - weaponsAdd: ["Demon Armor Claws"], weaponOptions: [{ baseWeapon : "unarmed strike", regExpSearch : /^(?=.*demon)(?=.*armor)(?=.*claws).*$/i, name : "Demon Armor Claws", source: [["SRD", 218], ["D", 165]], damage : [1, 8, "slashing"], - modifiers : [1, 1] + modifiers : [1, 1], + selectNow : true }] }, "dimensional shackles" : { @@ -1579,96 +1579,177 @@ var Base_MagicItemsList = { savetxt : { adv_vs : ["Dragon Frightful Presence", "Dragon Breath Weapons"], }, - armorOptions : [{ - regExpSearch : /^(?=.*dragon)(?=.*scale)(?=.*mail).*$/i, - name : "Dragon Scale Mail", - source : [["SRD", 219], ["D", 165]], - type : "medium", - ac : "14+1", - stealthdis : true, - weight : 45 - }], choices : ["Black (acid)", "Blue (lightning)", "Brass (fire)", "Bronze (lightning)", "Copper (acid)", "Gold (fire)", "Green (poison)", "Red (fire)", "Silver (cold)", "White (cold)"], choicesNotInMenu : true, "black (acid)" : { name : "Black Dragon Scale Mail", description : "This scale mail gives +1 to AC, adv. on saves against the frightful presence and breath weapons of dragons, and resistance to acid damage. As an action, I can magically discern the distance and direction to the closest black dragon within 30 miles. Once I use this action, I can't use it again until the next dawn.", - armorAdd : "Black Dragon Scale Mail", dmgres: ["Acid"], limfeaname : "Detect Black Dragon", - action : [["action", "Detect Black Dragon"]] + action : [["action", "Detect Black Dragon"]], + armorOptions : [{ + regExpSearch : /^(?=.*dragon)(?=.*scale)(?=.*mail).*$/i, + name : "Black Dragon Scale Mail", + source : [["SRD", 219], ["D", 165]], + type : "medium", + ac : "14+1", + stealthdis : true, + weight : 45, + selectNow : true + }] }, "blue (lightning)" : { name : "Blue Dragon Scale Mail", description : "This scale mail gives +1 to AC, adv. on saves against the frightful presence and breath weapons of dragons, and resistance to lightning damage. As an action, I can magically discern the distance and direction to the closest blue dragon in 30 miles. Once I use this action, I can't use it again until the next dawn.", - armorAdd : "Blue Dragon Scale Mail", dmgres: ["Lightning"], limfeaname : "Detect Blue Dragon", - action : [["action", "Detect Blue Dragon"]] + action : [["action", "Detect Blue Dragon"]], + armorOptions : [{ + regExpSearch : /^(?=.*dragon)(?=.*scale)(?=.*mail).*$/i, + name : "Blue Dragon Scale Mail", + source : [["SRD", 219], ["D", 165]], + type : "medium", + ac : "14+1", + stealthdis : true, + weight : 45, + selectNow : true + }] }, "brass (fire)" : { name : "Brass Dragon Scale Mail", description : "This scale mail gives +1 to AC, adv. on saves against the frightful presence and breath weapons of dragons, and resistance to fire damage. As an action, I can magically discern the distance and direction to the closest brass dragon within 30 miles. Once I use this action, I can't use it again until the next dawn.", - armorAdd : "Brass Dragon Scale Mail", dmgres: ["Fire"], limfeaname : "Detect Brass Dragon", - action : [["action", "Detect Brass Dragon"]] + action : [["action", "Detect Brass Dragon"]], + armorOptions : [{ + regExpSearch : /^(?=.*dragon)(?=.*scale)(?=.*mail).*$/i, + name : "Brass Dragon Scale Mail", + source : [["SRD", 219], ["D", 165]], + type : "medium", + ac : "14+1", + stealthdis : true, + weight : 45, + selectNow : true + }] }, "bronze (lightning)" : { name : "Bronze Dragon Scale Mail", description : "This scale mail gives +1 to AC, adv. on saves against the frightful presence and breath weapons of dragons, and resistance to lightning damage. As an action, I can magically discern the distance and direction to the closest bronze dragon in 30 miles. Once I use this action, I can't use it again until the next dawn.", - armorAdd : "Bronze Dragon Scale Mail", dmgres: ["Lightning"], limfeaname : "Detect Bronze Dragon", - action : [["action", "Detect Bronze Dragon"]] + action : [["action", "Detect Bronze Dragon"]], + armorOptions : [{ + regExpSearch : /^(?=.*dragon)(?=.*scale)(?=.*mail).*$/i, + name : "Bonze Dragon Scale Mail", + source : [["SRD", 219], ["D", 165]], + type : "medium", + ac : "14+1", + stealthdis : true, + weight : 45, + selectNow : true + }] }, "copper (acid)" : { name : "Copper Dragon Scale Mail", description : "This scale mail gives +1 to AC, adv. on saves against the frightful presence and breath weapons of dragons, and resistance to acid damage. As an action, I can magically discern the distance and direction to the closest copper dragon within 30 miles. Once I use this action, I can't use it again until the next dawn.", - armorAdd : "Copper Dragon Scale Mail", dmgres: ["Acid"], limfeaname : "Detect Copper Dragon", - action : [["action", "Detect Copper Dragon"]] + action : [["action", "Detect Copper Dragon"]], + armorOptions : [{ + regExpSearch : /^(?=.*dragon)(?=.*scale)(?=.*mail).*$/i, + name : "Copper Dragon Scale Mail", + source : [["SRD", 219], ["D", 165]], + type : "medium", + ac : "14+1", + stealthdis : true, + weight : 45, + selectNow : true + }] }, "gold (fire)" : { name : "Gold Dragon Scale Mail", description : "This scale mail gives +1 to AC, adv. on saves against the frightful presence and breath weapons of dragons, and resistance to fire damage. As an action, I can magically discern the distance and direction to the closest gold dragon within 30 miles. Once I use this action, I can't use it again until the next dawn.", - armorAdd : "Gold Dragon Scale Mail", dmgres: ["Fire"], limfeaname : "Detect Gold Dragon", - action : [["action", "Detect Gold Dragon"]] + action : [["action", "Detect Gold Dragon"]], + armorOptions : [{ + regExpSearch : /^(?=.*dragon)(?=.*scale)(?=.*mail).*$/i, + name : "Gold Dragon Scale Mail", + source : [["SRD", 219], ["D", 165]], + type : "medium", + ac : "14+1", + stealthdis : true, + weight : 45, + selectNow : true + }] }, "green (poison)" : { name : "Green Dragon Scale Mail", description : "This scale mail gives +1 to AC, adv. on saves against the frightful presence and breath weapons of dragons, and resistance to poison damage. As an action, I can magically discern the distance and direction to the closest green dragon in 30 miles. Once I use this action, I can't use it again until the next dawn.", - armorAdd : "Green Dragon Scale Mail", dmgres: ["Poison"], limfeaname : "Detect Green Dragon", - action : [["action", "Detect Green Dragon"]] + action : [["action", "Detect Green Dragon"]], + armorOptions : [{ + regExpSearch : /^(?=.*dragon)(?=.*scale)(?=.*mail).*$/i, + name : "Green Dragon Scale Mail", + source : [["SRD", 219], ["D", 165]], + type : "medium", + ac : "14+1", + stealthdis : true, + weight : 45, + selectNow : true + }] }, "red (fire)" : { name : "Red Dragon Scale Mail", description : "This scale mail gives +1 to AC, adv. on saves against the frightful presence and breath weapons of dragons, and resistance to fire damage. As an action, I can magically discern the distance and direction to the closest red dragon within 30 miles. Once I use this action, I can't use it again until the next dawn.", - armorAdd : "Red Dragon Scale Mail", dmgres: ["Fire"], limfeaname : "Detect Red Dragon", - action : [["action", "Detect Red Dragon"]] + action : [["action", "Detect Red Dragon"]], + armorOptions : [{ + regExpSearch : /^(?=.*dragon)(?=.*scale)(?=.*mail).*$/i, + name : "Red Dragon Scale Mail", + source : [["SRD", 219], ["D", 165]], + type : "medium", + ac : "14+1", + stealthdis : true, + weight : 45, + selectNow : true + }] }, "silver (cold)" : { name : "Silver Dragon Scale Mail", description : "This scale mail gives +1 to AC, adv. on saves against the frightful presence and breath weapons of dragons, and resistance to cold damage. As an action, I can magically discern the distance and direction to the closest silver dragon within 30 miles. Once I use this action, I can't use it again until the next dawn.", - armorAdd : "Silver Dragon Scale Mail", dmgres: ["Cold"], limfeaname : "Detect Silver Dragon", - action : [["action", "Detect Silver Dragon"]] + action : [["action", "Detect Silver Dragon"]], + armorOptions : [{ + regExpSearch : /^(?=.*dragon)(?=.*scale)(?=.*mail).*$/i, + name : "Silver Dragon Scale Mail", + source : [["SRD", 219], ["D", 165]], + type : "medium", + ac : "14+1", + stealthdis : true, + weight : 45, + selectNow : true + }] }, "white (cold)" : { name : "White Dragon Scale Mail", description : "This scale mail gives +1 to AC, adv. on saves against the frightful presence and breath weapons of dragons, and resistance to cold damage. As an action, I can magically discern the distance and direction to the closest white dragon within 30 miles. Once I use this action, I can't use it again until the next dawn.", - armorAdd : "White Dragon Scale Mail", dmgres: ["Cold"], limfeaname : "Detect White Dragon", - action : [["action", "Detect White Dragon"]] + action : [["action", "Detect White Dragon"]], + armorOptions : [{ + regExpSearch : /^(?=.*dragon)(?=.*scale)(?=.*mail).*$/i, + name : "White Dragon Scale Mail", + source : [["SRD", 219], ["D", 165]], + type : "medium", + ac : "14+1", + stealthdis : true, + weight : 45, + selectNow : true + }] } }, "dragon slayer" : { @@ -1747,7 +1828,6 @@ var Base_MagicItemsList = { descriptionFull : "While wearing this armor, you gain a +2 bonus to AC. In addition, if an effect moves you against your will along the ground, you can use your reaction to reduce the distance you are moved by up to 10 feet.", weight : 65, action : [["reaction", ""]], - armorAdd : "Dwarven Plate", armorOptions : [{ regExpSearch : /^(?=.*dwarven)(?=.*plate).*$/i, name : "Dwarven Plate", @@ -1756,7 +1836,8 @@ var Base_MagicItemsList = { ac : "18+2", stealthdis : true, weight : 65, - strReq : 15 + strReq : 15, + selectNow : true }] }, "dwarven thrower" : { @@ -1771,16 +1852,16 @@ var Base_MagicItemsList = { prereqeval : function(v) { return CurrentRace.known.indexOf('dwarf') !== -1; }, weight : 2, descriptionFull : "You gain a +3 bonus to attack and damage rolls made with this magic weapon. It has the thrown property with a normal range of 20 feet and a long range of 60 feet. When you hit with a ranged attack using this weapon, it deals an extra 1d8 damage or, if the target is a giant, 2d8 damage. Immediately after the attack, the weapon flies back to your hand.", - weaponsAdd : ["Dwarven Thrower"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "warhammer", regExpSearch : /^(?=.*dwarven)(?=.*thrower).*$/i, name : "Dwarven Thrower", source : [["SRD", 220], ["D", 167]], range : "Melee, 20/60 ft", description : "Thrown, versatile (1d10); +1d8 damage when thrown (2d8 vs. giants) and returns immediately", - modifiers : [3, 3] // add 3 to each to hit and damage because of the magical bonus - } + modifiers : [3, 3], + selectNow : true + }] }, "efreeti bottle" : { // contributed by AelarTheElfRogue name : "Efreeti Bottle", @@ -1882,14 +1963,14 @@ var Base_MagicItemsList = { description : "I gain a +1 bonus to AC while I wear this chain shirt. I am considered proficient with this armor even if I lack proficiency with medium armor.", descriptionFull : "You gain a +1 bonus to AC while you wear this armor. You are considered proficient with this armor even if you lack proficiency with medium armor.", weight : 20, - armorAdd : "Elven Chain", armorOptions : [{ regExpSearch : /^(?=.*elven)(?=.*chain).*$/i, name : "Elven Chain", source : [["SRD", 220], ["D", 168]], type : "medium", ac : "13+1", - weight : 20 + weight : 20, + selectNow : true }] }, "eversmoking bottle" : { @@ -2009,17 +2090,18 @@ var Base_MagicItemsList = { "The goat of terror becomes a giant goat for up to 3 hours. The goat can't attack, but I can remove its horns and use them as weapons. One horn becomes a +1 lance, and the other becomes a +2 longsword. Removing a horn requires an action, and the weapons disappear and the horns return when the goat reverts to figurine form. In addition, the goat radiates a 30-ft radius aura of terror while I am riding it. Any creature hostile to me that starts its turn in the aura must succeed on a DC 15 Wisdom saving throw or be frightened of the goat for 1 minute, or until the goat reverts to figurine form. The frightened creature can repeat the saving throw at the end of each of its turns, ending the effect on itself on a success. Once it successfully saves against the effect, a creature is immune to the goat's aura for the next 24 hours. Once the figurine has been used, it can't be used again until 15 days have passed." ] }], - weaponsAdd : ["Lance +1, Ivory Goat Horn", "Longsword +2, Ivory Goat Horn"], weaponOptions : [{ baseWeapon : "lance", regExpSearch : /^(?=.*ivory)(?=.*goat)(?=.*lance).*$/i, name : "Lance +1, Ivory Goat Horn", - source : [["SRD", 222], ["D", 170]] + source : [["SRD", 222], ["D", 170]], + selectNow : true }, { baseWeapon : "longsword", regExpSearch : /^(?=.*ivory)(?=.*goat)(?=.*longsword).*$/i, name : "Longsword +2, Ivory Goat Horn", - source : [["SRD", 222], ["D", 170]] + source : [["SRD", 222], ["D", 170]], + selectNow : true }] }, "marble elephant" : { @@ -2249,14 +2331,14 @@ var Base_MagicItemsList = { description : "Studded leather with +1 AC. As a bonus action, I can speak its command word and have it assume the appearance of a normal set of clothing or another armor. I decide what it looks like: style, color, and accessories, but the armor retains its bulk and weight. The illusion lasts until I use this again or remove the armor.", weight : 13, descriptionFull : "While wearing this armor, you gain a +1 bonus to AC. You can also use a bonus action to speak the armor's command word and cause the armor to assume the appearance of a normal set of clothing or some other kind of armor. You decide what it looks like, including color, style, and accessories, but the armor retains its normal bulk and weight. The illusory appearance last until you use this property again or remove the armor.", - armorAdd : "Glamoured Studded Leather", armorOptions : [{ regExpSearch : /^(?=.*glamou?r)(?=.*(studded|studs))(?=.*leather).*$/i, name : "Glamoured studded Leather", source : [["SRD", 224], ["D", 172]], type : "light", ac : "12+1", - weight : 13 + weight : 13, + selectNow : true }], action : [["bonus action", ""]] }, @@ -2308,14 +2390,14 @@ var Base_MagicItemsList = { choices : ["not attuned", "attuned (requires Belt of Giant Strength and Gauntlets of Ogre Power)"], "not attuned" : { description : "This magical maul adds a +1 bonus to attack and damage rolls made with it. It has additional features when I'm attuned to it, which requires me to wear both a belt of giant strength and gauntlets of ogre power.", - weaponsAdd : ["Hammer of Thunderbolts"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "maul", regExpSearch : /^(?=.*hammer)(?=.*thunderbolts).*$/i, name : "Hammer of Thunderbolts", source : [["SRD", 224], ["D", 173]], - modifiers : [1, 1] - } + modifiers : [1, 1], + selectNow : true + }] }, "attuned (requires belt of giant strength and gauntlets of ogre power)" : { name : "Hammer of Thunderbolts [attuned]", @@ -2331,15 +2413,15 @@ var Base_MagicItemsList = { additional : "regains 1d4+1", scores : [4, 0, 0, 0, 0, 0], scoresMaximum : [30, 0, 0, 0, 0, 0], - weaponsAdd : ["Hammer of Thunderbolts"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "maul", regExpSearch : /^(?=.*hammer)(?=.*thunderbolts).*$/i, name : "Hammer of Thunderbolts", source : [["SRD", 224], ["D", 173]], description : "Heavy, two-handed; On 20 to hit vs. Giant: DC 17 Con save or die; Expend charge to throw", - modifiers : [1, 1] - } + modifiers : [1, 1], + selectNow : true + }] } }, "hat of disguise" : { // contributed by Larry Hoy @@ -2834,8 +2916,7 @@ var Base_MagicItemsList = { usages : 1, recovery : "dawn", action : [["action", " (throw)"], ["bonus action", " (release)"]], - weaponsAdd : ["Iron Bands of Bilarro"], - weaponOptions : { + weaponOptions : [{ regExpSearch : /^(?=.*iron)(?=.*band)(?=.*(bilarro|binding)).*$/i, name : "Iron Bands of Bilarro", source : [["SRD", 228], ["D", 177]], @@ -2845,8 +2926,9 @@ var Base_MagicItemsList = { range : "60 ft", description : "Restrains Huge or smaller creature; DC 20 Strength check to break out", abilitytodamage : false, - weight : 1 - } + weight : 1, + selectNow : true + }] }, "iron flask" : { // contains contributions by Larry Hoy name : "Iron Flask", @@ -2871,14 +2953,14 @@ var Base_MagicItemsList = { weight : 2, usages : 1, recovery : "dawn", - weaponsAdd : ["Javelin of Lightning"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "javelin", regExpSearch : /^(?=.*javelin)(?=.*lightning).*$/i, name : "Javelin of Lightning", source : [["SRD", 228], ["D", 178]], - description : "Thrown; Once per dawn special attack, see item description" - } + description : "Thrown; Once per dawn special attack, see item description", + selectNow : true + }] }, "keoghtom's ointment" : { name : "Keoghtom's Ointment", @@ -2961,14 +3043,14 @@ var Base_MagicItemsList = { descriptionFull : "When you hit a fiend or an undead with this magic weapon, that creature takes an extra 2d6 radiant damage. If the target has 25 hit points or fewer after taking this damage, it must succeed on a DC 15 Wisdom saving throw or be destroyed. On a successful save, the creature becomes frightened of you until the end of your next turn.\n While you hold this weapon, it sheds bright light in a 20-foot radius and dim light for an additional 20 feet.", attunement : true, weight : 4, - weaponsAdd : ["Mace of Disruption"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "mace", regExpSearch : /^(?=.*mace)(?=.*disruption).*$/i, name : "Mace of Disruption", source : [["SRD", 229], ["D", 179]], - description : "Fiend/undead +2d6 radiant damage and if HP<26, DC 15 Wis save: fail - die, success - frightened until my next turn ends" - } + description : "Fiend/undead +2d6 radiant damage and if HP<26, DC 15 Wis save: fail - die, success - frightened until my next turn ends", + selectNow : true + }] }, "mace of smiting" : { name : "Mace of Smiting", @@ -2979,15 +3061,15 @@ var Base_MagicItemsList = { description : "This magical mace adds a +1 bonus (+3 vs. constructs) to attack and damage rolls made with it. When I roll a 20 on an attack roll, the target takes an extra 7 bludgeoning damage, or an extra 14 bludgeoning damage if it's a construct. If a construct has less than 26 HP after taking this damage, it is destroyed.", descriptionFull : "You gain a +1 bonus to attack and damage rolls made with this magic weapon. The bonus increases to +3 when you use the mace to attack a construct.\n When you roll a 20 on an attack roll made with this weapon, the target takes an extra 7 bludgeoning damage, or an extra 14 bludgeoning damage if it's a construct. If a construct has 25 hit points or fewer after taking this damage, it is destroyed.", weight : 4, - weaponsAdd : ["Mace of Smiting"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "mace", regExpSearch : /^(?=.*mace)(?=.*smiting).*$/i, name : "Mace of Smiting", source : [["SRD", 229], ["D", 179]], description : "+2 to hit/damage vs. constructs; On 20 to hit: +7 damage (+14 vs. constructs); Constructs HP<26 destroyed", - modifiers : [1,1] - } + modifiers : [1, 1], + selectNow : true + }] }, "mace of terror" : { name : "Mace of Terror", @@ -3003,13 +3085,13 @@ var Base_MagicItemsList = { usages : 3, recovery : "dawn", additional : "regains 1d3", - weaponsAdd : ["Mace of Terror"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "mace", regExpSearch : /^(?=.*mace)(?=.*terror).*$/i, name : "Mace of Terror", - source : [["SRD", 229], ["D", 180]] - } + source : [["SRD", 229], ["D", 180]], + selectNow : true + }] }, "mantle of spell resistance" : { name : "Mantle of Spell Resistance", @@ -3355,14 +3437,14 @@ var Base_MagicItemsList = { descriptionFull : 'When you nock an arrow on this bow, it whispers in Elvish, "Swift defeat to my enemies." When you use this weapon to make a ranged attack, you can, as a command phrase, say, "Swift death to you who have wronged me." The target of your attack becomes your sworn enemy until it dies or until dawn seven days later. You can have only one such sworn enemy at a time. When your sworn enemy dies, you can choose a new one after the next dawn.\n When you make a ranged attack roll with this weapon against your sworn enemy, you have advantage on the roll. In addition, your target gains no benefit from cover, other than total cover, and you suffer no disadvantage due to long range. If the attack hits, your sworn enemy takes an extra 3d6 piercing damage.\n While your sworn enemy lives, you have disadvantage on attack rolls with all other weapons.', attunement : true, weight : 2, - weaponsAdd : ["Oathbow"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "longbow", regExpSearch : /oathbow/i, name : "Oathbow", source : [["SRD", 231], ["D", 183]], - description : "Ammunition, heavy, two-handed; Vs. sworn enemy: adv, +3d6 damage, no cover/range penalties" - } + description : "Ammunition, heavy, two-handed; Vs. sworn enemy: adv, +3d6 damage, no cover/range penalties", + selectNow : true + }] }, "oil of etherealness" : { // contains contributions by AelarTheElfRogue name : "Oil of Etherealness", @@ -3509,7 +3591,6 @@ var Base_MagicItemsList = { usages : 1, recovery : "dawn", action : [["action", " (start/stop)"]], - armorAdd : "Plate Armor of Etherealness", armorOptions : [{ regExpSearch : /^(?=.*plate)(?=.*etherealness).*$/i, name : "Plate Armor of Etherealness", @@ -3518,7 +3599,8 @@ var Base_MagicItemsList = { ac : 18, stealthdis : true, weight : 65, - strReq : 15 + strReq : 15, + selectNow : true }], spellcastingBonus : { name : "once per dawn", @@ -3860,7 +3942,7 @@ var Base_MagicItemsList = { action : [["action", ""]] }, "bird" : { - description : "As an action, I can toss this token into the air and it turns into a roc. It obeys my simple commands, can't attack, can carry 500 lb while flying (16 miles per hour or 144 miles per day, as it rests 1 hour per 3 of flying), or double that at half speed. It disappears after a day, i it drops to 0 HP, or if I use an action to make it.", + description : "As an action, I can toss this token into the air to turns into a roc. It obeys my simple commands, can't attack, carries 500 lb while flying (16 miles/hour or 144 miles/day), or 1000 lb at half speed. It rests 1 hour per 3 flown. It disappears if it drops to 0 HP, after flying its max distance for a day, or if I dismiss it as an action.", descriptionFull : "This tiny object looks like a feather. You can use an action to toss the token 5 feet into the air. The token disappears and an enormous, multicolored bird takes its place. The bird has the statistics of a roc, but it obeys your simple commands and can't attack. It can carry up to 500 pounds while flying at its maximum speed (16 miles an hour for a maximum of 144 miles per day. with a one-hour rest for every 3 hours of flying), or 1,000 pounds at half that speed. The bird disappears after flying its maximum distance for a day or if it drops to 0 hit points. You can dismiss the bird as an action.", action : [["action", " (use/dismiss)"]] }, @@ -4502,8 +4584,7 @@ var Base_MagicItemsList = { usages : 3, recovery : "dawn", additional : "regains 1d3", - weaponsAdd : ["Ring of the Ram"], - weaponOptions : { + weaponOptions : [{ regExpSearch : /^(?=.*ring)(?=.*ram).*$/i, name : "Ring of the Ram", source : [["SRD", 238], ["D", 193]], @@ -4513,8 +4594,9 @@ var Base_MagicItemsList = { range : "60 ft", description : "Damage is per charge used, also pushes 5 ft away per charge used", abilitytodamage : false, - modifiers : [7, ""] - } + modifiers : [7, ""], + selectNow : true + }] }, "ring of three wishes" : { name : "Ring of Three Wishes", @@ -4647,13 +4729,13 @@ var Base_MagicItemsList = { "While wearing the Robe of the Archmagi my spell save DC and spell attack bonus each increase by 2." ] }, - armorAdd : "Robe of the Archmagi", armorOptions : [{ regExpSearch: /^(?=.*robe)(?=.*(archmage|archmagi)).*$/i, name : "Robe of the Archmagi", source : [["SRD", 239], ["D", 194]], ac : 15, - weight : 4 + weight : 4, + selectNow : true }], choices : ["Good", "Neutral", "Evil"], choicesNotInMenu : true, @@ -4759,19 +4841,19 @@ var Base_MagicItemsList = { regExpSearch : /^(?=.*rod)(?=.*lordly)(?=.*might)(?=.*axe).*$/i, name : "Rod of Lordly Might (Axe)", source : [["SRD", 240], ["D", 196]], - modifiers : [3,3] + modifiers : [3, 3] }, { baseWeapon : "mace", regExpSearch : /^(?=.*rod)(?=.*lordly)(?=.*might)(?=.*mace).*$/i, name : "Rod of Lordly Might (Mace)", source : [["SRD", 240], ["D", 196]], - modifiers : [3,3] + modifiers : [3, 3] }, { baseWeapon : "spear", regExpSearch : /^(?=.*rod)(?=.*lordly)(?=.*might)(?=.*spear).*$/i, name : "Rod of Lordly Might (Spear)", source : [["SRD", 240], ["D", 196]], - modifiers : [3,3] + modifiers : [3, 3] }], toNotesPage : [{ name : "Buttons and Other Functions", @@ -4852,8 +4934,7 @@ var Base_MagicItemsList = { descriptionFull : "This rope is 30 feet long and weighs 3 pounds. If you hold one end of the rope and use an action to speak its command word, the other end darts forward to entangle a creature you can see within 20 feet of you. The target must succeed on a DC 15 Dexterity saving throw or become restrained.\n You can release the creature by using a bonus action to speak a second command word. A target restrained by the rope can use an action to make a DC 15 Strength or Dexterity check (target's choice). On a success, the creature is no longer restrained by the rope.\n The rope has AC 20 and 20 hit points. It regains 1 hit point every 5 minutes as long as it has at least 1 hit point. If the rope drops to 0 hit points, it is destroyed.", weight : 3, action : [["action", " (entangle)"], ["bonus action", " (release)"]], - weaponsAdd : ["Rope of Entanglement"], - weaponOptions : { + weaponOptions : [{ regExpSearch : /^(?=.*rope)(?=.*entanglement).*$/i, name : "Rope of Entanglement", source : [["SRD", 241], ["D", 197]], @@ -4866,7 +4947,7 @@ var Base_MagicItemsList = { weight : 3, modifiers : [7, 0], dc : true - } + }] }, "scarab of protection" : { name : "Scarab of Protection", @@ -4893,15 +4974,15 @@ var Base_MagicItemsList = { attunement : true, weight : 3, action : [["bonus action", ""]], - weaponsAdd : ["Scimitar of Speed"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "scimitar", regExpSearch : /^(?=.*scimitar)(?=.*speed).*$/i, name : "Scimitar of Speed", source : [["SRD", 241], ["D", 199]], description : "Finesse, light; Extra attack as bonus action", - modifiers : [2, 2] - } + modifiers : [2, 2], + selectNow : true + }] }, "shield, +1, +2, or +3" : { name : "Shield, +1, +2, or +3", @@ -5385,15 +5466,15 @@ var Base_MagicItemsList = { usages : 20, recovery : "dawn", additional : "regains 2d8+4", - weaponsAdd : ["Staff of Power"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "quarterstaff", regExpSearch : /^(?=.*staff)(?=.*power).*$/i, name : "Staff of Power", source : [["SRD", 243], ["D", 202]], description : "Versatile (1d8); On hit, 1 charge for +1d6 force damage", - modifiers : [2, 2] - }, + modifiers : [2, 2], + selectNow : true + }], calcChanges : { spellCalc : [ function (type, spellcasters, ability) { @@ -5462,15 +5543,15 @@ var Base_MagicItemsList = { usages : 10, recovery : "dawn", additional : "regains 1d6+4", - weaponsAdd : ["Staff of Striking"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "quarterstaff", regExpSearch : /^(?=.*staff)(?=.*striking).*$/i, name : "Staff of Striking", source : [["SRD", 244], ["D", 203]], modifiers : [3, 3], - description : "Versatile (1d8); On hit, 1-3 charges for +1d6 force damage per charge" - } + description : "Versatile (1d8); On hit, 1-3 charges for +1d6 force damage per charge", + selectNow : true + }] }, "staff of swarming insects" : { name : "Staff of Swarming Insects", @@ -5517,14 +5598,14 @@ var Base_MagicItemsList = { prereqeval : function (v) { return classes.known.sorcerer || classes.known.warlock || classes.known.wizard ? true : false; }, - weaponsAdd : ["Staff of the Magi"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "quarterstaff", regExpSearch : /^(?=.*staff)(?=.*magi).*$/i, name : "Staff of the Magi", source : [["SRD", 244], ["D", 203]], - modifiers : [2, 2] - }, + modifiers : [2, 2], + selectNow : true + }], calcChanges : { spellCalc : [ function (type, spellcasters, ability) { @@ -5633,14 +5714,14 @@ var Base_MagicItemsList = { usages : 10, recovery : "dawn", additional : "regains 1d6+4", - weaponsAdd : ["Staff of the Woodlands"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "quarterstaff", regExpSearch : /^(?=.*staff)(?=.*woodlands).*$/i, name : "Staff of the Woodlands", source : [["SRD", 245], ["D", 204]], - modifiers : [2, 2] - }, + modifiers : [2, 2], + selectNow : true + }], calcChanges : { spellCalc : [ function (type, spellcasters, ability) { @@ -5702,15 +5783,15 @@ var Base_MagicItemsList = { attunement : true, weight : 4, action : [["action", "Staff of T\u0026L (Lightning Strike, Thunderclap, both)"]], - weaponsAdd : ["Staff of Thunder and Lightning"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "quarterstaff", regExpSearch : /^(?=.*staff)(?=.*thunder)(?=.*lightning).*$/i, name : "Staff of Thunder and Lightning", source : [["SRD", 245], ["D", 204]], description : "Versatile (1d8); Lightning: 1\xD7 per dawn, +2d6 lightning damage; Thunder: 1\xD7 per dawn DC 17 Con save or 1 round stunned", - modifiers : [2, 2] - }, + modifiers : [2, 2], + selectNow : true + }], extraLimitedFeatures : [{ name : "Staff of T\u0026L [Lightning]", usages : 1, @@ -5759,14 +5840,14 @@ var Base_MagicItemsList = { usages : 3, recovery : "dawn", additional : "regains 1d3", - weaponsAdd : ["Staff of Withering"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "quarterstaff", regExpSearch : /^(?=.*staff)(?=.*withering).*$/i, name : "Staff of Withering", source : [["SRD", 244], ["D", 203]], - description : "Versatile (1d8); On hit, 1 charge for +2d10 necrotic damage and save, see magic item" - } + description : "Versatile (1d8); On hit, 1 charge for +2d10 necrotic damage and save, see magic item", + selectNow : true + }] }, "stone of controlling earth elementals" : { name : "Stone of Controlling Earth Elementals", @@ -5822,16 +5903,16 @@ var Base_MagicItemsList = { descriptionFull : "This item appears to be a longsword hilt. While grasping the hilt, you can use a bonus action to cause a blade of pure radiance to spring into existence, or make the blade disappear. While the blade exists, this magic longsword has the finesse property. If you are proficient with shortswords or longswords, you are proficient with the sun blade.\n You gain a +2 bonus to attack and damage rolls made with this weapon, which deals radiant damage instead of slashing damage. When you hit an undead with it, that target takes an extra 1d8 radiant damage.\n The sword's luminous blade emits bright light in a 15-foot radius and dim light for an additional 15 feet. The light is sunlight. While the blade persists, you can use an action to expand or reduce its radius of bright and dim light by 5 feet each, to a maximum of 30 feet each or a minimum of 10 feet each.", weight : 3, action : [["bonus action", " (start/stop)"], ["action", " (change light)"]], - weaponsAdd : ["Sun Blade"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "longsword", regExpSearch : /^(?=.*sun)(?=.*blade).*$/i, name : "Sun Blade", source : [["SRD", 246], ["D", 205]], damage : [1, 8, "radiant"], description : "Finesse, versatile (1d10); +1d8 damage to undead", - modifiers : [2, 2] - }, + modifiers : [2, 2], + selectNow : true + }], calcChanges : { atkAdd : [ function (fields, v) { @@ -5882,8 +5963,8 @@ var Base_MagicItemsList = { rarity : "rare", magicItemTable : "H", attunement : true, - description : "When I roll a 20 to hit with this magic sword vs. a creature, it takes +14 slashing damage and I have a 5% chance of lobbing off one of its limbs. It does maximum damage vs. objects. With the command word, the blade gives bright light in a 10-ft radius \u0026 dim light in another 10 ft. " + (typePF ? "This stops if sheathed." : "The light stops when commanded again or sheathed."), - descriptionLong : "When I attack a creature with this magic sword and roll a 20 on the attack roll, that target takes an extra 14 slashing damage and I roll another d20. If that turns op 20 as well, I lob off one of the target's limbs. If the creature has no limb to sever, you lop off a portion of its body instead. When used against an object, the damage dice are maximized. In addition, I can speak the sword's command word to cause the blade to shed bright light in a 10-foot radius and dim light for an additional 10 feet. Speaking the command word again or sheathing the sword puts out the light.", + description : "When I roll a 20 to hit with this magic sword vs. a creature, it takes +14 slashing damage and I have a 5% chance of lopping off one of its limbs. It does maximum damage vs. objects. With the command word, the blade gives bright light in a 10-ft radius \u0026 dim light in another 10 ft. " + (typePF ? "This stops if sheathed." : "The light stops when commanded again or sheathed."), + descriptionLong : "When I attack a creature with this magic sword and roll a 20 on the attack roll, that target takes an extra 14 slashing damage and I roll another d20. If that turns up a 20 as well, I lop off one of the target's limbs. If the creature has no limb to sever, I lop off a portion of its body instead. When used against an object, the damage dice are maximized. In addition, I can speak the sword's command word to cause the blade to shed bright light in a 10-ft radius and dim light for an additional 10 ft. Speaking the command word again or sheathing the sword puts out the light.", descriptionFull : "When you attack an object with this magic sword and hit, maximize your weapon damage dice against the target.\n When you attack a creature with this weapon and roll a 20 on the attack roll, that target takes an extra 14 slashing damage. Then roll another d20. If you roll a 20, you lop off one of the target's limbs, with the effect of such loss determined by the DM. If the creature has no limb to sever, you lop off a portion of its body instead.\n In addition, you can speak the sword's command word to cause the blade to shed bright light in a 10-foot radius and dim light for an additional 10 feet. Speaking the command word again or sheathing the sword puts out the light.", // the SRD says 4d6 but that is incorrect chooseGear : { type : "weapon", @@ -5903,7 +5984,7 @@ var Base_MagicItemsList = { fields.Description += (fields.Description ? '; ' : '') + 'On 20 to hit: +14 damage \u0026 5% chance to sever limb; Max damage vs. objects'; } }, - 'If I include the words "of Sharpness" in a the name of a sword that deals slashing damage, it will be treated as the magic weapon Sword of Sharpness. It deals maximum damage against objects. On a roll of 20 to hit against creatures, it deals +14 slashing damage and has a 5% chance to lob off one limb.' + 'If I include the words "of Sharpness" in a the name of a sword that deals slashing damage, it will be treated as the magic weapon Sword of Sharpness. It deals maximum damage against objects. On a roll of 20 to hit against creatures, it deals +14 slashing damage and has a 5% chance to lop off one limb.' ] } }, @@ -6053,13 +6134,13 @@ var Base_MagicItemsList = { usages : 3, recovery : "dawn", additional : "regains 1d3", - weaponsAdd : ["Trident of Fish Command"], - weaponOptions : { + weaponOptions : [{ baseWeapon : "trident", regExpSearch : /^(?=.*trident)(?=.*fish)(?=.*command).*$/i, name : "Trident of Fish Command", - source : [["SRD", 247], ["D", 209]] - }, + source : [["SRD", 247], ["D", 209]], + selectNow : true + }], fixedDC : 15, spellFirstColTitle : "Ch", spellcastingBonus : { diff --git a/_variables/ListsRaces.js b/_variables/ListsRaces.js index e2f9babd..1d9c41c9 100644 --- a/_variables/ListsRaces.js +++ b/_variables/ListsRaces.js @@ -9,7 +9,7 @@ var Base_RaceList = { walk : { spd : 30, enc : 20 } }, languageProfs : ["Common", "Draconic"], - weaponOptions : { + weaponOptions : [{ regExpSearch : /^(?=.*breath)(?=.*weapon).*$/i, name : "Breath weapon", source : [["SRD", 5], ["P", 34]], @@ -20,9 +20,9 @@ var Base_RaceList = { description : "Hits all in area; Dex save, success - half damage; Usable only once per short rest", abilitytodamage : false, dc : true, - dbBreathWeapon : true - }, - weaponsAdd : ["Breath Weapon"], + dbBreathWeapon : true, + selectNow : true + }], age : " reach adulthood by 15 and live around 80 years", height : " stand well over 6 feet tall (5'6\" + 2d8\")", weight : " weigh around 240 lb (175 + 2d8 \xD7 2d6 lb)", diff --git a/_variables/ListsSpells.js b/_variables/ListsSpells.js index e2942fc0..8627304e 100644 --- a/_variables/ListsSpells.js +++ b/_variables/ListsSpells.js @@ -1416,7 +1416,7 @@ var Base_SpellsList = { components : "V,S", duration : "8 h (D)", description : "Me or 3/SL willing go to Ethereal Plane; move there, but able to perceive 60 ft into the normal plane", - descriptionFull : "You step into the border regions of the Ethereal Plane, in the area where it overlaps with your current plane. You remain in the Border Ethereal for the duration or until you use your action to dismiss the spell. During this time, you can move in any direction. If you move up or down, every foot of movement costs an extra foot. You can see and hear the plan you originated from, but everything there looks gray, and you can't see anything more than 60 feet away." + "\n " + "While on the Ethereal Plane, you can only affect and be affected by other creatures on that plane. Creatures that aren't on the Ethereal Plane can't perceive you and can't interact with you, unless a special ability or magic has given them the ability to do so." + "\n " + "You ignore all objects and effects that aren't on the Ethereal Plane, allowing you to move through objects you perceive on the plan you originated from." + "\n " + "When the spell ends, you immediately return to the plane you originated from in the spot you currently occupy. If you occupy the same spot as a solid object or creature when this happens, you are immediately shunted to the nearest unoccupied space that you can occupy and take force damage equal to twice the number of feet you are moved." + "\n " + "This spell has no effect if you cast it while you are on the Ethereal Plane or a plane that doesn't border it, such as one of the Outer Planes." + AtHigherLevels + "When you cast this spell using a spell slot of 8th level or higher, you can target up to three willing creatures (including you) for each slot level above 7th. The creatures must be within 10 feet of you when you cast the spell." + descriptionFull : "You step into the border regions of the Ethereal Plane, in the area where it overlaps with your current plane. You remain in the Border Ethereal for the duration or until you use your action to dismiss the spell. During this time, you can move in any direction. If you move up or down, every foot of movement costs an extra foot. You can see and hear the plane you originated from, but everything there looks gray, and you can't see anything more than 60 feet away." + "\n " + "While on the Ethereal Plane, you can only affect and be affected by other creatures on that plane. Creatures that aren't on the Ethereal Plane can't perceive you and can't interact with you, unless a special ability or magic has given them the ability to do so." + "\n " + "You ignore all objects and effects that aren't on the Ethereal Plane, allowing you to move through objects you perceive on the plane you originated from." + "\n " + "When the spell ends, you immediately return to the plane you originated from in the spot you currently occupy. If you occupy the same spot as a solid object or creature when this happens, you are immediately shunted to the nearest unoccupied space that you can occupy and take force damage equal to twice the number of feet you are moved." + "\n " + "This spell has no effect if you cast it while you are on the Ethereal Plane or a plane that doesn't border it, such as one of the Outer Planes." + AtHigherLevels + "When you cast this spell using a spell slot of 8th level or higher, you can target up to three willing creatures (including you) for each slot level above 7th. The creatures must be within 10 feet of you when you cast the spell." }, "evard's black tentacles" : { name : "Evard's Black Tentacles", diff --git a/additional content syntax/_common attributes.js b/additional content syntax/_common attributes.js index 1ca48bd3..d2847aba 100644 --- a/additional content syntax/_common attributes.js +++ b/additional content syntax/_common attributes.js @@ -416,10 +416,12 @@ weaponProfs : [ Add the names of weapons as they appear in the WeaponsList object. Alternatively, you can use a grouping of weapons, as their 'list' attribute says, for example 'firearm'. - Alternatively, you can use types of weapons, as their 'type' attribute says, for example 'Improvised Weapons'. + Alternatively, you can use types of weapons, as their 'type' attribute says, for example 'Improvised Weapons'. For example the High Elf weapon proficiency looks like this: weaponProfs : [false, false, ["longsword", "shortsword", "longbow", "shortbow"]], + + If you don't want to add individual weapon proficiencies, you can simply not set this weaponProfs 3rd entry, or set this to `false`, an empty string `""`, or `0`. */ ], @@ -428,28 +430,105 @@ weaponProfs : [ // >>> Weapons & Armour >>> // // >>>>>>>>>>>>>>>>>>>>>>>> // -weaponsAdd : ["Bite", "Longsword +2"], +weaponsAdd : ["Bite", "Longsword +2"], // legacy, before v13.1.14 +weaponsAdd : { + select : ["Bite", "Rusty Greataxe"], + options : ["Longsword +2", "Rusty Greataxe"] +}, /* weaponsAdd // OPTIONAL // - TYPE: array (variable length) - USE: adds each string in the array to one of the attack drop-downs on the 1st page - - This is an array of strings. Each string will be added to the attack section. - An entry will only be added if there is space left in the attack section and it isn't already present. - The strings will be added exactly as you write them here, capitalisation and all. - - If a feature with this attribute is removed, these attack entries will be removed as well. + TYPE: object + USE: add attack(s) to and/or edit the available options in 1st page attack section + CHANGE: v13.1.14 (changed from array to object) + + This does not add automation for the added attack selections or options. + If you want to add automation for an attack option, then don't use this attribute, + but use `weaponOptions` (see below). That can also add it to the current selection. + + This is an object with two possible attributes, each is optional. + `select` + OPTIONAL + TYPE: array of strings + USE: fill 1st page attack lines with strings + + Each string will be added to the attack section. + An entry will only be added if there is space left in the attack section and + it isn't already present. + The string will be added exactly as written, capitalisation and all. + + If no selections have to be added to attack sections, then + don't include this attribute. + + `options` + OPTIONAL + TYPE: array of strings + USE: add options to 1st page attack drop-down boxes + + Each string in the array will be added as an option in the attack drop-down boxes + on the 1st page. + Each will be added at the top of list, along with those added by + `weaponOptions` (see below), and sorted alphabetically. + The strings will be added exactly as written, capitalisation and all. + + If no options have to be added to the list in the drop-down box, then + don't include this attribute. + + If a feature with this attribute is removed, these attack selections/options + will be removed as well. + + >> Backwards compatible << + Before v13.1.14, this was an array of strings, not an object. + If `weaponsAdd` is an array, it will be treated as if that array was set for the + `select` attribute, thus preserving the functionality from v13.1.13 and earlier. */ -armorAdd : "Natural Armor", +armorAdd : "Natural Armor", // legacy, before v13.1.14 +armorAdd : { + select : "Breastplate +1", + options : ["Glamoured Studded Leather", "Unarmored Defense (Con)"] +}, /* armorAdd // OPTIONAL // - TYPE: string - USE: sets the string as the value for the armour drop-down on the 1st page - - The armour will only be set if there is currently no armour selected on the 1st page, or - if the currently selected armour gives a lower AC total than this armour. - The string will be added exactly as you write it here, capitalisation and all. - - If a feature with this attribute is removed, this armour will be removed as well. + TYPE: object + USE: select armor as current and/or edit the available options in the drop-down + CHANGE: v13.1.14 (changed from string to object) + + This does not add automation for the added armour selection or options. + If you want to add automation for an armour option, then don't use this attribute, + but use `armorOptions` (see below). That can also add it to the current selection. + + This is an object with two possible attributes, each is optional. + `select` + OPTIONAL + TYPE: string + USE: sets the value for the armour drop-down on the 1st page + + The armour will only be set if there is currently no armour selected, or + if the currently selected armour gives a lower AC total than this armour. + The string will be added exactly as you write it here, capitalisation and all. + + If nothing has to change about the current armour selection, then + don't include this attribute. + + `options` + OPTIONAL + TYPE: array of strings + USE: add options to 1st page armour drop-down box + + Each string in the array will be added as an option in the armour drop-down box + on the 1st page. + Each will be added at the top of list, along with those added by + `armorOptions` (see below), and sorted alphabetically. + The strings will be added exactly as written, capitalisation and all. + + If no options have to be added to the list in the drop-down box, then + don't include this attribute. + + If a feature with this attribute is removed, the selection/options + will be removed as well. + + >> Backwards compatible << + Before v13.1.14, this was a string, not an object. + If `armorAdd` is a string, it will be treated as if that string was set for the + `select` attribute, thus preserving the functionality from v13.1.13 and earlier. */ shieldAdd : "Wooden Buckler", @@ -517,9 +596,16 @@ armorOptions : [{ /* ArmourList object, see "armor (ArmourList).js" syntax file /* armorOptions // OPTIONAL // TYPE: array of objects (variable length) USE: adds each object in the array to the ArmourList variable + CHANGE: v13.1.14 (added `selectNow` attribute) The syntax of the objects is not explained here, but in the "armor (ArmourList).js" syntax file. + Since v13.1.14, objects in the `armorOptions` array can use the `selectNow` attribute. + This attribute is also explained in the "armor (ArmourList).js" syntax file. + Adding `selectNow : true` will cause the armour to be immediately select on the 1st page, + but only if it grants higher AC than the current selected armour. + It also means that you don't need to include the `armorAdd` attribute as well. + This way you can have a feature add a type of armour to the automation. It will also be added at the top of options in the armour field drop-down. This will result in having the armour only available if the feature is present. @@ -529,9 +615,17 @@ weaponOptions : [{ /* WeaponsList object, see "weapon (WeaponsList).js" syntax f /* weaponOptions // OPTIONAL // TYPE: array of objects (variable length) USE: adds each object in the array to the WeaponsList variable + CHANGE: v13.1.14 (added `selectNow` attribute) The syntax of the objects is not explained here, but in the "weapon (WeaponsList).js" syntax file. + Since v13.1.14, objects in the `weaponOptions` array can use the `selectNow` attribute. + This attribute is also explained in the "weapon (WeaponsList).js" syntax file. + Adding `selectNow : true` will cause the weapon to be immediately added to the selection + on the 1st page, if there is space to do so. + It also means that you don't need to include the `weaponsAdd` attribute + next to this attribute. + This way you can have a feature add a type of weapon/attack to the automation. It will also be added at the top of options in each attack field drop-down. This will result in having the weapon/attack only available if the feature is present. @@ -1243,16 +1337,17 @@ spellcastingBonusElsewhere : { Normally, the automation will only influence spells known for spellcasting gained from the parent object. With this attribute, you can add known and/or bonus spells to another spellcasting source. - For example, you could have a magic item spellbook add spells to the spellbook of a wizard. That way - they aren't displayed in their own header on the spell sheet pages, but as part of the wizard's spells. + For example, you could have a magic item spellbook add spells to the spellbook of a wizard. + That way they aren't displayed in their own header on the spell sheet pages, + but as part of the wizard's spells. - To do this, the object must contain the `addTo` attribute and either or both the `spellcastingBonus` - and `addToKnown` attributes. + To do this, the object must contain the `addTo` attribute and either or both the + `spellcastingBonus` and `addToKnown` attributes. These attributes are discussed individually below. Note that you should not use this if you want to add bonus spells to spellcasting from a parent object. - For example, don't use this for a subclass feature that adds a bonus spell for that class', instead - use `spellcastingBonus`, see above. + For example, don't use this for a subclass feature that adds a bonus spell for its class, + but instead use `spellcastingBonus`, see above. */ addTo : "wizard", /* addTo // REQUIRED // @@ -1279,8 +1374,8 @@ spellcastingBonusElsewhere : { Be aware that this spellcastingBonus will be added to the spellcasting defined in `addTo` above. Be careful, because you could overwrite somethings like which spellcasting ability is used. - The `spellcastingBonusElsewhere` object requires to have either or both the `spellcastingBonus` - or `addToKnown` attribute to be present. + The `spellcastingBonusElsewhere` object won't work if neither the `spellcastingBonus` + attribute nor the `addToKnown` attribute are present. */ addToKnown : [], @@ -1288,25 +1383,28 @@ spellcastingBonusElsewhere : { TYPE: array (variable length) of spell object names as used in the SpellsList object USE: which spells should be added to the spells known / spellbook - Unlike the `spellcastingBonus` attribute above, the spells listed here will be directly added - to the known cantrips/spells. + Unlike the `spellcastingBonus` attribute above, the spells listed here will be directly + added to the known cantrips/spells. This comes with the following limitations/considerations: - * Only spellscasting classes have known spells, feats, magic items, and races only have - 'bonus' spells. To add spells to those kind of entries, use the `spellcastingBonus` attribute. - * Spellcasting classes that always know all their spells (e.g. cleric, druid, paladin), can't - have spells added this way to their known spells (cantrips will still work). + * Only spellscasting classes can have known spells (but not all do). + Feats, magic items, and races only have 'bonus' spells. + To add spells to those kind of entries, use the `spellcastingBonus` attribute. + * Spellcasting classes that always know all their spells (e.g. cleric, druid, paladin), + can't have spells added this way to their known spells (cantrips will still work). For those kind of classes, use `calcChanges.spellList`. - * The sheet only has space for 20 cantrips and 20 spells known. If the spellcaster already has - known spells and this list would increase the number above 20, the access spells will be lost. - This limitation does not apply to classes that use a spellbook, as a spellbook can have an - unlimited number of spells. + * The sheet only has space for 20 cantrips and 20 spells known. If the spellcaster + already has known spells and this list would increase the number above 20, + the access spells will be lost. + This limitation does not apply to classes that use a spellbook, as a spellbook can + have an unlimited number of spells. Every class can still only have a maximum of 20 known cantrips, though. - * These added spells must still adhere to the normal restrictions of the spell list available for - the class. If you want to go beyond that (for example, add a wizard spell to a cleric), + * These added spells must still adhere to the normal restrictions of the spell list + available for the class. + If you want to go beyond that (for example, add a wizard spell to a cleric), you'll also have to change the available spell list using `calcChanges.spellList`. - The `spellcastingBonusElsewhere` object requires to have either or both the `spellcastingBonus` - or `addToKnown` attribute to be present. + The `spellcastingBonusElsewhere` object won't work if neither the `spellcastingBonus` + attribute nor the `addToKnown` attribute are present. */ countsTowardsKnown : true diff --git a/additional content syntax/armor (ArmourList).js b/additional content syntax/armor (ArmourList).js index e7ec8745..fd5b624d 100644 --- a/additional content syntax/armor (ArmourList).js +++ b/additional content syntax/armor (ArmourList).js @@ -36,8 +36,8 @@ Remarks: This syntax is also used for objects in the 'armorOptions' attribute found in '_common attributes.js'. For the 'armorOptions', you can disregard the object name and ArmourList variable. - Note that if you want a class feature, race, racial trait, feat, background, or magic item to add an armor, - you should be using the 'armorOptions' attribute. + Note that if you want a class feature, race, racial trait, feat, background, or magic item to + add an armor, you should be using the 'armorOptions' attribute. Sheet: v13.0.6 and newer @@ -305,4 +305,21 @@ ArmourList["purple mail"] = { Setting this to false is the same as not including this attribute. */ + selectNow : true, +/* selectNow // OPTIONAL // + TYPE: boolean + USE: whether (true) or not (false) this armour should immediately be selected + ADDED: v13.1.14 + + This attribute only has an effect on armour added through the `armorOptions` common attribute + (see '_common attributes.js'). + + By setting this attribute to `true`, it is no longer necessary to include the + `armorAdd` attribute as well. + + This attribute has no effect outside of `armorOptions`. + For armour added directly in the ArmourList, this attribute will be ignored. + + Setting this to false is the same as not including this attribute. +*/ } diff --git a/additional content syntax/weapon (WeaponsList).js b/additional content syntax/weapon (WeaponsList).js index 93fd230e..9a841bb8 100644 --- a/additional content syntax/weapon (WeaponsList).js +++ b/additional content syntax/weapon (WeaponsList).js @@ -38,8 +38,8 @@ Remarks: This syntax is also used for objects in the 'weaponOptions' attribute found in '_common attributes.js'. For the 'weaponOptions', you can disregard the object name and WeaponsList variable. - Note that if you want a class feature, race, racial trait, feat, background, or magic item to add a weapon/attack, - you should be using the 'weaponOptions' attribute. + Note that if you want a class feature, race, racial trait, feat, background, or magic item to + add a weapon/attack, you should be using the 'weaponOptions' attribute. Sheet: v13.0.6 and newer @@ -536,5 +536,22 @@ WeaponsList["sword of purple"] = { By linking a weapon to a base weapon those scripts that would affect the base weapon will also affect this weapon. Setting this to an empty string ("") is the same as not including this attribute. +*/ + selectNow : true, +/* selectNow // OPTIONAL // + TYPE: boolean + USE: whether (true) or not (false) this weapon should immediately be selected + ADDED: v13.1.14 + + This attribute only has an effect on weapons added through the `weaponOptions` common attribute + (see '_common attributes.js'). + + By setting this attribute to `true`, it is no longer necessary to include the + `weaponsAdd` attribute as well. + + This attribute has no effect outside of `weaponOptions`. + For armour added directly in the WeaponsList, this attribute will be ignored. + + Setting this to false is the same as not including this attribute. */ } diff --git a/additional content/Classes/Battlemage [Luke Arndt's work, transcribed by MPMB].js b/additional content/Classes/Battlemage [Luke Arndt's work, transcribed by MPMB].js index 49504b96..545f11ee 100644 --- a/additional content/Classes/Battlemage [Luke Arndt's work, transcribed by MPMB].js +++ b/additional content/Classes/Battlemage [Luke Arndt's work, transcribed by MPMB].js @@ -18,7 +18,7 @@ */ var iFileName = "Battlemage [Luke Arndt's work, transcribed by MPMB].js"; -RequiredSheetVersion("13.0.6"); +RequiredSheetVersion("13.1.14"); SourceList["LA:BM"] = { name : "Luke Arndt: Battlemage (v4.0)", @@ -483,7 +483,6 @@ AddSubClass("battlemage", "mystic marksman", { "I can throw any small object that fits into my hand (e.g. coins, cards) as a magical dart", "I double the range of all of my thrown weapons and deal 1d8 damage with them" ]), - weaponsAdd : ["Arcane Throw"], weaponOptions : [{ baseWeapon : "dart", regExpSearch : /^(?=.*arcane)(?=.*throw).*$/i, @@ -491,7 +490,8 @@ AddSubClass("battlemage", "mystic marksman", { source : ["LA:BM", 4], damage : [1, 8, "piercing"], description : "Thrown, finesse; Counts as magical; Objects fitting in one hand", - weight : "" + weight : "", + selectNow : true }], calcChanges : { atkAdd : [ @@ -573,7 +573,6 @@ AddSubClass("battlemage", "mystic marksman", { "All in the 60-ft long, 1-ft wide line must make a Dex save or take the attack's damage", "The energy dice are added as lightning damage; The line ignores 1/2 and 3/4 cover" ]), - weaponsAdd : ["Arcane Puncture"], weaponOptions : [{ isArcanePuncture : true, regExpSearch : /^(?=.*arcane)(?=.*puncture).*$/i, @@ -585,7 +584,8 @@ AddSubClass("battlemage", "mystic marksman", { range : "60-ft line", description : "Dex save to avoid; With ranged weapon attack; Damage is weapon damage + energy dice expended (3+)", abilitytodamage : false, - dc : true + dc : true, + selectNow : true }], calcChanges : { atkAdd : [ @@ -870,14 +870,14 @@ AddSubClass("battlemage", "spell dancer", { source : ["LA:BM", 7], minlevel : 3, description : "\n " + "Without armor and no shield, my AC is 10 + Dexterity modifier + Intelligence modifier", - armorOptions : { - regExpSearch : /justToAddToDropDown/, + armorOptions : [{ + regExpSearch : /justToAddToDropDownAndEffectWildShape/, name : "Unarmored Defense (Int)", source : ["LA:BM", 7], ac : "10+Int", - affectsWildShape : true - }, - armorAdd : "Unarmored Defense (Int)" + affectsWildShape : true, + selectNow : true + }] }, "subclassfeature6" : { name : "Defensive Riposte", diff --git a/additional content/Classes/Dragon Knight [Rain-Junkie's work, transcribed by MPMB].js b/additional content/Classes/Dragon Knight [Rain-Junkie's work, transcribed by MPMB].js index 22722721..be5c66a4 100644 --- a/additional content/Classes/Dragon Knight [Rain-Junkie's work, transcribed by MPMB].js +++ b/additional content/Classes/Dragon Knight [Rain-Junkie's work, transcribed by MPMB].js @@ -34,7 +34,7 @@ */ var iFileName = "Dragon Knight [Rain-Junkie's work, transcribed by MPMB].js"; -RequiredSheetVersion('13.1.11'); +RequiredSheetVersion('13.1.14'); SourceList["RJ:DK"] = { name : "/u/Rain-Junkie: Dragon Knight (v8.1)", @@ -1180,9 +1180,9 @@ ClassList["dragon knight"] = { name : "Draconic Nature: Scales", source : [["RJ:DK", 6]], ac : "10+Cha", - affectsWildShape : true - }], - armorAdd : "Draconic Nature: Scales" + affectsWildShape : true, + selectNow : true + }] }, "eyes (perception and investigation)" : { name : "Draconic Nature: Eyes", diff --git a/additional content/Classes/Elementalist [2CGaming's work, transcribed by MPMB].js b/additional content/Classes/Elementalist [2CGaming's work, transcribed by MPMB].js index 3f72683e..393f7436 100644 --- a/additional content/Classes/Elementalist [2CGaming's work, transcribed by MPMB].js +++ b/additional content/Classes/Elementalist [2CGaming's work, transcribed by MPMB].js @@ -21,7 +21,7 @@ */ var iFileName = "Elementalist [2CGaming's work, transcribed by MPMB].js"; -RequiredSheetVersion('13.1.13'); +RequiredSheetVersion('13.1.14'); SourceList["ELCC"] = { name : "Epic Legacy Campaign Codex", @@ -409,7 +409,6 @@ AddSubClass("elementalist", "air", { return (n < 6 ? 1 : n < 10 ? 2 : n < 14 ? 3 : n < 18 ? 4 : 5) + 'd6 bludgeoning damage' }), action : [["action", ""]], - weaponsAdd : ["Guiding Wind Blast"], weaponOptions : [{ regExpSearch : /^(?=.*guiding)(?=.*wind)(?=.*blast).*$/i, name : "Guiding Wind Blast", @@ -420,7 +419,8 @@ AddSubClass("elementalist", "air", { description : "Ranged spell attack; Or add damage to ally's ranged weapon attack", damage : [1, 6, "bludgeoning"], abilitytodamage : false, - isGuidingWindBlast : true + isGuidingWindBlast : true, + selectNow : true }], calcChanges : { atkAdd : [ @@ -552,7 +552,6 @@ AddSubClass("elementalist", "earth", { "After I finish a long rest, I can gain 4 times my elementalist level in temporary hit points", "I can make melee spell attacks instead of unarmed strikes, dealing +" + elementalistAbilityAbbr + " mod damage" ]), - weaponsAdd : ["Stone Mantle Strike"], weaponOptions : [{ baseWeapon : "unarmed strike", regExpSearch : /^(?=.*stone)(?=.*mantle)(?=.*strike).*$/i, @@ -561,7 +560,8 @@ AddSubClass("elementalist", "earth", { ability : elementalistAbility, type : "Spell", description : "Melee spell attack", - damage : ["1+Str", "", "bludgeoning"] + damage : ["1+Str", "", "bludgeoning"], + selectNow : true }], additional : levels.map(function (n) { return (n * 4) + " temp HP"; @@ -805,7 +805,6 @@ AddSubClass("elementalist", "water", { return (n < 6 ? 1 : n < 10 ? 2 : n < 14 ? 3 : n < 18 ? 4 : 5) + 'd4 necrotic damage' }), action : [["action", ""]], - weaponsAdd : ["Siphoning Strike"], weaponOptions : [{ regExpSearch : /^(?=.*siphoning)(?=.*strike).*$/i, name : "Siphoning Strike", @@ -816,7 +815,8 @@ AddSubClass("elementalist", "water", { description : "Melee spell attack; Ally in area of influence heals same amount as damage dealt", damage : [1, 4, "necrotic"], abilitytodamage : false, - isSiphoningStrike : true + isSiphoningStrike : true, + selectNow : true }], calcChanges : { atkAdd : [ diff --git a/additional content/Classes/Witch [William Russell's work, transcribed by MPMB].js b/additional content/Classes/Witch [William Russell's work, transcribed by MPMB].js index 66363a1e..05c32fa2 100644 --- a/additional content/Classes/Witch [William Russell's work, transcribed by MPMB].js +++ b/additional content/Classes/Witch [William Russell's work, transcribed by MPMB].js @@ -20,7 +20,7 @@ */ var iFileName = "Witch [William Russell's work, transcribed by MPMB].js"; -RequiredSheetVersion("13.1.3"); +RequiredSheetVersion("13.1.14"); SourceList["WR:W"] = { name : "William Russell: Witch", @@ -586,14 +586,14 @@ AddSubClass("witch-wr", "shadow tradition", { "My look changes as I gain stringy hair, pale skin, dark eyes, and long, sharp teeth", "I can use my sharp teeth to make unarmed strikes dealing 1d4 piercing damage" ]), - weaponOptions : { + weaponOptions : [{ baseWeapon : "unarmed strike", regExpSearch : /\bbite\b/i, name : "Bite", source : [["WR:W", 8]], - damage : [1, 4, "piercing"] - }, - weaponsAdd : ["Bite"] + damage : [1, 4, "piercing"], + selectNow : true + }] }, "subclassfeature5" : { name : "Shadowborne", diff --git a/additional content/Races/Abishai [GarzettDragon's work, transcribed by MPMB].js b/additional content/Races/Abishai [GarzettDragon's work, transcribed by MPMB].js index 1e5a5af9..0ba8566e 100644 --- a/additional content/Races/Abishai [GarzettDragon's work, transcribed by MPMB].js +++ b/additional content/Races/Abishai [GarzettDragon's work, transcribed by MPMB].js @@ -16,7 +16,7 @@ */ var iFileName = "Abishai [GarzettDragon's work, transcribed by MPMB].js"; -RequiredSheetVersion(13.1); +RequiredSheetVersion("13.1.14"); RaceList["abishai"] = { regExpSearch : /abishai/i, @@ -33,14 +33,14 @@ RaceList["abishai"] = { vision : [["Darkvision", 120]], savetxt : { immune : ["poison", "disease"] }, scores : [0, 0, 2, 0, 0, 1], - armorOptions : { + armorOptions : [{ regExpSearch : /^(?=.*natural)(?=.*armou?r).*$/i, name : "Natural Armor", source : [["HB", 0]], ac : "10+Con+Cha", - dex : -10 - }, - armorAdd : "Natural Armor", + dex : -10, + selectNow : true + }], abilitySave : 6, trait : [ "Abishai (+2 Constitution, +1 Charisma)",