diff --git a/ProjectMoonTRPG/ProjectMoonTRPG.html b/ProjectMoonTRPG/ProjectMoonTRPG.html index f45dfda779..ecb4889945 100644 --- a/ProjectMoonTRPG/ProjectMoonTRPG.html +++ b/ProjectMoonTRPG/ProjectMoonTRPG.html @@ -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 + "
"; - + activepower = parseInt(values.attPower) + parseInt(values.Strength) - parseInt(values.Feeble); + attackmessage = weapontype + " | " + weaponrange + weaponuse + skillmass + "
"; } 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"];