New feature: AutoEffects, part 6

Configures all autorolls use to use AutoEffects, including all attack/block/evade rolls, Defeated, Staggered, Damaged, Panic, Combat start, Round start and Skills
This commit is contained in:
BeautiDemise
2024-07-27 03:07:40 +02:00
parent 3d67ccbe41
commit 7861e75c81
+362 -307
View File
@@ -10690,6 +10690,10 @@ on("change:StagRes", function() {
setAttrs({"StaggerState":"Staggered"});
/* AutoScripts */
resetConditionals();
AutoScriptMain("", "Staggered");
} /* Value check end */
@@ -10788,6 +10792,10 @@ on("change:SP", function() {
if(currentsan <= 0 && panicstate == "0"){
setAttrs({"PanicState":"Panic"});
/* AutoScripts */
resetConditionals();
AutoScriptMain("", "Panic");
}
else if(currentsan > 0 && panicstate != "0"){
@@ -10798,7 +10806,7 @@ on("change:SP", function() {
} /* AutoDetect check end */
});
});
});
/* Auto: HP related updates (Detect Defeat, Detect EGO activation) */
@@ -10824,6 +10832,10 @@ on("change:HP", function() {
setAttrs({"DefeatState":"Defeated"});
/* AutoScripts */
resetConditionals();
AutoScriptMain("", "Defeated");
} /* Defeat check end */
});
@@ -11621,7 +11633,7 @@ on("change:skillSelect", function() {
/* Get IDs/names */
getAttrs(["skillSelect"], function(values){
let buttonid = values.skillSelect;
let buttonid = values.skillSelect;
let skillcat = buttonid.split('S')[0];
let name = buttonid + "Name";
@@ -11929,6 +11941,9 @@ getSectionIDs(`repeating_global`, idarray => {
});
});
/* AutoScripts */
resetConditionals();
AutoScriptMain("", "Round start");
});
@@ -12109,9 +12124,9 @@ getAttrs(["Bleed", "bleedResist", "bleedResist_ego", "distortState", "egoActiveS
on('clicked:rollCombat', (info) => {
/* Preparing values */
/* Get IDs/names */
let buttonid = info.htmlAttributes.id.split('_')[1];
let rawcheck = info.htmlAttributes.id.split('_')[2];
let numcheck = info.htmlAttributes.id.split('_')[3];
let buttonid = info.htmlAttributes.id.split('_')[1];
let rawcheck = info.htmlAttributes.id.split('_')[2];
let numcheck = info.htmlAttributes.id.split('_')[3];
let name = buttonid + "Name";
let type = buttonid + "Type";
@@ -12198,7 +12213,11 @@ on('clicked:rollCombat', (info) => {
getSectionIDs(`repeating_global`, idarray => {
let id = `repeating_global_${idarray[0]}`;
getAttrs(["egoActiveState", "settingSimpleDisplay", "settingWhisperRolls", "settingWhisperTarget", "settingMultihitFull", `${id}_multiPenalty`, `${id}_multiStyle`, "character_name", "advState", "difficulty", "skillSelect", "baseActNum", "Light", "difficulty", "Endurance", "Disarm", "Strength", "Feeble", "evdPositive", "evdNegative", "advNum", "disadvNum", "attPower", "defPower", "evdPower", "selectName", "selectLight", "selectType", "selectDice1", "selectDice2", "selectDice3", "selectEffect", "distortWeaponDice1", "distortWeaponDice2", "distortWeaponDice3", "distortDefDice1", "distortDefDice2", "distortDefDice3", "distortEvdDice1", "distortEvdDice2", "distortEvdDice3", "distortEffect", "distortEffect2", "settingMultihitUses", "settingHideUses", `${name}`, `${type}`, `${range}`, `${effect}`, `${diceA}`, `${diceB}`, `${diceC}`, `${uses}`, `${usesmax}`, `${usetype}`], function(values) {
getAttrs(["egoActiveState", "settingSimpleDisplay", "settingWhisperRolls", "settingWhisperTarget", "settingMultihitFull", `${id}_multiPenalty`, `${id}_multiStyle`, "character_name", "advState", "difficulty", "skillSelect", "baseActNum", "Light",
"difficulty", "Endurance", "Disarm", "Strength", "Feeble", "evdPositive", "evdNegative", "advNum", "disadvNum", "attPower", "defPower", "evdPower",
"selectName", "selectLight", "selectType", "selectDice1", "selectDice2", "selectDice3", "selectEffect",
"distortWeaponDice1", "distortWeaponDice2", "distortWeaponDice3", "distortDefDice1", "distortDefDice2", "distortDefDice3", "distortEvdDice1", "distortEvdDice2", "distortEvdDice3", "distortEffect", "distortEffect2", "settingMultihitUses", "settingHideUses",
`${name}`, `${type}`, `${range}`, `${effect}`, `${diceA}`, `${diceB}`, `${diceC}`, `${uses}`, `${usesmax}`, `${usetype}`,], function(values) {
let currentlight = parseInt(values.Light);
let newlight = parseInt(values.Light);
@@ -12353,20 +12372,51 @@ getSectionIDs(`repeating_global`, idarray => {
}
}
getAttrs([`${buttonid}AutoScript`, "outfitAutoScript", "egoAutoScript", `${skillselect}AutoScript`], function(values) {
/* AutoScripts */
let AutoScript = "";
let triggerType = "None";
/* Get AutoScript from taken action */
switch (buttonid) {
case "def": AutoScript = values.outfitAutoScript; break;
case "evd": AutoScript = values.outfitAutoScript; break;
case "egoDef": AutoScript = values.egoAutoScript; break;
case "egoEvd": AutoScript = values.egoAutoScript; break;
default: AutoScript = values[`${buttonid}AutoScript`]; break;
}
/* Get trigger type if any */
switch (basetype) {
case "Attack": triggerType = "Offensive"; break;
case "Defend": triggerType = "Block"; break;
case "Evade": triggerType = "Evade"; break;
}
/* Get skill AutoAcript if any */
if (skillselect != undefined || skillselect != "0") {
AutoScript += values[`${skillselect}AutoScript`];
}
/* Clean AutoScript. Remove nested and undefined */
AutoScript = AutoScript.replace(/\[([#][^]+[#])\]/g, "");
AutoScript = AutoScript.replace("undefined", "");
resetConditionals();
AutoScriptMain(AutoScript, triggerType);
/* Power */
let activepower = "0";
if(basetype == "Attack"){
activepower = parseInt(values.attPower) + parseInt(values.Strength) - parseInt(values.Feeble);
attackmessage = weapontype + " | " + weaponrange + weaponuse + skillmass + "<br>";
activepower = parseInt(values.attPower) + parseInt(values.Strength) - parseInt(values.Feeble);
attackmessage = weapontype + " | " + weaponrange + weaponuse + skillmass + "<br>";
}
else if(basetype == "Defend"){
activepower = parseInt(values.defPower) + parseInt(values.Endurance) - parseInt(values.Disarm);
activepower = parseInt(values.defPower) + parseInt(values.Endurance) - parseInt(values.Disarm);
}
else if(basetype == "Evade"){
activepower = parseInt(values.evdPower) + parseInt(values.evdPositive) - parseInt(values.evdNegative);
activepower = parseInt(values.evdPower) + parseInt(values.evdPositive) - parseInt(values.evdNegative);
}
/* Distortion modifiers */
@@ -12577,7 +12627,7 @@ getSectionIDs(`repeating_global`, idarray => {
setAttrs({"dummy":" ", "skillSelect":"0", [`${uses}`]:newuses});
});
});
});
});
@@ -12728,6 +12778,10 @@ on('clicked:rollChallenge', (info) => {
}
else if(statn == "Speed"){
setAttrs({"baseSpeed": total });
/* AutoScripts */
resetConditionals();
AutoScriptMain("", "Combat start");
}
finishRoll(
@@ -13057,6 +13111,12 @@ on('clicked:applyDamage', (info) => {
if (newSP > maxSP) { newSP = maxSP }
output["HP"] = newHP; output["StagRes"] = newST; output["SP"] = newSP;
setAttrs(output);
/* AutoScripts */
if (newHP < oldHP || newST < oldST) {
resetConditionals();
AutoScriptMain("", "Damaged");
}
/* console.log("HP base: " + sumBothBefore + ". HP after resistance: " + Math.ceil(Math.min((hpResistance * (sumBothBefore + sumHpBefore)) + hpProtection + damageResistance, 0)))
console.log("ST base: " + sumBothBefore + ". ST after resistance: " + Math.ceil(Math.min((stResistance * (sumBothBefore + sumStBefore)) + stProtection + damageResistance, 0)))
@@ -14548,7 +14608,291 @@ getAttrs(["settingEditMode"], function(values) {
});
/*--- AutoScript functions ---*/
/* AutoScript editor open button */
on("clicked:autoScriptEdit", function(info) {
let newEditorTarget = info.htmlAttributes.id;
getAttrs([`${newEditorTarget}`,"autoScriptEditorTarget", "autoScriptEditorInput"], function(values) {
let oldEditorTarget = values.autoScriptEditorTarget;
let newEditorInput = values[`${newEditorTarget}`];
let oldEditorInput = values.autoScriptEditorInput;
setAttrs({
[oldEditorTarget]: oldEditorInput,
autoScriptEditorInput: newEditorInput,
autoScriptEditorTarget: newEditorTarget,
autoScriptEditor_display: "true"
});
});
});
/* AutoScript editor close button */
on("clicked:closeAutoScriptEdit", function(info) {
getAttrs(["autoScriptEditorTarget", "autoScriptEditorInput"], function(values) {
let editorTarget = values.autoScriptEditorTarget;
let editorInput = values.autoScriptEditorInput;
setAttrs({
[editorTarget]: editorInput,
autoScriptEditor_display: "0"
});
});
});
/* Temp testing button */
on("clicked:autoEffectTest", function() {
/* All buttons except conditional buttons must have resetConditionals */
resetConditionals();
AutoScriptMain(`(Gain 3 Burn) (Gain 2 Fragile Next turn, TestConditional) (Gain 4 Fragile, TestConditional)`, "Combat start")
});
/* Executes a conditional button. Hides the button if at least one check fails */
/* Also hides the button if a Consume check would fail after using the button again */
on("clicked:repeating_conditionalButtons:activate", function(info) {
let buttonid = info.sourceAttribute.split("_")[2];
let buttonAutoScript = "";
let returnValues = {};
getAttrs([`repeating_conditionalButtons_${buttonid}_buttonAutoScript`], function(values) {
buttonAutoScript = values[`repeating_conditionalButtons_${buttonid}_buttonAutoScript`]
AutoScriptMain(buttonAutoScript, "None", function(returnValues) {
if (returnValues.checkResult != "success") {
setAttrs({[`repeating_conditionalButtons_${buttonid}_hideButton`]: "true"})
}
}, "false");
});
});
/* Main function for using AutoScripts. Called by actions through on click events */
/* inputAutoScript: AutoScript provided by the action. Can be an empty string */
/* trigger: "Combat start", "Round start", "Damaged", "Staggered", "Defeated", "Panic",
"Permanent", "Offensive", "Defensive", "Block", "Evade" or "None".
Selects which type of AutoEffects to collect and append to an AutoScript.
Block and Evade also include Defensive */
/* callback: Function to be run on returnValues. Defaults to an empty function */
/* collect: If the function should collect augment/outfit/etc. AutoEffects or not*/
function AutoScriptMain(inputAutoScript, triggerType="None", callback=() => {}, collect="true") {
/* Adds the input AutoScript */
let AutoScript = "";
if (inputAutoScript != "") {
AutoScript = inputAutoScript;
}
/* Appends one or more AutoScripts based on the trigger type */
let autoScriptTypes = [];
if (collect == "true") {
autoScriptTypes.push(triggerType)
if (triggerType != "None") {
if (autoScriptTypes.includes("Block") || autoScriptTypes.includes("Evade")) {
autoScriptTypes.push("Defensive");
}
}
if (!autoScriptTypes.includes("Permanent")) {
autoScriptTypes.push("Permanent")
}
}
getAttrs(["augmentAutoScript", "outfitAutoScript", "egoAutoScript", "distortState", "egoActiveState"], function(values) {
let augmentAutoScript = "";
let outfitAutoScript = "";
let egoAutoScript = "";
let collectedAutoScript = [];
/* Finds all substrings that begin with "[#" and end with "#]" */
augmentAutoScript = values.augmentAutoScript.match(/\[([#][^]+[#])\]/g);
if (augmentAutoScript == null) { augmentAutoScript = ""; }
outfitAutoScript = values.outfitAutoScript.match(/\[([#][^]+[#])\]/g);
if (outfitAutoScript == null) { outfitAutoScript = ""; }
if (values.distortState == "true" || values.egoActiveState == "true") {
egoAutoScript = values.egoAutoScript.match(/\[([#][^]+[#])\]/g);
if (egoAutoScript == null) { egoAutoScript = ""; }
}
let TypedAutoScript = AutoScriptToArray(augmentAutoScript + outfitAutoScript + egoAutoScript, "nested");
TypedAutoScript.forEach((autoScriptType) => {
if (autoScriptTypes.includes(autoScriptType[0])) {
AutoScript += autoScriptType[1];
}
});
/* Convert AutoScript to an array */
AutoScript = AutoScriptToArray(AutoScript);
/* Get relevant attributes */
getAttrs(["settingMuteMessage", "settingWhisperRolls", "settingWhisperTarget", "settingLimbusStyle", "settingHideNextTurn",
"HP", "HP_max", "StagRes", "StagRes_max", "SP", "SP_max",
"StaggerState", "distortState", "egoActiveState", "egoType"], function(values) {
let settingMuteMessage = values.settingMuteMessage;
let settingWhisperRolls = values.settingWhisperRolls;
let settingWhisperTarget = values.settingWhisperTarget;
let settingLimbusStyle = values.settingLimbusStyle;
let settingHideNextTurn = values.settingHideNextTurn;
let HP = values.HP;
let ST = values.StagRes;
let SP = values.SP;
let barList = { HP: parseInt(HP), ST:parseInt(ST), SP:parseInt(SP) };
let HPdamage = values.HP_max - HP;
let STdamage = values.StagRes_max - ST;
let SPdamage = values.SP_max - SP;
let barDamageList = { "-HP": HPdamage, "-ST":STdamage, "-SP":SPdamage }
let StaggerState = values.StaggerState;
let distortState = values.distortState;
let egoActiveState = values.egoActiveState;
let egoType = values.egoType;
let scaling = 1;
let checkResult = "success";
let output = {};
let tempOutput = {};
let returnValues = { checkResult:"success", error:false, };
let conditionalList = {}
let ailmentList = {};
/* Get all ailments */
getAttrs(["burnNextTurnSetting", "bleedNextTurnSetting", "smokeNextTurnSetting", "chargeNextTurnSetting",
"Burn", "Bleed", "Paralysis", "Protection", "StaggerProtection", "Fragile", "Strength", "Feeble", "Endurance", "Disarm", "Haste", "Bind", "Smoke", "Charge", "Fortune",
"BurnNextTurn", "BleedNextTurn", "ParalysisNextTurn", "ProtectionNextTurn", "StaggerProtectionNextTurn", "FragileNextTurn", "StrengthNextTurn", "FeebleNextTurn", "EnduranceNextTurn", "DisarmNextTurn", "HasteNextTurn", "BindNextTurn", "SmokeNextTurn", "ChargeNextTurn", "FortuneNextTurn"], function(values) {
const HasNextTurn = settingHideNextTurn == true ? 'false' : 'true';
let ailmentNames = ["Burn", "Bleed", "Paralysis", "Protection", "StaggerProtection", "Fragile", "Strength", "Feeble", "Endurance", "Disarm", "Haste", "Bind", "Smoke", "Charge", "Fortune"]
ailmentNames.forEach(ailment => {
if (["Burn", "Bleed", "Smoke", "Charge"].includes(ailment)) {
ailmentList[ailment] = [values[ailment.toLowerCase()+"NextTurnSetting"], values[ailment], values[`${ailment}NextTurn`]];
} else {
ailmentList[ailment] = [HasNextTurn, values[ailment], values[`${ailment}NextTurn`]];
}
});
/* Get all custom ailments */
getSectionIDs(`repeating_ailments`, idarray => {
const fieldnames = idarray.reduce((rows,id) =>
[...rows, `repeating_ailments_${id}_ailName`, `repeating_ailments_${id}_ailNextTurn`,
`repeating_ailments_${id}_ailNum`, `repeating_ailments_${id}_ailNumNextTurn`, ], '');
let ailName = "";
let ailHasNextTurn = "";
let ailNum = 0;
let ailNumNextTurn = 0;
getAttrs([...fieldnames], v => {
idarray.forEach(id => {
ailName = v[`repeating_ailments_${id}_ailName`].replace(" ","_");
ailHasNextTurn = v[`repeating_ailments_${id}_ailNextTurn`];
ailNum = v[`repeating_ailments_${id}_ailNum`];
ailNumNextTurn = v[`repeating_ailments_${id}_ailNumNextTurn`]
ailmentList[ailName] = [ailHasNextTurn, ailNum, ailNumNextTurn, id];
});
/* Execute each AutoEffect in the AutoScript */
AutoScript.forEach(AutoEffect => {
if (AutoEffect == undefined) {
return;
}
/* If conditional, add AutoEffect to either a new conditional button or a existing one */
if (AutoEffect.length > 1) {
AutoEffect.slice(1).forEach(conditional => {
if (conditionalList.hasOwnProperty(conditional)) {
conditionalList[conditional] += " (" + AutoEffect[0].toString().replaceAll(","," ") + ")";
} else {
conditionalList[conditional] = "(" + AutoEffect[0].toString().replaceAll(","," ") + ")";
}
});
}
/* If not conditional, process AutoEffect as normal */
else {
/* Checks are always processed. Other AutoEffects are not processed if the last check failed */
switch (AutoEffect[0][0]) {
case "Require": tempOutput = autoEffectRequire(AutoEffect[0], ailmentList, barList, barDamageList); break;
case "Consume": tempOutput = autoEffectConsume(AutoEffect[0], ailmentList, barList); break;
default: tempOutput = {}; break;
}
if (checkResult != "failure") {
switch (AutoEffect[0][0]) {
case "Require": break; /* Already executed above */
case "Consume": break;
case "Gain": tempOutput = autoEffectGainAilment(AutoEffect[0], ailmentList, scaling); break;
default: tempOutput = {error:true}; autoEffectErrorMessage(`${AutoEffect[0]} is not a valid AutoEffect`, AutoEffect); break;
}
}
console.log(tempOutput)
/* Handle errors. Continues executing AutoEffects for the sake of finding additional errors, */
/* but does not apply any changes to attributes */
if (tempOutput.hasOwnProperty("error") || returnValues.error == true) {
returnValues.error == true;
output = {};
return;
}
/* Handle changes to scaling */
if (tempOutput.hasOwnProperty("scaling")) {
scaling = parseInt(tempOutput.scaling);
delete tempOutput.scaling;
}
/* Handle check results from Require and Consume */
/* For the returnValues, the worst result is returned */
if (tempOutput.checkResult != undefined) {
checkResult = tempOutput.checkResult;
if (returnValues.checkResult == "success") {
returnValues.checkResult = tempOutput.checkResult;
}
else if (returnValues.checkResult == "last success" && tempOutput.checkResult == "failure") {
returnValues.checkResult = tempOutput.checkResult;
}
delete tempOutput.checkResult;
}
/* Add attribute changes from AutoEffect to output */
/* The first time a attribute is modified, add its count */
/* For example, if Gain 3 Burn is used and current Burn is 2, output Burn is set to 5 */
/* If Consume 4 Burn is used later, this amount will be removed without adding count */
for (const property in tempOutput) {
if (output.hasOwnProperty(property)) {
output[property] += tempOutput[property];
} else {
output[property] = tempOutput[property] + tempOutput.count;
}
}
}
});
// console.log(output)
setAttrs(output);
/* Create conditional buttons */
for (const [buttonName, buttonAutoScript] of Object.entries(conditionalList)) {
createConditionalButton(buttonName, buttonAutoScript);
}
/* Message handling */
/* Error handling */
if (returnValues.error == true) {
/* Run function that clears all condition buttons */
}
callback(returnValues);
});
});
});
});
});
}
/* Removes all newline and tab characters as well as JavaScript comments from an AutoScript */
function cleanAutoScript(AutoScript) {
let cleanAutoScript = AutoScript.replace(/(\r\n|\n|\r|\t)/gm, "");
@@ -14608,301 +14952,11 @@ function AutoScriptToArray(inputAutoScript, mode="normal") {
/* Return the converted AutoScript */
return AutoScriptArray;
}
/* AutoScript editor */
on("clicked:autoScriptEdit", function(info) {
let newEditorTarget = info.htmlAttributes.id;
getAttrs([`${newEditorTarget}`,"autoScriptEditorTarget", "autoScriptEditorInput"], function(values) {
let oldEditorTarget = values.autoScriptEditorTarget;
let newEditorInput = values[`${newEditorTarget}`];
let oldEditorInput = values.autoScriptEditorInput;
setAttrs({
[oldEditorTarget]: oldEditorInput,
autoScriptEditorInput: newEditorInput,
autoScriptEditorTarget: newEditorTarget,
autoScriptEditor_display: "true"
});
});
});
on("clicked:closeAutoScriptEdit", function(info) {
getAttrs(["autoScriptEditorTarget", "autoScriptEditorInput"], function(values) {
let editorTarget = values.autoScriptEditorTarget;
let editorInput = values.autoScriptEditorInput;
setAttrs({
[editorTarget]: editorInput,
autoScriptEditor_display: "0"
});
});
});
on("clicked:autoEffectTest", function() {
/* All buttons except conditional buttons must have resetConditionals */
resetConditionals();
AutoScriptMain(`(Gain 3 Burn) (Gain 2 Fragile Next turn, TestConditional) (Gain 4 Fragile, TestConditional)`, "Combat start")
});
/* Executes a conditional button. Hides the button if at least one check fails */
/* Also hides the button if a Consume check would fail after using the button again */
on("clicked:repeating_conditionalButtons:activate", function(info) {
let buttonid = info.sourceAttribute.split("_")[2];
let buttonAutoScript = "";
let returnValues = {};
getAttrs([`repeating_conditionalButtons_${buttonid}_buttonAutoScript`], function(values) {
buttonAutoScript = values[`repeating_conditionalButtons_${buttonid}_buttonAutoScript`]
AutoScriptMain(buttonAutoScript, "None", function(returnValues) {
if (returnValues.checkResult != "success") {
setAttrs({[`repeating_conditionalButtons_${buttonid}_hideButton`]: "true"})
}
});
});
});
/* Main function for using AutoScripts. Called by actions through on click events */
/* inputAutoScript: AutoScript provided by the action. Can be an empty string */
/* trigger: "Combat start", "Round start", "Round end", "Damaged", "Staggered", "Defeated", "Panic",
"Permanent", "Offensive", "Defensive", "Block", "Evade" or "None".
Selects which type of AutoEffects to collect and append to an AutoScript.
Block and Evade also include Defensive */
/* callback: Function to be run on returnValues. Defaults to an empty function */
function AutoScriptMain(inputAutoScript, triggerType="None", callback=() => {}) {
/* Adds the input AutoScript */
let AutoScript = "";
if (inputAutoScript != "") {
AutoScript = inputAutoScript;
}
/* Appends one or more AutoScripts based on the trigger type */
let autoScriptTypes = [triggerType];
if (triggerType != "None") {
if (autoScriptTypes.includes("Block") || autoScriptTypes.includes("Evade")) {
autoScriptTypes.push("Defensive");
}
}
if (!autoScriptTypes.includes("Permanent")) {
autoScriptTypes.push("Permanent")
}
console.log(autoScriptTypes)
getAttrs(["augmentAutoScript", "outfitAutoScript", "egoAutoScript", "distortState", "egoActiveState"], function(values) {
let augmentAutoScript = "";
let outfitAutoScript = "";
let egoAutoScript = "";
let collectedAutoScript = [];
/* Finds all substrings that begin with "[#" and end with "#]" */
augmentAutoScript = values.augmentAutoScript.match(/\[([#][^]+[#])\]/g);
if (augmentAutoScript == null) { augmentAutoScript = ""; }
outfitAutoScript = values.outfitAutoScript.match(/\[([#][^]+[#])\]/g);
if (outfitAutoScript == null) { outfitAutoScript = ""; }
if (values.distortState == "true" || values.egoActiveState == "true") {
egoAutoScript = values.egoAutoScript.match(/\[([#][^]+[#])\]/g);
if (egoAutoScript == null) { egoAutoScript = ""; }
}
let TypedAutoScript = AutoScriptToArray(augmentAutoScript + outfitAutoScript + egoAutoScript, "nested");
TypedAutoScript.forEach((autoScriptType) => {
if (autoScriptTypes.includes(autoScriptType[0])) {
AutoScript += autoScriptType[1];
}
});
/* Convert AutoScript to an array */
AutoScript = AutoScriptToArray(AutoScript);
/* Get relevant attributes */
getAttrs(["settingMuteMessage", "settingWhisperRolls", "settingWhisperTarget", "settingLimbusStyle", "settingHideNextTurn",
"HP", "HP_max", "StagRes", "StagRes_max", "SP", "SP_max",
"StaggerState", "distortState", "egoActiveState", "egoType"], function(values) {
let settingMuteMessage = values.settingMuteMessage;
let settingWhisperRolls = values.settingWhisperRolls;
let settingWhisperTarget = values.settingWhisperTarget;
let settingLimbusStyle = values.settingLimbusStyle;
let settingHideNextTurn = values.settingHideNextTurn;
let HP = values.HP;
let ST = values.StagRes;
let SP = values.SP;
let barList = { HP: parseInt(HP), ST:parseInt(ST), SP:parseInt(SP) };
let HPdamage = values.HP_max - HP;
let STdamage = values.StagRes_max - ST;
let SPdamage = values.SP_max - SP;
let barDamageList = { "-HP": HPdamage, "-ST":STdamage, "-SP":SPdamage }
let StaggerState = values.StaggerState;
let distortState = values.distortState;
let egoActiveState = values.egoActiveState;
let egoType = values.egoType;
let scaling = 1;
let checkResult = "success";
let output = {};
let tempOutput = {};
let returnValues = { checkResult:"success", error:false, };
let conditionalList = {}
let ailmentList = {};
/* Get all ailments */
getAttrs(["burnNextTurnSetting", "bleedNextTurnSetting", "smokeNextTurnSetting", "chargeNextTurnSetting",
"Burn", "Bleed", "Paralysis", "Protection", "StaggerProtection", "Fragile", "Strength", "Feeble", "Endurance", "Disarm", "Haste", "Bind", "Smoke", "Charge", "Fortune",
"BurnNextTurn", "BleedNextTurn", "ParalysisNextTurn", "ProtectionNextTurn", "StaggerProtectionNextTurn", "FragileNextTurn", "StrengthNextTurn", "FeebleNextTurn", "EnduranceNextTurn", "DisarmNextTurn", "HasteNextTurn", "BindNextTurn", "SmokeNextTurn", "ChargeNextTurn", "FortuneNextTurn"], function(values) {
const HasNextTurn = settingHideNextTurn == true ? 'false' : 'true';
let ailmentNames = ["Burn", "Bleed", "Paralysis", "Protection", "StaggerProtection", "Fragile", "Strength", "Feeble", "Endurance", "Disarm", "Haste", "Bind", "Smoke", "Charge", "Fortune"]
ailmentNames.forEach(ailment => {
if (["Burn", "Bleed", "Smoke", "Charge"].includes(ailment)) {
ailmentList[ailment] = [values[ailment.toLowerCase()+"NextTurnSetting"], values[ailment], values[`${ailment}NextTurn`]];
} else {
ailmentList[ailment] = [HasNextTurn, values[ailment], values[`${ailment}NextTurn`]];
}
});
/* Get all custom ailments */
getSectionIDs(`repeating_ailments`, idarray => {
const fieldnames = idarray.reduce((rows,id) =>
[...rows, `repeating_ailments_${id}_ailName`, `repeating_ailments_${id}_ailNextTurn`,
`repeating_ailments_${id}_ailNum`, `repeating_ailments_${id}_ailNumNextTurn`, ], '');
let ailName = "";
let ailHasNextTurn = "";
let ailNum = 0;
let ailNumNextTurn = 0;
getAttrs([...fieldnames], v => {
idarray.forEach(id => {
ailName = v[`repeating_ailments_${id}_ailName`].replace(" ","_");
ailHasNextTurn = v[`repeating_ailments_${id}_ailNextTurn`];
ailNum = v[`repeating_ailments_${id}_ailNum`];
ailNumNextTurn = v[`repeating_ailments_${id}_ailNumNextTurn`]
ailmentList[ailName] = [ailHasNextTurn, ailNum, ailNumNextTurn, id];
});
/* Execute each AutoEffect in the AutoScript */
AutoScript.forEach(AutoEffect => {
if (AutoEffect == undefined) {
return;
}
/* If conditional, add AutoEffect to either a new conditional button or a existing one */
if (AutoEffect.length > 1) {
AutoEffect.slice(1).forEach(conditional => {
if (conditionalList.hasOwnProperty(conditional)) {
conditionalList[conditional] += " (" + AutoEffect[0].toString().replaceAll(","," ") + ")";
} else {
conditionalList[conditional] = "(" + AutoEffect[0].toString().replaceAll(","," ") + ")";
}
});
}
/* If not conditional, process AutoEffect as normal */
else {
/* Checks are always processed. Other AutoEffects are not processed if the last check failed */
switch (AutoEffect[0][0]) {
case "Require": tempOutput = autoEffectRequire(AutoEffect[0], ailmentList, barList, barDamageList); break;
case "Consume": tempOutput = autoEffectConsume(AutoEffect[0], ailmentList, barList); break;
default: tempOutput = {}; break;
}
if (checkResult != "failure") {
switch (AutoEffect[0][0]) {
case "Require": break; /* Already executed above */
case "Consume": break;
case "Gain": tempOutput = autoEffectGainAilment(AutoEffect[0], ailmentList, scaling); break;
default: tempOutput = {error:true}; autoEffectErrorMessage(`${AutoEffect[0]} is not a valid AutoEffect`, AutoEffect); break;
}
}
console.log(tempOutput)
/* Handle errors. Continues executing AutoEffects for the sake of finding additional errors, */
/* but does not apply any changes to attributes */
if (tempOutput.hasOwnProperty("error") || returnValues.error == true) {
returnValues.error == true;
output = {};
return;
}
/* Handle changes to scaling */
if (tempOutput.hasOwnProperty("scaling")) {
scaling = parseInt(tempOutput.scaling);
delete tempOutput.scaling;
}
/* Handle check results from Require and Consume */
/* For the returnValues, the worst result is returned */
if (tempOutput.checkResult != undefined) {
checkResult = tempOutput.checkResult;
if (returnValues.checkResult == "success") {
returnValues.checkResult = tempOutput.checkResult;
}
else if (returnValues.checkResult == "last success" && tempOutput.checkResult == "failure") {
returnValues.checkResult = tempOutput.checkResult;
}
delete tempOutput.checkResult;
}
/* Add attribute changes from AutoEffect to output */
/* The first time a attribute is modified, add its count */
/* For example, if Gain 3 Burn is used and current Burn is 2, output Burn is set to 5 */
/* If Consume 4 Burn is used later, this amount will be removed without adding count */
for (const property in tempOutput) {
if (output.hasOwnProperty(property)) {
output[property] += tempOutput[property];
} else {
output[property] = tempOutput[property] + tempOutput.count;
}
}
}
});
// console.log(output)
setAttrs(output);
/* Create conditional buttons */
for (const [buttonName, buttonAutoScript] of Object.entries(conditionalList)) {
createConditionalButton(buttonName, buttonAutoScript);
}
/* Message handling */
/* Error handling */
if (returnValues.error == true) {
/* Run function that clears all condition buttons */
}
callback(returnValues);
});
});
});
});
});
}
/*--- AutoScript functions end ---*/
/*--- AutoEffect functions ---*/
/* Whispers an error message to the user detailing an AutoEffect error */
@@ -14928,7 +14982,6 @@ function resetConditionals() {
});
}
function autoEffectRequire(AutoEffect, ailmentList, barList, barDamageList) {
/* Check format */
if (AutoEffect.length < 3 || AutoEffect.length > 4) { autoEffectErrorMessage(`Expected format: (Require N #Ailment/#Bar/#BarDamage #Scaling(optional))`, AutoEffect); return {error: true}; }
@@ -15063,6 +15116,8 @@ function autoEffectGainAilment(AutoEffect, ailmentList, scaling) {
/*--- AutoEffect functions end ---*/
/*--- Export/Import functions ---*/
let attrkeyCharacter = ["character_nameBase", "instinct", "wisdom", "justice", "charm", "insight", "temperance", "EXP", "character_job", "age", "height", "character_origin", "character_residence", "character_assets", "character_ahn", "character_url", "character_summary", "character_combatnote", "character_history", "character_relations", "character_notes", "character_desc", "character_personality", "character_background"];