- Settings
+ Settings
-
- Cost
-
-
-
- Slots
-
-
+
+ Cost
+
+ Cost
+
+
+
+ Slots
+
+
+
+
+ Heat
+
+ Heat produced
+
+
+
+ Heat Spike
+
+
+
@@ -615,13 +653,14 @@ on('clicked:repeating_mechweapons:roll',
// prefix gets an empty string for normal attributes, and repeating_section_ID_ for repeating attributes
var prefix = event.sourceAttribute.split('_').slice(0,3).join('_') + '_'
+ let attrs = await asw.getAttrs([prefix+'heat', prefix+'heatspike']);
+ let overheat = await overheatCheck( attrs[prefix+'heat'], attrs[prefix+'heatspike']);
+
let rollPart = event.htmlAttributes.value.replaceAll('prefix-', `${prefix}`);
- let results = await startRoll(rollPart);
+ let results = await startRoll(rollPart + overheat.queryMod);
- let attrs = await asw.getAttrs(['heat']);
- let resultingHeat = parseInt(attrs.heat) + results.results.weaponheat.result;
asw.setAttrs({
- heat: resultingHeat
+ heat: overheat.resultingHeat
});
finishRoll(
@@ -630,6 +669,50 @@ on('clicked:repeating_mechweapons:roll',
);
});
+on('clicked:repeating_modules:use-module clicked:repeating_systems:use-system', async (event) => {
+
+ // prefix gets an empty string for normal attributes, and repeating_section_ID_ for repeating attributes
+ var trigger = event.triggerName.slice(8); // this always starts with 'clicked:'
+ var prefix = trigger.split('_').slice(0,3).join('_') + '_'
+
+ let attrs = await asw.getAttrs(['character_name', 'energy', 'heat', prefix+'name', prefix+'cost', prefix+'heat', prefix+'heatspike', prefix+'has-uses']);
+ let cost = parseInt(attrs[prefix+'cost']);
+ let heat = parseInt(attrs[prefix+'heat']);
+ let heatspike = attrs[prefix+'heatspike'];
+
+ let overheat = await overheatCheck(heat, heatspike);
+
+ if(overheat.queryMod.includes("{{toMuchHeat=[[1]]}}")) {
+ let rollBase = `/w ${attrs.character_name} &{template:info}{{info= You have to much heat to use ${attrs[prefix+'name']} }}`;
+ let roll = await startRoll(rollBase);
+ finishRoll(roll.rollId, {});
+ return;
+ }
+
+ let toSet = {}
+
+ let rollBase = `/w ${attrs.character_name} &{template:info}{{name=${attrs.character_name}}}{{info= You activated ${attrs[prefix+'name']} for `;
+ if(heat !== 0) {
+ rollBase += `${heat} heat and `
+ toSet.heat = overheat.resultingHeat;
+ }
+ if(attrs[prefix+'has-uses'] !== 'on') {
+ toSet.energy = attrs['energy'] - cost;
+ rollBase += `${cost} EP. ${toSet.energy} Energy remaining}}`
+ }
+ else {
+ toSet[prefix+'cost'] = cost-1;
+ rollBase += `1 use. ${toSet[prefix+'cost']} Uses remaining}}`
+ }
+
+ toSet[prefix+'active'] = 'on';
+
+ asw.setAttrs(toSet);
+
+ let roll = await startRoll(rollBase + overheat.queryMod);
+ finishRoll(roll.rollId, {});
+});
+
on('clicked:reactPush', async (ev) => {
await push(ev, 'roll');
});
@@ -640,15 +723,15 @@ on('clicked:reactPushWeapon', async (ev) => {
const push = async (ev, template) => {
- let attrs = await asw.getAttrs(['character_name', 'heat']);
+ let attrs = await asw.getAttrs(['character_name']);
- let resultingHeat = parseInt(attrs.heat) + 2;
+ let overheat = await overheatCheck(2);
- let rollBase = `&{template:${template}}{{name=${attrs.character_name}}}{{roll=[[1d20]]}}{{mech=1}}{{heatroll=[[1d20]]}}{{heat=[[${resultingHeat}]]}}`;
+ let rollBase = `&{template:${template}}{{name=${attrs.character_name}}}{{roll=[[1d20]]}}{{mech=1}}` + overheat.queryMod ;
let roll = await startRoll(rollBase);
- asw.setAttrs({
- heat: resultingHeat
+ await asw.setAttrs({
+ heat: overheat.resultingHeat
});
finishRoll(roll.rollId, {
@@ -656,15 +739,47 @@ const push = async (ev, template) => {
});
}
+const overheatCheck = async (heatchange, heatspike) => {
+
+ let attrs = await asw.getAttrs(['heat', 'heat_max']);
+ let resultingHeat = parseInt(attrs.heat) + parseInt(heatchange);
+
+ let queryMod = '';
+
+ if(heatspike === 'on') {
+ queryMod = `{{heat=[[${resultingHeat}]]}}{{heatspike=[[1d20]]}}`;
+ }
+
+ if(resultingHeat > parseInt(attrs.heat_max)) {
+ return {
+ resultingHeat: parseInt(attrs.heat),
+ queryMod: queryMod + '{{toMuchHeat=[[1]]}}'
+ }
+ }
+
+ if(resultingHeat === parseInt(attrs.heat_max)) {
+ return {
+ resultingHeat: resultingHeat,
+ queryMod: queryMod + `{{heatroll=[[1d20]]}}{{heat=[[${resultingHeat}]]}}{{toMuchHeat=[[0]]}}`,
+
+ }
+ }
+
+ return {
+ resultingHeat: resultingHeat,
+ queryMod: queryMod +'{{toMuchHeat=[[0]]}}',
+ }
+}
+
on('clicked:reactOverload', async (ev) => {
await reactOverload(ev);
});
const reactOverload = async (ev) => {
- let attrs = await asw.getAttrs(['character_name', 'heat', 'heat_max']);
+ let attrs = await asw.getAttrs(['character_name']);
- let rollBase = `&{template:overload}{{name=${attrs.character_name}}}{{roll=[[1d20]]}}{{heat=${attrs.heat}}}{{maxheat=${attrs.heat_max}}}`;
+ let rollBase = `&{template:overload}{{name=${attrs.character_name}}}{{roll=[[1d20]]}}`;
let roll = await startRoll(rollBase);
finishRoll(roll.rollId, {});
@@ -682,202 +797,252 @@ on('clicked:downtime', async (ev) => {
});
});
-on('clicked:repeating_modules:use-module clicked:repeating_systems:use-system', async (event) => {
-
- // prefix gets an empty string for normal attributes, and repeating_section_ID_ for repeating attributes
- var trigger = event.triggerName.slice(8); // this always starts with 'clicked:'
- var prefix = trigger.split('_').slice(0,3).join('_') + '_'
-
- let attrs = await asw.getAttrs(['character_name', 'energy', prefix+'name', prefix+'cost', prefix+'has-uses']);
- let cost = parseInt(attrs[prefix+'cost']);
-
- let toSet = {}
-
- let rollBase = `/w ${attrs.character_name} &{template:info}{{info= You activated ${attrs[prefix+'name']} for `;
- if(attrs[prefix+'has-uses'] ==! 'on') {
- toSet.energy = attrs['energy'] - cost;
- rollBase += `${cost} EP. ${toSet.energy} Energy remaining}}`
- }
- else {
- toSet[prefix+'cost'] = cost-1;
- rollBase += `1 use. ${toSet[prefix+'cost']} Uses remaining}}`
- }
- toSet[prefix+'active'] = 'on';
-
- asw.setAttrs(toSet);
-
- let roll = await startRoll(rollBase);
- finishRoll(roll.rollId, {});
-});
-
-/////////////////////
-// IMPORTER ////
-/////////////////////
+///////////////////////
+// MECH IMPORTER ////
+///////////////////////
on('clicked:import-mech-stats', async (ev) => {
- let mech = {};
+ let mech = {};
- let toImport = (await asw.getAttrs(['importerText'])).importerText;
- let stats = toImport.replaceAll(/[a-zA-Z]/g, '').replaceAll(/\./g, '').replaceAll(/^\s*[\r\n]/gm, '').trim().split(/\r?\n|\s+/);
+ let toImport = (await asw.getAttrs(['importerText'])).importerText;
+ let stats = toImport.replaceAll(/[a-zA-Z]/g, '').replaceAll(/\./g, '').replaceAll(/^\s*[\r\n]/gm, '').trim().split(/\r?\n|\s+/);
- if(stats.length < 6) {
- asw.setAttrs({
- importerText: 'Could not parse input: Not enough values'
- });
- return;
- }
+ if(stats.length < 6) {
+ asw.setAttrs({
+ importerText: 'Could not parse input: Not enough values'
+ });
+ return;
+ }
- if(!toImport.startsWith(' ') && !/^\d+/g.test(toImport)) {
- let name = toImport.split(/\r?\n/)[0].trim().replace(/(\w)(\w*)/g, (_, firstChar, rest) => firstChar + rest.toLowerCase());
- mech.character_name = name;
- mech.chassis = name;
- }
+ if(!toImport.startsWith(' ') && !/^\d+/g.test(toImport)) {
+ let name = toImport.split(/\r?\n/)[0].trim().replace(/(\w)(\w*)/g, (_, firstChar, rest) => firstChar + rest.toLowerCase());
+ mech.character_name = name;
+ mech.chassis = name;
+ }
- if(/CHASSIS\s*ABILITY/.test(toImport)) {
- mech.chassisDetails = toImport.split(/CHASSIS\s*ABILITY/)[1].replaceAll(/[\r\n]/gm, '').trim();
- }
+ if(/CHASSIS\s*ABILITY/.test(toImport)) {
+ mech.chassisDetails = toImport.split(/CHASSIS\s*ABILITY/)[1].replaceAll(/[\r\n]/gm, '').trim();
+ }
- mech.structure = stats[0];
- mech.structure_max = stats[0];
- mech.energy = stats[1];
- mech.energy_max = stats[1];
- mech.heat_max = stats[2];
- mech.systems_max = stats[3];
- mech.modules_max = stats[4];
- mech.maxcargo = stats[5];
- mech.importerText = "Values imported";
+ mech.structure = stats[0];
+ mech.structure_max = stats[0];
+ mech.energy = stats[1];
+ mech.energy_max = stats[1];
+ mech.heat_max = stats[2];
+ mech.systems_max = stats[3];
+ mech.modules_max = stats[4];
+ mech.maxcargo = stats[5];
+ mech.importerText = "Values imported";
- await asw.setAttrs(mech);
+ await asw.setAttrs(mech);
});
on('clicked:import-mech-weapon', async (ev) => {
- let toImport = removeLineBreakInRules((await asw.getAttrs(['importerText'])).importerText);
+ let toImport = formatImporterText((await asw.getAttrs(['importerText'])).importerText);
- var row = "repeating_mechweapons_" + generateRowID() + "_";
- let weapon = {};
+ var row = "repeating_mechweapons_" + generateRowID() + "_";
+ let weapon = {};
- if(/T\d/.test(toImport)) {
- let tier = toImport.match(/T\d/).pop();
+ toImport = importName(toImport, weapon, row);
+ toImport = importCost(toImport, weapon, row);
- let associatedCost = toImport.split(/T\d/)[1].trim().split(/\r?\n|\s+/)
- weapon[row + "scrap"] = associatedCost[1] + " " + tier;
- weapon[row + "slots"] = parseInt(associatedCost[0]);
+ let rules = toImport.split(/\r?\n/)[0].trim();
+ rules = importRange(rules, weapon, row);
+ rules = importDamage(rules, weapon, row);
- toImport = toImport.split(/T\d/)[0].trim()
- }
+ importHeat(rules, weapon, row);
+ importDetails(rules, toImport, weapon, row);
- toImport = toImport.replaceAll(/[\r\n]/gm, '#').split('#');
+ weapon["importerText"] ='Values imported'
- weapon[row + "weaponname"] = toImport[0];
- weapon[row + "range"] = toImport[1].split('//')[0].replaceAll(/[a-zA-Z]*:/g, '').trim();
- weapon[row + "damage"] = toImport[1].split('//')[1].replaceAll(/[a-zA-Z]*:/g, '').trim();
-
- if(toImport[1].includes("Hot (")) {
- weapon[row + "weaponheat"] = toImport[1].match(/Hot \(\d\)/g).pop().match(/\d+/).pop();
- }
- else {
- weapon[row + "weaponheat"] = 0;
- }
-
- weapon[row + "weapondetails"] = toImport[1].split('//').slice(2).join('//').trim() + "\n" + toImport.slice(2).join(' ').trim();
- weapon["importerText"] ='Values imported'
-
- asw.setAttrs(weapon);
+ asw.setAttrs(weapon);
});
on('clicked:import-mech-system', async (ev) => {
-
- let toImport = removeLineBreakInRules((await asw.getAttrs(['importerText'])).importerText);
-
- var row = "repeating_systems_" + generateRowID() + "_";
- let system = {};
-
- system[row + "name"] = toImport.split(/\r?\n/)[0].trim().replace(/(\w)(\w*)/g, (_, firstChar, rest) => firstChar + rest.toLowerCase());
-
- if(toImport.split(/\r?\n/)[1].includes("EP")) {
- system[row + "cost"] = toImport.split(/\r?\n/)[1].trim();
- toImport = toImport.replaceAll(toImport.split(/\r?\n/)[1], '');
- }
-
- toImport = toImport.replaceAll(/^\s*[\r\n]/gm, '');
-
- let rules = toImport.split(/\r?\n/)[1].trim();
-
- if(rules.includes("Range:")) {
- system[row + "range"] = rules.split('Range:')[1].split('//')[0].replaceAll(/[a-zA-Z]*:/g, '').trim()
- rules = rules.split('//').slice(1).join('//').trim()
- }
-
- if(/T\d/.test(toImport)) {
- let tier = toImport.match(/T\d/).pop();
-
- let associatedCost = toImport.split(/T\d/)[1].trim().split(/\r?\n|\s+/)
- system[row + "scrap"] = associatedCost[1] + " " + tier;
- system[row + "slots"] = associatedCost[0];
-
- toImport = toImport.split(/T\d/)[0].trim()
- }
-
- let longtext = toImport.split('\n').slice(2).join('').trim();
- system[row + "details"] = rules + "\n" + longtext;
-
- system.importerText = 'Values imported'
-
- asw.setAttrs(system);
+ importFromImporter("systems");
});
on('clicked:import-mech-module', async (ev) => {
-
-let toImport = removeLineBreakInRules((await asw.getAttrs(['importerText'])).importerText);
-
- var row = "repeating_modules_" + generateRowID() + "_";
- let module = {};
-
- module[row + "name"] = toImport.split(/\r?\n/)[0].trim().replace(/(\w)(\w*)/g, (_, firstChar, rest) => firstChar + rest.toLowerCase());
-
- if(toImport.split(/\r?\n/)[1].includes("EP")) {
- module[row + "cost"] = toImport.split(/\r?\n/)[1].trim();
- toImport = toImport.replaceAll(toImport.split(/\r?\n/)[1], '');
- }
-
- toImport = toImport.replaceAll(/^\s*[\r\n]/gm, '');
-
- let rules = toImport.split(/\r?\n/)[1].trim();
-
- if(rules.includes("Range:")) {
- module[row + "range"] = rules.split('Range:')[1].split('//')[0].replaceAll(/[a-zA-Z]*:/g, '').trim()
- rules = rules.split('//').slice(1).join('//').trim()
- }
-
- if(/T\d/.test(toImport)) {
- let tier = toImport.match(/T\d/).pop();
-
- let associatedCost = toImport.split(/T\d/)[1].trim().split(/\r?\n|\s+/)
- module[row + "scrap"] = associatedCost[1] + " " + tier;
- module[row + "slots"] = associatedCost[0];
-
- toImport = toImport.split(/T\d/)[0].trim()
- }
-
- let longtext = toImport.split('\n').slice(2).join('').trim();
- module[row + "details"] = rules + "\n" + longtext;
-
- module.importerText = 'Values imported'
-
- asw.setAttrs(module);
+ importFromImporter("modules");
});
+const importFromImporter = async(type) => {
+ let toImport = formatImporterText((await asw.getAttrs(['importerText'])).importerText);
+ await importModuleSystem(type, toImport);
+}
+
+const importModuleSystem = async (type, toImport) => {
+
+ let row = "repeating_" + type + "_" + generateRowID() + "_";
+ let object = {};
+
+ if(checkForMultipleEP(toImport)) {
+ importMultipleEp(type, toImport);
+ }
+
+ toImport = importName(toImport, object, row);
+ toImport = importCost(toImport, object, row);
+
+ toImport = importEp(toImport, object, row);
+ let rules = toImport.split(/\r?\n/)[0].trim();
+
+ rules = importAction(rules, object, row);
+ rules = importRange(rules, object, row);
+
+ if(rules.includes("Passive")) {
+ object[row + "is-passive"] = "on";
+ rules = rules.split('//').slice(1).join('//').trim()
+ }
+
+ importHeat(rules, object, row);
+ importDetails(rules, toImport, object, row);
+
+ object.importerText = 'Values imported'
+
+ asw.setAttrs(object);
+};
+
+const importMultipleEp = async (type, toImport) => {
+ let template = {};
+ let name = importName(toImport, template, '');
+ //remove cost
+ toImport = importCost(toImport, template, '');
+
+ let splitByEp = toImport.split(/(?=^\dEP|XEP)/gm).slice(1);
+
+ for (const ability of splitByEp) {
+ let perLine = ability.split(/\r?\n/g);
+ let firstLine = perLine[0].split(/\s+/g);
+ let importerText = template.name + " "+ firstLine[1] + "\n" + firstLine[0] + "\n" + perLine.slice(1).join("\n");
+ await importModuleSystem(type, importerText);
+ }
+}
+
+const formatImporterText = (toImport) => {
+ let formatted = toImport.replaceAll(/\/\/\s*[\r\n]/gm, '// ').replaceAll(/[\r\n]/gm, '#').replaceAll(/#\/\//g, '//').replaceAll(/#/g, '\n').replaceAll(/^\s*\n/gm,'');
+
+ let multilineName = formatted.split(/\r?\n/);
+ if(multilineName[2].includes("Range") || multilineName[2].includes("Passive") || multilineName[2].includes("EP")) {
+ formatted = multilineName.slice(0,2).join(' ') + "\n" + multilineName.slice(2).join("\n");
+ }
+
+ let multilineRules = formatted.split(/\r?\n/);
+ if(multilineRules[2].includes("//") && !multilineRules[1].includes("EP")) {
+ formatted = multilineRules[0] + "\n" + multilineRules.slice(1,3).join('') + "\n" + multilineRules.slice(3).join("\n");
+ }
+
+ return formatted;
+};
+
+const checkForMultipleEP = (toImport) => {
+ return (toImport.match(/^\dEP|XEP/gm) || []).length > 1;
+}
+
+const importName = (toImport, object, row) => {
+ let textSplits = toImport.split(/\r?\n/);
+ object[row + "name"] = textSplits[0].trim().replace(/(\w)(\w*)/g, (_, firstChar, rest) => firstChar + rest.toLowerCase());
+
+ return textSplits.slice(1).join('\n');
+};
+
+const importCost = (toImport, object, row) => {
+ if(/T\d/.test(toImport)) {
+ let tier = toImport.match(/T\d/).pop();
+
+ let associatedCost = toImport.split(/T\d/)[1].trim().split(/\r?\n|\s+/)
+ object[row + "scrap"] = associatedCost[1] + " " + tier;
+ object[row + "slots"] = parseInt(associatedCost[0]);
+
+ return toImport.split(/T\d/)[0].trim()
+ }
+
+ return toImport;
+}
+
+const importEp = (toImport, object, row) => {
+
+ if(toImport.split(/\r?\n/)[0].includes("EP")) {
+ object[row + "cost"] = toImport.split(/\r?\n/)[0].trim();
+ return toImport.split(/\r?\n/).slice(1).join("\n");
+ }
+ return toImport;
+}
+
+const importRange = (rules, object, row) => {
+ if(rules.includes("Range:")) {
+ object[row + "range"] = rules.split('Range:')[1].split('//')[0].replaceAll(/[a-zA-Z]*:/g, '').trim()
+ let index = rules.split(' // ').indexOf('Range: '+ object[row + "range"]);
+ rules = rules.split(' // ');
+ rules.splice(index, 1);
+ return rules.join(' // ').trim()
+ }
+
+ return rules;
+}
+
+const importDamage = (rules, object, row) => {
+ if(rules.includes("Damage:")) {
+ let damage = rules.split('Damage:')[1].split('//')[0].replaceAll(/[a-zA-Z]*:/g, '').trim();
+ if(damage.match(/\d+[d]\d+/g)) {
+ damage = "[[" + damage + "]]";
+ }
+ object[row + "damage"] = damage;
+ return rules.split('//').slice(1).join('//').trim()
+ }
+
+ return rules;
+}
+
+const importAction = (rules, object, row) => {
+
+ if(rules.includes("Reaction")) {
+ object[row + "action"] = "Reaction";
+ return rules.replaceAll("Reaction //", '').replaceAll("Reaction", '').trim();
+ }
+
+ if(rules.includes("Turn Action")) {
+ object[row + "action"] = "Turn Action";
+ return rules.replaceAll("Turn Action //", '').replaceAll("Turn Action", '').trim();
+ }
+
+ if(rules.includes("Short Action")) {
+ object[row + "action"] = "Short Action";
+ return rules.replaceAll("Short Action //", '').replaceAll("Short Action", '').trim();
+ }
+
+ if(rules.includes("Long Action")) {
+ object[row + "action"] = "Long Action";
+ return rules.replaceAll("Long Action //", '').replaceAll("Long Action", '').trim();
+ }
+
+ return rules;
+}
+
+const importHeat = (rules, object, row) => {
+
+ if(rules.includes("Hot (")) {
+ object[row + "heat"] = rules.match(/Hot \(\d\)/g).pop().match(/\d+/).pop();
+ }
+ else {
+ object[row + "heat"] = 0;
+ }
+
+ if(rules.includes("Heat Spike")) {
+ object[row + "heatspike"] = "on";
+ }
+}
+
+const importDetails = (rules, toImport, object, row) => {
+ let longtext = toImport.split('\n').slice(1).join('').trim();
+ object[row + "details"] = rules + "\n" + longtext;
+}
///////////////////
// HELPER ////
///////////////////
-const removeLineBreakInRules = (toImport) => {
- return toImport.replaceAll(/\/\/\s*[\r\n]/gm, '// ').replaceAll(/[\r\n]/gm, '#').replaceAll(/#\/\//g, '//').replaceAll(/#/g, '\n')
-};
-
async function repeatingSum (destination, fieldsum, ...sections){
// destination = the name of the attribute that stores the total
// fieldsum = the name of the field to be summed
@@ -943,62 +1108,94 @@ const asw = (() => {
{{name}} rolls
+
+ {{#rollTotal() toMuchHeat 1}}
-
+ You cannot make this roll due to heat.
-
-
- {{#rollBetween() roll 20 20}}
- Nailed it ({{roll}})
- You have overcome the odds and managed an outstanding success. You may achieve an additional bonus of your choice to the action. When dealing damage you double it.
- {{/rollBetween() roll 20 20}}
+ {{/rollTotal() toMuchHeat 1}}
- {{#rollBetween() roll 11 19}}
- Success ({{roll}}) - You’ve achieved your goal without any compromises.
- {{/rollBetween() roll 11 19}}
+ {{#rollTotal() toMuchHeat 0}}
+
+
+
+
+
+
+
+ {{#rollWasCrit() roll}}
+ Nailed it ({{roll}})
+ You have overcome the odds and managed an outstanding success. You may achieve an additional bonus of your choice to the action. When dealing damage you double it.
+ {{/rollWasCrit() roll}}
- {{#rollBetween() roll 6 10}}
- Tough Choice ({{roll}}) - You succeed in your action but at a cost. The Mediator will give you a tough choice with some kind of consequence.
- {{/rollBetween() roll 6 10}}
+ {{#^rollWasCrit() roll}}
+ {{#rollBetween() roll 11 19}}
+ Success ({{roll}}) - You’ve achieved your goal without any compromises.
+ {{/rollBetween() roll 11 19}}
- {{#rollBetween() roll 2 5}}
- Failure ({{roll}}) - You’ve failed at what you were attempting, and you’ll face a consequence of The Mediator’s choice.
- {{/rollBetween() roll 2 5}}
+ {{#rollBetween() roll 6 10}}
+ Tough Choice ({{roll}}) - You succeed in your action but at a cost. The Mediator will give you a tough choice with some kind of consequence.
+ {{/rollBetween() roll 6 10}}
- {{#rollBetween() roll 1 1}}
- Cascade Failure ({{roll}}) - You have not only failed, but something has gone terribly wrong. You will suffer a severe consequence of The Mediator’s choice.
- {{/rollBetween() roll 1 1}}
-
-
- {{#heat}}
-
-
-
-
-
-
-
- Heat Check: {{heat}} vs {{heatroll}}
-
-
- {{/heat}}
+ {{#rollBetween() roll 2 5}}
+ Failure ({{roll}}) - You’ve failed at what you were attempting, and you’ll face a consequence of The Mediator’s choice.
+ {{/rollBetween() roll 2 5}}
+
+ {{#rollBetween() roll 1 1}}
+ Cascade Failure ({{roll}}) - You have not only failed, but something has gone terribly wrong. You will suffer a severe consequence of The Mediator’s choice.
+ {{/rollBetween() roll 1 1}}
+ {{/^rollWasCrit() roll}}
+
+
+ {{#heatroll}}
+
+
+
+
+
+
+
+ Heat Check: {{heat}} vs {{heatroll}}
+
+
+ {{/heatroll}}
+ {{#heatspike}}
+
+
+
+
+
+
+
+ Heat Spike: {{heat}} vs {{heatspike}}
+
+
+ {{/heatspike}}
+ {{/rollTotal() toMuchHeat 0}}
{{#mech}}
{{/mech}}
@@ -1007,7 +1204,7 @@ const asw = (() => {
- {{callsign}} rolls an attack on range {{range}} with {{weapon_name}}
+ {{name}} rolls an attack on range {{range}} with {{weapon_name}}
@@ -1015,76 +1212,107 @@ const asw = (() => {
+ {{#rollTotal() toMuchHeat 1}}
- {{#rollBetween() roll 20 20}}
- Nailed it ({{roll}})
- You have overcome the odds and managed an outstanding success. You may achieve an additional bonus of your choice to the action e.g. double the damage.
- {{/rollBetween() roll 20 20}}
+ You cannot make this roll due to heat.
+
+
+ {{/rollTotal() toMuchHeat 1}}
+ {{#rollTotal() toMuchHeat 0}}
+
+
+ {{#rollWasCrit() roll}}
+ Nailed it ({{roll}})
+ You have overcome the odds and managed an outstanding success. You may achieve an additional bonus of your choice to the action e.g. double the damage.
+ {{/rollWasCrit() roll}}
- {{#rollBetween() roll 11 19}}
- Success ({{roll}}) - You hit the target and deal standard damage
- {{/rollBetween() roll 11 19}}
+ {{#^rollWasCrit() roll}}
+ {{#rollBetween() roll 11 19}}
+ Success ({{roll}}) - You hit the target and deal standard damage
+ {{/rollBetween() roll 11 19}}
- {{#rollBetween() roll 6 10}}
- Tough Choice ({{roll}}) - You succeed in your action but at a cost. The Mediator will give you a tough choice with some kind of consequence. You hit but something has
- gone wrong.
- {{/rollBetween() roll 6 10}}
+ {{#rollBetween() roll 6 10}}
+ Tough Choice ({{roll}}) - You succeed in your action but at a cost. The Mediator will give you a tough choice with some kind of consequence. You hit but something has
+ gone wrong.
+ {{/rollBetween() roll 6 10}}
- {{#rollBetween() roll 2 5}}
- Failure ({{roll}}) - You miss the target.
- {{/rollBetween() roll 2 5}}
+ {{#rollBetween() roll 2 5}}
+ Failure ({{roll}}) - You miss the target.
+ {{/rollBetween() roll 2 5}}
- {{#rollBetween() roll 1 1}}
- Cascade Failure ({{roll}}) - You miss the target and something has gone wrong.
- {{/rollBetween() roll 1 1}}
-
-
- {{#damage}}
-
-
-
-
-
-
-
- Weapondamage: {{damage}}
-
-
- {{/damage}}
- {{#^rollTotal() weaponheat 0}}
-
-
- Weaponheat: {{weaponheat}}
-
-
- {{/^rollTotal() weaponheat 0}}
- {{#heat}}
-
-
-
-
-
-
-
- Heat Check: {{heat}} vs {{heatroll}}
-
-
- {{/heat}}
+ {{#rollBetween() roll 1 1}}
+ Cascade Failure ({{roll}}) - You miss the target and something has gone wrong.
+ {{/rollBetween() roll 1 1}}
+ {{/^rollWasCrit() roll}}
+
+
+ {{#damage}}
+
+
+
+
+
+
+
+ Weapondamage: {{damage}}
+
+
+ {{/damage}}
+ {{#^rollTotal() weaponheat 0}}
+
+
+ Weaponheat: {{weaponheat}}
+
+
+ {{/^rollTotal() weaponheat 0}}
+ {{#heatroll}}
+
+
+
+
+
+
+
+ Heat Check: {{heat}} vs {{heatroll}}
+
+
+ {{/heatroll}}
+ {{#heatspike}}
+
+
+
+
+
+
+
+ Heat Spike: {{heat}} vs {{heatspike}}
+
+
+ {{/heatspike}}
+ {{/rollTotal() toMuchHeat 0}}
{{#mech}}
{{/mech}}
@@ -1209,5 +1437,30 @@ const asw = (() => {
{{info}}
+
+ {{#heatroll}}
+
+ Heat Check: {{heat}} vs {{heatroll}}
+ {{/heatroll}}
+ {{#heatspike}}
+
+ Heat Spike: {{heat}} vs {{heatspike}}
+ {{/heatspike}}
+
+
\ No newline at end of file