From a14f03cce29b408b17c57ccfce5e2a9b96a9774c Mon Sep 17 00:00:00 2001 From: Noel da Costa Date: Mon, 22 Feb 2021 20:00:43 +0000 Subject: [PATCH 1/5] Changed .rst to .md Should look better on the Character Sheet selection page in game. --- GammaWorld3e/{README.rst => README.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename GammaWorld3e/{README.rst => README.md} (100%) diff --git a/GammaWorld3e/README.rst b/GammaWorld3e/README.md similarity index 100% rename from GammaWorld3e/README.rst rename to GammaWorld3e/README.md From 59d25168f2737ed4c810801cb715096895405d83 Mon Sep 17 00:00:00 2001 From: Noel da Costa Date: Mon, 22 Feb 2021 20:05:55 +0000 Subject: [PATCH 2/5] Fixed problems in some roll calculations --- GammaWorld3e/sheet.html | 1067 ++++++++++++++++++++---------------- GammaWorld3e/src/sheet.pug | 161 ++++-- 2 files changed, 720 insertions(+), 508 deletions(-) diff --git a/GammaWorld3e/sheet.html b/GammaWorld3e/sheet.html index cda4d0449c..32bb8ab371 100644 --- a/GammaWorld3e/sheet.html +++ b/GammaWorld3e/sheet.html @@ -37,7 +37,7 @@
- +
@@ -108,6 +108,8 @@ + + @@ -336,26 +338,42 @@
- +
- +
y
-
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
-
- +
- @@ -365,20 +383,18 @@
- +
- + + + + + +
-
- -
-
- -
@@ -391,6 +407,9 @@
+
Show description on roll + +
@@ -400,10 +419,10 @@

Attacks

-
+
-
+
@@ -412,17 +431,17 @@
-
- +
+
-
+
-
- @@ -442,7 +461,7 @@
- +
y @@ -568,14 +587,36 @@
Tech Lvl.
+
Tech Rank
- +
+
Add attack rank to damage + +
Notes
@@ -868,7 +909,7 @@
-
+
- @@ -1061,7 +1102,16 @@
- + +
+
+ y +
+
+
Description
+
+ +
@@ -1078,6 +1128,7 @@
+
@@ -1087,17 +1138,9 @@ y
-
Affects:
-
- -
-
Act Factor:
-
- -
-
Notes
+
Description
- +
@@ -1540,7 +1583,7 @@
- +
@@ -1554,7 +1597,7 @@
- @@ -1610,7 +1653,7 @@
- +
@@ -1619,7 +1662,7 @@
- @@ -1635,10 +1678,11 @@
+
- +
y @@ -1764,14 +1808,35 @@
Tech Lvl.
- +
Tech Rank
- +
+
Add attack rank to damage + +
Notes
@@ -2084,500 +2149,580 @@ })(); - -//------ Functions --------- + //------ Functions --------- -const update_ability = function(name) { - console.log('update_ability: '+name); - let update = {}; - getAttrs([name+'_rolled', name+'_advanced', name+'_tmp'], (v) => { - console.log(v); - update[name] = (parseInt(v[name+'_rolled']) || 0 ) + (parseInt(v[name+'_advanced']) || 0 ) + (parseInt(v[name+'_tmp']) || 0 ); - console.log(update); - setAttrs(update, {silent: false}); - }); +const update_ability = function (name) { + console.log("update_ability: " + name); + let update = {}; + getAttrs([name + "_rolled", name + "_advanced", name + "_tmp"], (v) => { + console.log(v); + update[name] = + (parseInt(v[name + "_rolled"]) || 0) + + (parseInt(v[name + "_advanced"]) || 0) + + (parseInt(v[name + "_tmp"]) || 0); + console.log(update); + setAttrs(update, { silent: false }); + }); }; // @todo: this should probably just pick up equipped shields, rather than having a specific shield setting. -const getShieldCS = function(shield_size, shield_material) { - console.log('getShieldCS'); - console.log(shield_size); - console.log(shield_material); - let CS_physical = 0, CS_energy = 0, CS_mental = 0; - - CS_physical = - parseInt(shield_size) > 2 ? -2 : - parseInt(shield_size) > 1 ? -1 : - 0; - - CS_physical = - parseInt(shield_material) === 1 ? CS_physical : - parseInt(shield_material) === 2 ? CS_physical : - parseInt(shield_material) === 3 ? CS_physical-1 : - parseInt(shield_material) === 4 ? CS_physical-1 : - parseInt(shield_material) === 5 ? CS_physical-2 : - parseInt(shield_material) === 6 ? CS_physical : - CS_physical; - CS_energy = parseInt(shield_material) === 6 ? CS_physical -3 : CS_physical; - return {CS_physical, CS_energy, CS_mental}; +const getShieldCS = function (shield_size, shield_material) { + console.log("getShieldCS"); + console.log(shield_size); + console.log(shield_material); + let CS_physical = 0, + CS_energy = 0, + CS_mental = 0; + + CS_physical = + parseInt(shield_size) > 2 ? -2 : parseInt(shield_size) > 1 ? -1 : 0; + + CS_physical = + parseInt(shield_material) === 1 + ? CS_physical + : parseInt(shield_material) === 2 + ? CS_physical + : parseInt(shield_material) === 3 + ? CS_physical - 1 + : parseInt(shield_material) === 4 + ? CS_physical - 1 + : parseInt(shield_material) === 5 + ? CS_physical - 2 + : parseInt(shield_material) === 6 + ? CS_physical + : CS_physical; + CS_energy = parseInt(shield_material) === 6 ? CS_physical - 3 : CS_physical; + return { CS_physical, CS_energy, CS_mental }; }; -const update_ac = function() { - console.log('update_ac'); - let update = {}; - let dr_total = 0; - let ac_total = 0; - let count = 0; - let enc_attrs = ['shield_CS']; +const update_ac = function () { + console.log("update_ac"); + let update = {}; + let dr_total = 0; + let ac_total = 0; + let count = 0; + let enc_attrs = ["shield_CS"]; + getSectionIDs("repeating_armour", (armourIds) => { + _.each(armourIds, (currentID, i) => { + enc_attrs.push(`repeating_armour_${currentID}_weight`); + enc_attrs.push(`repeating_armour_${currentID}_count`); + enc_attrs.push(`repeating_armour_${currentID}_equipped`); + }); + getAttrs(enc_attrs, (v) => {}); + }); +}; + +const update_enc = function () { + console.log("update_enc"); + let update = {}; + let wtotal = 0; + let DR_physical = 0; + let DR_energy = 0; + let CS = {}; + let RFtotal = 0; + let CS_physical = 0; + let CS_mental = 0; + let CS_energy = 0; + let count = 0; + let PSfactor = 1; + let spdfactor = 1; + let enc_attrs = [ + "DR_physical", + "DR_energy", + "coin_gp", + "coin_nk", + "coin_sp", + "coin_dm", + "PS", + "PS_rolled", + "PS_advanced", + "PS_tmp", + "encumbrance", + "encumbrance_max", + "speed", + "speed_max", + "burden", + "burden_max", + ]; + getSectionIDs("repeating_gear", (gearIds) => { + _.each(gearIds, (currentID, i) => { + enc_attrs.push(`repeating_gear_${currentID}_weight`); + enc_attrs.push(`repeating_gear_${currentID}_count`); + enc_attrs.push(`repeating_gear_${currentID}_equipped`); + }); + getSectionIDs("repeating_armour", (armourIds) => { - _.each(armourIds, (currentID, i) => { - enc_attrs.push(`repeating_armour_${currentID}_weight`); - enc_attrs.push(`repeating_armour_${currentID}_count`); - enc_attrs.push(`repeating_armour_${currentID}_equipped`); - }); - getAttrs(enc_attrs, (v) => { - - }) - }); -}; - -const update_enc = function() { - console.log('update_enc'); - let update = {}; - let wtotal = 0; - let DR_physical = 0; - let DR_energy = 0; - let CS = {}; - let RFtotal = 0; - let CS_physical = 0; - let CS_mental = 0; - let CS_energy = 0; - let count = 0; - let PSfactor = 1; - let spdfactor = 1; - let enc_attrs = ['DR_physical', 'DR_energy', 'coin_gp', 'coin_nk', 'coin_sp', 'coin_dm', 'PS', 'PS_rolled', 'PS_advanced', 'PS_tmp', 'encumbrance', 'encumbrance_max', 'speed', 'speed_max', 'burden', 'burden_max']; - getSectionIDs("repeating_gear", (gearIds) => { - _.each(gearIds, (currentID, i) => { - enc_attrs.push(`repeating_gear_${currentID}_weight`); - enc_attrs.push(`repeating_gear_${currentID}_count`); - enc_attrs.push(`repeating_gear_${currentID}_equipped`); - }); - - getSectionIDs("repeating_armour", (armourIds) => { - _.each(armourIds, (currentID, i) => { - enc_attrs.push(`repeating_armour_${currentID}_weight`); - enc_attrs.push(`repeating_armour_${currentID}_count`); - enc_attrs.push(`repeating_armour_${currentID}_equipped`); - enc_attrs.push(`repeating_armour_${currentID}_powered`); - enc_attrs.push(`repeating_armour_${currentID}_enc_factor`); - enc_attrs.push(`repeating_armour_${currentID}_spd_factor`); - enc_attrs.push(`repeating_armour_${currentID}_PS_factor`); - enc_attrs.push(`repeating_armour_${currentID}_shield_size`); - enc_attrs.push(`repeating_armour_${currentID}_shield_material`); - enc_attrs.push(`repeating_armour_${currentID}_CS_mental`); - enc_attrs.push(`repeating_armour_${currentID}_DR_energy`); - enc_attrs.push(`repeating_armour_${currentID}_DR_physical`); - enc_attrs.push(`repeating_armour_${currentID}_RF_physical`); - }); - getAttrs(enc_attrs, (v) => { - - console.log(v); - if (v["speed_max"] === undefined) { - v["speed_max"] = v['speed']; - update["speed_max"] = v['speed']; - } - ["coin_gp", "coin_sp", "coin_nk", "coin_dm"].forEach((type)=> { - let coinweight = (isNaN(parseInt(v[`${type}`], 10)) === false) ? parseInt(v[`${type}`], 10) : 0; - // use roughly correct weights for different materials as per g/cm3 - if(type === 'coin_gp') { - wtotal += coinweight / 100 - } - if(type === 'coin_sp') { - wtotal += coinweight / 200 - } - if(type === 'coin_nk') { - wtotal += coinweight / 250 - } - if(type === 'coin_dm') { - wtotal += coinweight / 1000 - } - if(type === 'coin_dl') { - wtotal += coinweight / 1000 - } - if(type === 'coin_db') { - wtotal += coinweight / 1000 - } - }); - - _.each(gearIds, (currentID, i) => { - if ( - v[`repeating_gear_${currentID}_weight`] - && v[`repeating_gear_${currentID}_equipped`] === '1' - && isNaN(parseInt(v[`repeating_gear_${currentID}_weight`], 10)) === false) - { - count = v[`repeating_gear_${currentID}_count`] && isNaN(parseFloat(v[`repeating_gear_${currentID}_count`])) === false ? parseFloat(v[`repeating_gear_${currentID}_count`]) : 1; - wtotal = wtotal + (parseFloat(v[`repeating_gear_${currentID}_weight`]) * count); - } - }); - - _.each(armourIds, (currentID, i) => { - if ( - v[`repeating_armour_${currentID}_weight`] - && v[`repeating_armour_${currentID}_equipped`] === '1' - && isNaN(parseInt(v[`repeating_armour_${currentID}_weight`], 10)) === false) - { - count = v[`repeating_armour_${currentID}_count`] && isNaN(parseFloat(v[`repeating_armour_${currentID}_count`])) === false ? parseFloat(v[`repeating_armour_${currentID}_count`]) : 1; - wtotal = wtotal + (parseFloat(v[`repeating_armour_${currentID}_weight`]) * count * (isNaN(parseFloat(v[`repeating_armour_${currentID}_enc_factor`])) === false ? parseFloat(v[`repeating_armour_${currentID}_enc_factor`]) : 0.5)); - PSfactor - = isNaN(parseFloat(v[`repeating_armour_${currentID}_PS_factor`])) === false - ? (v[`repeating_armour_${currentID}_PS_factor`] > PSfactor ? v[`repeating_armour_${currentID}_PS_factor`] : PSfactor) - : PSfactor; - spdfactor - = isNaN(parseFloat(v[`repeating_armour_${currentID}_spd_factor`])) === false - ? (v[`repeating_armour_${currentID}_spd_factor`] > spdfactor ? v[`repeating_armour_${currentID}_spd_factor`] : spdfactor) - : spdfactor; - } - // update DR_physical - if ( - v[`repeating_armour_${currentID}_DR_physical`] - && v[`repeating_armour_${currentID}_equipped`] === '1' - && isNaN(parseInt(v[`repeating_armour_${currentID}_DR_physical`], 10)) === false - ) { - DR_physical += parseInt(v[`repeating_armour_${currentID}_DR_physical`]); - } - // update DR_energy - console.log('DR_energy: ', v[`repeating_armour_${currentID}_DR_energy`]); - if ( - v[`repeating_armour_${currentID}_DR_energy`] !== undefined - && v[`repeating_armour_${currentID}_equipped`] === '1' - && isNaN(parseInt(v[`repeating_armour_${currentID}_DR_energy`], 10)) === false - ) { - DR_energy += parseInt(v[`repeating_armour_${currentID}_DR_energy`]); - } else { - DR_energy += DR_physical; - } - - // update CS - if ( - v[`repeating_armour_${currentID}_shield_size`] - && v[`repeating_armour_${currentID}_shield_material`] - && v[`repeating_armour_${currentID}_equipped`] === '1' - ) { - CS = getShieldCS(v[`repeating_armour_${currentID}_shield_size`], v[`repeating_armour_${currentID}_shield_material`] ); - CS_physical += CS.CS_physical; - CS_mental += CS.CS_mental; - CS_energy += CS.CS_energy; - } - if ( - v[`repeating_armour_${currentID}_CS_mental`] - && v[`repeating_armour_${currentID}_equipped`] === '1' - ) { - console.log('HELMET: '+v[`repeating_armour_${currentID}_CS_mental`] ) - CS_mental += parseInt(v[`repeating_armour_${currentID}_CS_mental`]) ; - } - - // update RF - if ( - v[`repeating_armour_${currentID}_RF_physical`] - && v[`repeating_armour_${currentID}_equipped`] === '1' - && isNaN(parseInt(v[`repeating_armour_${currentID}_RF_physical`], 10)) === false - ) { - RFtotal += parseInt(v[`repeating_armour_${currentID}_RF_physical`]); - console.log(CS_physical); - } - }); - // console.log(CS_physical); - update["RF_physical"] = RFtotal; - update["RF_energy"] = RFtotal; - update["CS_physical"] = CS_physical; - update["CS_energy"] = CS_energy; - update["CS_mental"] = CS_mental; - update["DR_physical"] = DR_physical; - update["DR_energy"] = DR_energy; - update["encumbrance"] = Math.round(wtotal * 10) / 10; - let PS = (parseInt(v["PS_rolled"]) - + parseInt(v["PS_advanced"]) - + parseInt(v["PS_tmp"])) * PSfactor; - update['PS'] = PS; - update["burden"] = - (wtotal > PS*5) ? "Crushing Weight" : - (wtotal > PS*3) ? "Immobile" : - (wtotal > PS*2) ? "Heavily Burdened" : - (wtotal > PS*1) ? "Burdened" : - "Normal"; - update["speed"] = - (wtotal > PS*3) ? 0 : - (wtotal > PS*2) ? Math.floor((parseInt(v["speed_max"]) / 3)) : - (wtotal > PS*1) ? Math.floor((parseInt(v["speed_max"]) /3)*2) : - parseInt(v["speed_max"]) * spdfactor; - console.log(update); - setAttrs(update, {silent: true}); - update_mod('PS'); - }); - }); - }); -}; - -const update_mod = function(ability) { - console.log('update_mod: '+ability); - let update = {}; - let mod = 6; - let total = 0; - let ps_attrs = [ability]; - getAttrs(ps_attrs, (v) => { + _.each(armourIds, (currentID, i) => { + enc_attrs.push(`repeating_armour_${currentID}_weight`); + enc_attrs.push(`repeating_armour_${currentID}_count`); + enc_attrs.push(`repeating_armour_${currentID}_equipped`); + enc_attrs.push(`repeating_armour_${currentID}_powered`); + enc_attrs.push(`repeating_armour_${currentID}_enc_factor`); + enc_attrs.push(`repeating_armour_${currentID}_spd_factor`); + enc_attrs.push(`repeating_armour_${currentID}_PS_factor`); + enc_attrs.push(`repeating_armour_${currentID}_shield_size`); + enc_attrs.push(`repeating_armour_${currentID}_shield_material`); + enc_attrs.push(`repeating_armour_${currentID}_CS_mental`); + enc_attrs.push(`repeating_armour_${currentID}_DR_energy`); + enc_attrs.push(`repeating_armour_${currentID}_DR_physical`); + enc_attrs.push(`repeating_armour_${currentID}_RF_physical`); + }); + getAttrs(enc_attrs, (v) => { console.log(v); - console.log(v[ability]); - total += parseInt(v[ability]); - if(total < 601) { - mod = 5; + if (v["speed_max"] === undefined) { + v["speed_max"] = v["speed"]; + update["speed_max"] = v["speed"]; } - if(total < 121) { - mod = 4; - } - if(total < 22) { - mod = 3; - } - if(total < 19) { - mod = 2; - } - if(total < 16) { - mod = 1; - } - if(total < 12) { - mod = 0; - } - if(total < 10) { - mod = -1; - } - if(total < 7) { - mod = -2; - } - if(total < 4) { - mod = -3; - } - if(total < 0) { - mod = -4; - } - if(total < -6) { - mod = -5; - } - if(total < -26) { - mod = -6; - } - update[ability+'_modifier'] = mod; - setAttrs(update, {silent: true}); + ["coin_gp", "coin_sp", "coin_nk", "coin_dm"].forEach((type) => { + let coinweight = + isNaN(parseInt(v[`${type}`], 10)) === false + ? parseInt(v[`${type}`], 10) + : 0; + // use roughly correct weights for different materials as per g/cm3 + if (type === "coin_gp") { + wtotal += coinweight / 100; + } + if (type === "coin_sp") { + wtotal += coinweight / 200; + } + if (type === "coin_nk") { + wtotal += coinweight / 250; + } + if (type === "coin_dm") { + wtotal += coinweight / 1000; + } + if (type === "coin_dl") { + wtotal += coinweight / 1000; + } + if (type === "coin_db") { + wtotal += coinweight / 1000; + } + }); + + _.each(gearIds, (currentID, i) => { + if ( + v[`repeating_gear_${currentID}_weight`] && + v[`repeating_gear_${currentID}_equipped`] === "1" && + isNaN(parseInt(v[`repeating_gear_${currentID}_weight`], 10)) === + false + ) { + count = + v[`repeating_gear_${currentID}_count`] && + isNaN(parseFloat(v[`repeating_gear_${currentID}_count`])) === + false + ? parseFloat(v[`repeating_gear_${currentID}_count`]) + : 1; + wtotal = + wtotal + + parseFloat(v[`repeating_gear_${currentID}_weight`]) * count; + } + }); + + _.each(armourIds, (currentID, i) => { + if ( + v[`repeating_armour_${currentID}_weight`] && + v[`repeating_armour_${currentID}_equipped`] === "1" && + isNaN(parseInt(v[`repeating_armour_${currentID}_weight`], 10)) === + false + ) { + count = + v[`repeating_armour_${currentID}_count`] && + isNaN(parseFloat(v[`repeating_armour_${currentID}_count`])) === + false + ? parseFloat(v[`repeating_armour_${currentID}_count`]) + : 1; + wtotal = + wtotal + + parseFloat(v[`repeating_armour_${currentID}_weight`]) * + count * + (isNaN( + parseFloat(v[`repeating_armour_${currentID}_enc_factor`]) + ) === false + ? parseFloat(v[`repeating_armour_${currentID}_enc_factor`]) + : 0.5); + PSfactor = + isNaN( + parseFloat(v[`repeating_armour_${currentID}_PS_factor`]) + ) === false + ? v[`repeating_armour_${currentID}_PS_factor`] > PSfactor + ? v[`repeating_armour_${currentID}_PS_factor`] + : PSfactor + : PSfactor; + spdfactor = + isNaN( + parseFloat(v[`repeating_armour_${currentID}_spd_factor`]) + ) === false + ? v[`repeating_armour_${currentID}_spd_factor`] > spdfactor + ? v[`repeating_armour_${currentID}_spd_factor`] + : spdfactor + : spdfactor; + } + // update DR_physical + if ( + v[`repeating_armour_${currentID}_DR_physical`] && + v[`repeating_armour_${currentID}_equipped`] === "1" && + isNaN( + parseInt(v[`repeating_armour_${currentID}_DR_physical`], 10) + ) === false + ) { + DR_physical += parseInt( + v[`repeating_armour_${currentID}_DR_physical`] + ); + } + // update DR_energy + console.log( + "DR_energy: ", + v[`repeating_armour_${currentID}_DR_energy`] + ); + if ( + v[`repeating_armour_${currentID}_DR_energy`] !== undefined && + v[`repeating_armour_${currentID}_equipped`] === "1" && + isNaN( + parseInt(v[`repeating_armour_${currentID}_DR_energy`], 10) + ) === false + ) { + DR_energy += parseInt(v[`repeating_armour_${currentID}_DR_energy`]); + } else { + DR_energy += DR_physical; + } + + // update CS + if ( + v[`repeating_armour_${currentID}_shield_size`] && + v[`repeating_armour_${currentID}_shield_material`] && + v[`repeating_armour_${currentID}_equipped`] === "1" + ) { + CS = getShieldCS( + v[`repeating_armour_${currentID}_shield_size`], + v[`repeating_armour_${currentID}_shield_material`] + ); + CS_physical += CS.CS_physical; + CS_mental += CS.CS_mental; + CS_energy += CS.CS_energy; + } + if ( + v[`repeating_armour_${currentID}_CS_mental`] && + v[`repeating_armour_${currentID}_equipped`] === "1" + ) { + console.log( + "HELMET: " + v[`repeating_armour_${currentID}_CS_mental`] + ); + CS_mental += parseInt(v[`repeating_armour_${currentID}_CS_mental`]); + } + + // update RF + if ( + v[`repeating_armour_${currentID}_RF_physical`] && + v[`repeating_armour_${currentID}_equipped`] === "1" && + isNaN( + parseInt(v[`repeating_armour_${currentID}_RF_physical`], 10) + ) === false + ) { + RFtotal += parseInt(v[`repeating_armour_${currentID}_RF_physical`]); + console.log(CS_physical); + } + }); + // console.log(CS_physical); + update["RF_physical"] = RFtotal; + update["RF_energy"] = RFtotal; + update["CS_physical"] = CS_physical; + update["CS_energy"] = CS_energy; + update["CS_mental"] = CS_mental; + update["DR_physical"] = DR_physical; + update["DR_energy"] = DR_energy; + update["encumbrance"] = Math.round(wtotal * 10) / 10; + let PS = + (parseInt(v["PS_rolled"]) + + parseInt(v["PS_advanced"]) + + parseInt(v["PS_tmp"])) * + PSfactor; + update["PS"] = PS; + update["burden"] = + wtotal > PS * 5 + ? "Crushing Weight" + : wtotal > PS * 3 + ? "Immobile" + : wtotal > PS * 2 + ? "Heavily Burdened" + : wtotal > PS * 1 + ? "Burdened" + : "Normal"; + update["speed"] = + wtotal > PS * 3 + ? 0 + : wtotal > PS * 2 + ? Math.floor(parseInt(v["speed_max"]) / 3) + : wtotal > PS * 1 + ? Math.floor((parseInt(v["speed_max"]) / 3) * 2) + : parseInt(v["speed_max"]) * spdfactor; + console.log(update); + setAttrs(update, { silent: true }); + update_mod("PS"); + }); }); + }); }; - +const update_mod = function (ability) { + console.log("update_mod: " + ability); + let update = {}; + let mod = 6; + let total = 0; + let ps_attrs = [ability]; + getAttrs(ps_attrs, (v) => { + console.log(v); + console.log(v[ability]); + total += parseInt(v[ability]); + if (total < 601) { + mod = 5; + } + if (total < 121) { + mod = 4; + } + if (total < 22) { + mod = 3; + } + if (total < 19) { + mod = 2; + } + if (total < 16) { + mod = 1; + } + if (total < 12) { + mod = 0; + } + if (total < 10) { + mod = -1; + } + if (total < 7) { + mod = -2; + } + if (total < 4) { + mod = -3; + } + if (total < 0) { + mod = -4; + } + if (total < -6) { + mod = -5; + } + if (total < -26) { + mod = -6; + } + update[ability + "_modifier"] = mod; + setAttrs(update, { silent: true }); + }); +}; //------ Events --------- -on("sheet:opened", function(eventinfo) { - console.log('sheet:opened'); +on("sheet:opened", function (eventinfo) { + console.log("sheet:opened"); }); -on("change:import", function(args) { - console.log('sheet:import',args); - +on("change:import", function (args) { + console.log("sheet:import", args); }); -on("change:PS_rolled", function(args) { - console.log('change:PS_rolled') - update_ability('PS'); +on("change:PS_rolled", function (args) { + console.log("change:PS_rolled"); + update_ability("PS"); }); -on("change:PS_advanced", function(args) { - console.log('change:PS_advanced') - update_ability('PS'); +on("change:PS_advanced", function (args) { + console.log("change:PS_advanced"); + update_ability("PS"); }); -on("change:PS_tmp", function(args) { - console.log('change:PS_tmp') - update_ability('PS'); +on("change:PS_tmp", function (args) { + console.log("change:PS_tmp"); + update_ability("PS"); }); -on("change:PS", function(args) { - console.log('PS changed'); - update_mod('PS'); - update_enc(); +on("change:PS", function (args) { + console.log("PS changed"); + update_mod("PS"); + update_enc(); }); -on("change:DX_rolled", function(args) { - console.log('change:DX_rolled') - update_ability('DX'); +on("change:DX_rolled", function (args) { + console.log("change:DX_rolled"); + update_ability("DX"); }); -on("change:DX_advanced", function(args) { - console.log('change:DX_advanced') - update_ability('DX'); +on("change:DX_advanced", function (args) { + console.log("change:DX_advanced"); + update_ability("DX"); }); -on("change:DX_tmp", function(args) { - console.log('change:DX_tmp') - update_ability('DX'); +on("change:DX_tmp", function (args) { + console.log("change:DX_tmp"); + update_ability("DX"); }); -on("change:DX", function(args) { - console.log('DX changed'); - update_mod('DX'); +on("change:DX", function (args) { + console.log("DX changed"); + update_mod("DX"); }); -on("change:CN_rolled", function(args) { - console.log('change:CN_rolled') - update_ability('CN'); +on("change:CN_rolled", function (args) { + console.log("change:CN_rolled"); + update_ability("CN"); }); -on("change:CN_advanced", function(args) { - console.log('change:CN_advanced') - update_ability('CN'); +on("change:CN_advanced", function (args) { + console.log("change:CN_advanced"); + update_ability("CN"); }); -on("change:CN_tmp", function(args) { - console.log('change:CN_tmp') - update_ability('CN'); +on("change:CN_tmp", function (args) { + console.log("change:CN_tmp"); + update_ability("CN"); }); -on("change:CN", function(args) { - console.log('CN changed'); - update_mod('CN'); +on("change:CN", function (args) { + console.log("CN changed"); + update_mod("CN"); }); -on("change:IN_rolled", function(args) { - console.log('change:IN_rolled') - update_ability('IN'); +on("change:IN_rolled", function (args) { + console.log("change:IN_rolled"); + update_ability("IN"); }); -on("change:IN_advanced", function(args) { - console.log('change:IN_advanced') - update_ability('IN'); +on("change:IN_advanced", function (args) { + console.log("change:IN_advanced"); + update_ability("IN"); }); -on("change:IN_tmp", function(args) { - console.log('change:IN_tmp') - update_ability('IN'); +on("change:IN_tmp", function (args) { + console.log("change:IN_tmp"); + update_ability("IN"); }); -on("change:IN", function(args) { - console.log('IN changed'); - update_mod('IN'); +on("change:IN", function (args) { + console.log("IN changed"); + update_mod("IN"); }); -on("change:MS_rolled", function(args) { - console.log('change:MS_rolled') - update_ability('MS'); +on("change:MS_rolled", function (args) { + console.log("change:MS_rolled"); + update_ability("MS"); }); -on("change:MS_advanced", function(args) { - console.log('change:MS_advanced') - update_ability('MS'); +on("change:MS_advanced", function (args) { + console.log("change:MS_advanced"); + update_ability("MS"); }); -on("change:MS_tmp", function(args) { - console.log('change:MS_tmp') - update_ability('MS'); +on("change:MS_tmp", function (args) { + console.log("change:MS_tmp"); + update_ability("MS"); }); -on("change:MS", function(args) { - console.log('MS changed'); - update_mod('MS'); +on("change:MS", function (args) { + console.log("MS changed"); + update_mod("MS"); }); -on("change:CH_rolled", function(args) { - console.log('change:CH_rolled') - update_ability('CH'); +on("change:CH_rolled", function (args) { + console.log("change:CH_rolled"); + update_ability("CH"); }); -on("change:CH_advanced", function(args) { - console.log('change:CH_advanced') - update_ability('CH'); +on("change:CH_advanced", function (args) { + console.log("change:CH_advanced"); + update_ability("CH"); }); -on("change:CH_tmp", function(args) { - console.log('change:CH_tmp') - update_ability('CH'); +on("change:CH_tmp", function (args) { + console.log("change:CH_tmp"); + update_ability("CH"); }); -on("change:CH", function(args) { - console.log('CH changed'); - update_mod('CH'); +on("change:CH", function (args) { + console.log("CH changed"); + update_mod("CH"); }); -on("change:repeating_gear", function(args) { - update_enc(); +on("change:repeating_gear", function (args) { + update_enc(); }); -on("change:repeating_armour", function(args) { - console.log('change:repeating_armour'); - update_enc(); - // update_ac(); +on("change:repeating_armour", function (args) { + console.log("change:repeating_armour"); + update_enc(); + // update_ac(); }); -on("change:coin_gp", function(args) { - update_enc(); +on("change:coin_gp", function (args) { + update_enc(); }); -on("change:coin_nk", function(args) { - update_enc(); +on("change:coin_nk", function (args) { + update_enc(); }); -on("change:coin_dm", function(args) { - update_enc(); +on("change:coin_dm", function (args) { + update_enc(); }); -on("change:coin_sp", function(args) { - update_enc(); +on("change:coin_sp", function (args) { + update_enc(); }); -on("change:rollSwitch", function(args) { - console.log(args); - let update = {}; - if(args.newValue == "0") { - update['PS_rolled'] = 0; - update['IN_rolled'] = 0; - update['CN_rolled'] = 0; - update['IN_rolled'] = 0; - update['MS_rolled'] = 0; - update['CH_rolled'] = 0; - } else { - update['PS_rolled'] = dices.roll('4d6', {dropLowest: 1}).total; - update['DX_rolled'] = dices.roll('4d6', {dropLowest: 1}).total; - update['CN_rolled'] = dices.roll('4d6', {dropLowest: 1}).total; - update['IN_rolled'] = dices.roll('4d6', {dropLowest: 1}).total; - update['MS_rolled'] = dices.roll('4d6', {dropLowest: 1}).total; - update['CH_rolled'] = dices.roll('4d6', {dropLowest: 1}).total; - } - setAttrs(update, {silent: true}); - - update_ability('PS'); - update_ability('DX'); - update_ability('CN'); - update_ability('IN'); - update_ability('MS'); - update_ability('CH'); +on("change:rollSwitch", function (args) { + console.log(args); + let update = {}; + if (args.newValue == "0") { + update["PS_rolled"] = 0; + update["IN_rolled"] = 0; + update["CN_rolled"] = 0; + update["IN_rolled"] = 0; + update["MS_rolled"] = 0; + update["CH_rolled"] = 0; + } else { + update["PS_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total; + update["DX_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total; + update["CN_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total; + update["IN_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total; + update["MS_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total; + update["CH_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total; + } + setAttrs(update, { silent: true }); - update_mod('PS'); - update_mod('DX'); - update_mod('CN'); - update_mod('IN'); - update_mod('MS'); - update_mod('CH'); + update_ability("PS"); + update_ability("DX"); + update_ability("CN"); + update_ability("IN"); + update_ability("MS"); + update_ability("CH"); + update_mod("PS"); + update_mod("DX"); + update_mod("CN"); + update_mod("IN"); + update_mod("MS"); + update_mod("CH"); }); - -on("change:hpRollSwitch", function(args) { - let update = {}; - if(args.newValue == "0") { - update['hp_max'] = 0; - } else { - let rank, CN; - getAttrs(['character_rank', 'CN'], (v) => { - rank = v['character_rank']; - CN = v['CN']; - }); - - update['hp_max'] = dices.roll(`${CN}d6+${CN}`).total; - setAttrs(update, {silent: true}); - } +on("change:hpRollSwitch", function (args) { + console.log("change:hpRollSwitch"); + console.log(args); + let update = {}; + if (args.newValue == "0") { + console.log("set hp_max to zero"); + update["hp_max"] = 0; + setAttrs(update, { silent: true }); + } else { + let rank, CN; + getAttrs(["character_rank", "CN"], (v) => { + console.log("v", v); + rank = v["character_rank"]; + CN = v["CN"]; + update["hp_max"] = dices.roll(`${CN}d6+${CN}`).total; + setAttrs(update, { silent: true }); + }); + } }); + \ No newline at end of file diff --git a/GammaWorld3e/src/sheet.pug b/GammaWorld3e/src/sheet.pug index ccf3e9e237..0983920a92 100644 --- a/GammaWorld3e/src/sheet.pug +++ b/GammaWorld3e/src/sheet.pug @@ -29,7 +29,7 @@ .col-xs-3 label Rank: .col-xs-3 - input(type="number" name="attr_character_rank" value=1) + input(type="number" name="attr_character_rank" title="@{character_rank}" value=1) .col-xs-5 .row.middle-xs .col-xs-2 @@ -77,6 +77,8 @@ option(value=1) I option(value=2) II option(value=3) III + option(value=4) IV + option(value=5) V .row.top-xs .col-xs-8 .row.underline @@ -247,25 +249,37 @@ .col-xs-1 input(type="number" name="attr_rank") .col-xs-1 - input(type="number" name="attr_dmg") + input(type="text" name="attr_dmg") .col-xs-1 input(type="hidden" name="attr_id") input(type="hidden" name="attr_ref") - button(type='roll' name='roll_mutation' value='!gw act @{rank} CS|?{CS|0} id|@{ref} title|ref category|mutations save|@{save} effect|@{effect} effect_crit|@{effect_crit} dmg|@{dmg} mod|@{mod} character|@{character_id} target_id|@{target|target1|token_id} ') + button(type='roll' name='roll_mutation' value='!gw act @{rank} CS|?{CS|0} id|@{ref} title|ref describe|@{describe} category|mutations save|@{save} effect|@{effect} effect_crit|@{effect_crit} dmg|@{dmg} dmg_type|@{dmg_type} mod|@{modifier} character|@{character_id} target_id|@{target|target1|token_id} ') //- button(type='roll' name='roll_mutation2' value='!gw act @{rank} title|@{name} character|@{character_id} target_id|@{target|token_id}') //- button(type='roll' name='roll_mutation4' value='!gw act @{rank} title|@{name} character|@{character_id} target_id|@{target|target1|token_name}') input.short.options-flag(type="checkbox" name="attr_options-flag" class="options-flag" ) span y .options .row.middle-xs - .col-xs-1 + .col-xs-3 + label Effort + .col-xs-3 + select(name="attr_effort") + option(value="passive") Subconscious + option(value="active") Conscious + .col-xs-3 + label Targets + .col-xs-3 + input(type="text" name="attr_number") + + .row.middle-xs + .col-xs-2 label Mod. - .col-xs-1 - input(type="hidden" name="attr_save") + .col-xs-2 + //- input(type="hidden" name="attr_save") input(type="hidden" name="attr_effect") input(type="hidden" name="attr_effect_crit") input(type="hidden" name="attr_dmg_type") - select(name="attr_mod") + select(name="attr_modifier") option(value="PS") PS option(value="DX") DX option(value="CN") CN @@ -273,15 +287,16 @@ option(value="MS") MS option(value="CH") CH .col-xs-2 - label Effort + label Save .col-xs-2 - select(name="attr_effort") - option(value="passive") Subconscious - option(value="active") Conscious - .col-xs-1 - label No. - .col-xs-1 - input(type="text" name="attr_number") + select(name="attr_save") + option(value="PS") PS + option(value="DX") DX + option(value="CN") CN + option(value="IN") IN + option(value="MS") MS + option(value="CH") CH + .col-xs-2 label Duration .col-xs-2 @@ -290,26 +305,28 @@ label Description .col-xs-12 textarea(name="attr_description") + .col-xs-12 Show description on roll + input.short(type="checkbox" name="attr_describe" class="check-flag" ) .row.underline .col-xs-12 h2 Attacks .row.middle-xs - .col-xs-3 + .col-xs-5 label Name - .col-xs-1 + .col-xs-2 label Mod. .col-xs-1 label Range .col-xs-1 label Dmg. - .col-xs-2 - label Rank + .col-xs-1 + label Skill fieldset.repeating_attacks .row - .col-xs-3 + .col-xs-5 input(type="text" name="attr_name") - .col-xs-1 - select(name="attr_mod") + .col-xs-2 + select(name="attr_modifier") option(value="PS") PS option(value="DX") DX option(value="CN") CN @@ -324,8 +341,8 @@ input(type="hidden" name="attr_ref") input(type="text" name="attr_rank") .col-xs-1 - button(type='roll' name='roll_attack' value='!gw act @{rank} CS|?{CS|0} id|@{ref} title|ref category|attacks effect|@{effect} effect_crit|@{effect_crit} dmg|@{dmg} mod|@{mod} skill|@{skill} tech|@{tech} type|@{type} character|@{character_id} target_id|@{target|target1|token_id}') - //- button(type='roll' name='roll_attack' value='!gw act @{rank} CS|?{CS|0} title|@{name} mod|@{mod} tech|@{tech} type|@{type} effect|@{effect} character|@{character_id}') + button(type='roll' name='roll_attack' value='!gw act @{rank} CS|?{CS|0} id|@{ref} title|ref category|attacks effect|@{effect} effect_crit|@{effect_crit} dmg|@{dmg} skilldmg|@{skilldmg} mod|@{modifier} skill|@{skill} tech|@{tech} type|@{type} character|@{character_id} target_id|@{target|target1|token_id}') + //- button(type='roll' name='roll_attack' value='!gw act @{rank} CS|?{CS|0} title|@{name} mod|@{modifier} tech|@{tech} type|@{type} effect|@{effect} character|@{character_id}') input.short.options-flag(type="checkbox" name="attr_options-flag" class="options-flag" ) span y .options @@ -438,10 +455,29 @@ .row.middle-xs .col-xs-2 Tech Lvl. .col-xs-2 + select(name="attr_tech") + option(value=1) I + option(value=2) II + option(value=3) III + option(value=4) IV + option(value=5) V input(type="number" name="attr_tech") .col-xs-2 Tech Rank .col-xs-2 - input(type="text" name="attr_tech_rank") + select(name="attr_tech_rank") + option(value="N") N + option(value="A") A + option(value="B") B + option(value="C") C + option(value="D") D + option(value="E") E + option(value="F") F + option(value="G") G + option(value="H") H + option(value="I") I + option(value="J") J + .col-xs-12 Add attack rank to damage + input.short(type="checkbox" name="attr_skilldmg" class="check-flag" ) .col-xs-12 Notes .col-xs-12 textarea(name="attr_notes") @@ -671,7 +707,7 @@ option(value=5) V .col-xs-1 select(name="attr_tech_rank") - option(value="N") A + option(value="N") N option(value="A") A option(value="B") B option(value="C") C @@ -794,7 +830,7 @@ .row .col-xs-5 label Name - .col-xs-3 + .col-xs-2 label Rank .col-xs-3 label Mod. @@ -802,10 +838,10 @@ .row .col-xs-5 input(type="text" name="attr_name") - .col-xs-3 + .col-xs-2 input(type="number" name="attr_rank") .col-xs-3 - select(name="attr_mod") + select(name="attr_modifier") option(value="PS") PS option(value="DX") DX option(value="CN") CN @@ -813,7 +849,14 @@ option(value="MS") MS option(value="CH") CH .col-xs-1 - button(type='roll' name='roll_skill' value='!gw act @{rank} title|@{name} mod|@{mod} character|@{character_id}') + button(type='roll' name='roll_skill' value='!gw act @{rank} title|@{name} mod|@{modifier} character|@{character_id}') + input.short.options-flag(type="checkbox" name="attr_options-flag" class="options-flag" ) + span y + .options + .row + .col-xs-12 Description + .col-xs-12 + textarea(name="attr_description") .row.underline .col-xs-12 h2 Talents @@ -823,6 +866,7 @@ fieldset.repeating_talents .row .col-xs-8 + input(type="hidden" name="attr_ref") input(type="text" name="attr_name") .col-xs-2 button(type='roll' name='roll_talent' value='!gw act @{character_rank} title|@{name} character|@{character_id}') @@ -830,15 +874,18 @@ span y .options .row - .col-xs-3 Affects: - .col-xs-3 - input(type="text" name="attr_affects") - .col-xs-3 Act Factor: - .col-xs-3 - input(type="text" name="attr_act_factor") - .col-xs-12 Notes + //- .col-xs-3 Affects: + //- .col-xs-3 + //- input(type="text" name="attr_affects") + //- .col-xs-3 Act Factor: + //- .col-xs-3 + //- input(type="text" name="attr_act_factor") + .col-xs-12 Description .col-xs-12 - textarea(name="attr_notes") + textarea(name="attr_description") + //- .col-xs-12 Notes + //- .col-xs-12 + //- textarea(name="attr_notes") .row.underline .col-xs-12 h2 Coins @@ -1160,7 +1207,7 @@ .col-xs-1 input(type="number" name="attr_rank") .col-xs-1 - input(type="number" name="attr_dmg") + input(type="text" name="attr_dmg") .col-xs-1 input(type="hidden" name="attr_id") button(type='roll' name='roll_mutation' value='!gw act @{rank} title|@{name} character|@{character_id}') @@ -1171,7 +1218,7 @@ .col-xs-2 label Mod. .col-xs-2 - select(name="attr_mod") + select(name="attr_modifier") option(value="PS") PS option(value="DX") DX option(value="CN") CN @@ -1208,13 +1255,13 @@ .col-xs-1 label Dmg. .col-xs-2 - label Rank + label Skill fieldset.repeating_attacks .row .col-xs-3 input(type="text" name="attr_name") .col-xs-1 - select(name="attr_mod") + select(name="attr_modifier") option(value="PS") PS option(value="DX") DX option(value="CN") CN @@ -1226,9 +1273,11 @@ .col-xs-1 input(type="text" name="attr_dmg") .col-xs-1 + input(type="hidden" name="attr_ref") input(type="text" name="attr_rank") .col-xs-1 - button(type='roll' name='roll_attack' value='!gw act @{rank} CS|?{CS|0} title|@{name} mod|@{mod} tech| type|@{type} effect|@{effect} character|@{character_id}') + button(type='roll' name='roll_attack' value='!gw act @{rank} CS|?{CS|0} id|@{ref} title|ref category|attacks effect|@{effect} effect_crit|@{effect_crit} dmg|@{dmg} skilldmg|@{skilldmg} mod|@{modifier} skill|@{skill} tech|@{tech} type|@{type} character|@{character_id} target_id|@{target|target1|token_id}') + input.short.options-flag(type="checkbox" name="attr_options-flag" class="options-flag" ) span y .options @@ -1341,10 +1390,28 @@ .row.middle-xs .col-xs-2 Tech Lvl. .col-xs-2 - input(type="number" name="attr_tech") + select(name="attr_tech") + option(value=1) I + option(value=2) II + option(value=3) III + option(value=4) IV + option(value=5) V .col-xs-2 Tech Rank .col-xs-2 - input(type="text" name="attr_tech_rank") + select(name="attr_tech_rank") + option(value="N") N + option(value="A") A + option(value="B") B + option(value="C") C + option(value="D") D + option(value="E") E + option(value="F") F + option(value="G") G + option(value="H") H + option(value="I") I + option(value="J") J + .col-xs-12 Add attack rank to damage + input.short(type="checkbox" name="attr_skilldmg" class="check-flag" ) .col-xs-12 Notes .col-xs-12 textarea(name="attr_notes") @@ -1434,5 +1501,5 @@ input(type="hidden" name="attr_RF_energy" title="@RF_energy" value="0") script(type="text/worker") | | - include dice3.js - include sheetworkers.js \ No newline at end of file + include src/dice3.js + include src/sheetworkers.js \ No newline at end of file From 0ac0ca2b5025472b3415174ccacccbda044b76c2 Mon Sep 17 00:00:00 2001 From: Noel da Costa Date: Mon, 22 Feb 2021 20:25:37 +0000 Subject: [PATCH 3/5] Updated description without formatting for sheet.json manifest Hopefully this will fix the hideous formatting when selecting character sheets in game. --- GammaWorld3e/sheet.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GammaWorld3e/sheet.json b/GammaWorld3e/sheet.json index 04bf56360e..0cbb2b6e9f 100644 --- a/GammaWorld3e/sheet.json +++ b/GammaWorld3e/sheet.json @@ -3,7 +3,7 @@ "css": "styles.css", "authors": "Noel da Costa", "roll20userid": "3920005", - "instructions": "# Instructions/r/r## Using the sheet/r/r### Overview/r/rThis sheet is for use with the GammaWorld 3rd edition rules./r/r### Abilities/r/r3e required that character abilities be rolled randomly. This is currently a requirement on the sheet - you can't edit your attributes directly. To roll your character's abilities, click on the `Roll-up` tab, here you can roll attributes and hitpoints. If you wish to re-roll you need to first click `Reset`./r/r- Adv. - This represents your character's advancement through XP. If you take your ability scores up with XP add the amount in this field./r- Tmp. - Any temporary modifiers to an ability score should be entered in this field/r- Mod. - The ability modifier is calculated automatically/r/r### Combat Stats/r/r#### Defence/r/rNote that this is a slight departure from the original character sheets included with the rules in that it splits defence ratings across `energy`, `physical` and `mental`. These were implied in the rules but not fully represented on the PnP character sheet. These are calculated values based on Gear, Armour and Mutation entries./r/r- _CS_: Column Shift/r- _RF_: Result Factor/r- _DR_: Damage Reduction", + "instructions": "This sheet is for use with the GammaWorld 3rd edition rules. Character abilities must be rolled randomly, this is currently a requirement on the sheet - you cannot edit your attributes directly. To roll your character's abilities, click on the `Roll-up` tab, here you can roll attributes and hitpoints. If you wish to re-roll you need to first click `Reset`. Note that this is a slight departure from the original character sheets included with the rules in that it splits defence ratings across `energy`, `physical` and `mental`. These were implied in the rules but not fully represented on the PnP character sheet. These are calculated values based on Gear, Armour and Mutation entries. CS: Column Shift RF: Result Factor DR: Damage Reduction", "preview": "GW3-sheet.png", "legacy": true } \ No newline at end of file From 8066142f094437974d65f76816ba52b8cbb8896b Mon Sep 17 00:00:00 2001 From: Noel da Costa Date: Tue, 23 Feb 2021 00:54:32 +0000 Subject: [PATCH 4/5] Update companion.js chat styles Cosmetic change only --- GammaWorld3e/src/api-scripts/companion.js | 458 ++++++++++++++++------ 1 file changed, 337 insertions(+), 121 deletions(-) diff --git a/GammaWorld3e/src/api-scripts/companion.js b/GammaWorld3e/src/api-scripts/companion.js index 1574992bdf..396083ca71 100644 --- a/GammaWorld3e/src/api-scripts/companion.js +++ b/GammaWorld3e/src/api-scripts/companion.js @@ -48,8 +48,7 @@ function empty(mixedVar) { return false; } -// @license: GammaWorld compendium not included for licensing reasons, but you can create your own, contact me for advice on how -// import compendium from './compendium' +import compendium from "./compendium"; var GW3Companion = GW3Companion || @@ -63,10 +62,12 @@ var GW3Companion = // Styling for the chat responses. const styles = { reset: "padding: 0; margin: 0;", + menuborder: + "border: 0px solid transparent; border-radius: 4px; padding: 6px; background: red;", menu: - "background-color: #fff; border: 1px dashed #ae2400; padding: 5px 5px 10px 5px; border-radius: 5px;", + "background-color: #f1f1f1; border: 5px solid transparent; padding: 6px 5px 10px 5px; border-radius: 4px;", button: - "background-color: #000; border: 1px solid #292929; border-radius: 3px; padding: 5px; color: #fff; text-align: center;", + "background-color: #000; border: 1px solid #292929; border-radius: 3px; padding: 5px; color: #f1f1f1; text-align: center;", list: "list-style: none;", float: { right: "float: right;", @@ -83,6 +84,10 @@ var GW3Companion = fullWidth: "width: 100%;", underline: "text-decoration: underline;", strikethrough: "text-decoration: strikethrough", + border: + "margin-top: 1rem; border: 1px solid #aaa; padding: 1rem; border-radius: 5px;", + description: + "font-weight: normal; margin-top: 5px; border: 1px solid grey; padding: 1rem; border-radius: 5px; background-color: #aaa; color: white;", effect: "font-weight: bold; margin-top: 5px; border: 1px solid grey; padding: 1rem; border-radius: 5px; background-color: #aaa; color: white;", }, @@ -217,6 +222,7 @@ var GW3Companion = log(msg); log("GM issued " + script_name + " msg: " + msg.content); log("GM issued " + script_name + " command: " + command); + log("state config", state[state_name].config.command); if (command == state[state_name].config.command) { switch (extracommand) { case "reset": @@ -294,10 +300,14 @@ var GW3Companion = case "act": log("ACT roll"); if (args.length > 0) { + log("args obj..."); log(args); // Get main settings let rankSetting = args.shift().split("|"); + log("rankSetting..."); + log(rankSetting); let rank = rankSetting.shift(); + log("rank: ", rank); let roll1 = rankSetting[0]; let roll2 = rankSetting[1]; @@ -306,6 +316,7 @@ var GW3Companion = log("parameters: "); log(parameters); log("act passed rank: " + rank); + log("roll1 & roll2..."); log(roll1); log(roll2); // log(value); @@ -326,14 +337,21 @@ var GW3Companion = break; case "category": log("category"); + log("args length:" + args.length); if (args.length > 0) { let category = args.shift(); + log("category: " + category); let cost = 0; data = getData(); + if (!data) { + return; + } + log("got data"); listItems = []; let items = Object.keys(data[category]); let subcat = {}; let header = ""; + log("got items"); _.each(items, (item) => { // render type headers if (data[category][item].type) { @@ -394,8 +412,18 @@ var GW3Companion = case "compendium": log("compendium"); data = getData(); + if (!data) { + return; + } listItems = []; - let categories = ["armour", "attacks", "gear", "mutations"]; + let categories = [ + "armour", + "attacks", + "gear", + "mutations", + "skills", + "talents", + ]; _.each(categories, (category) => { button = makeButton( ucFirst(category), @@ -484,10 +512,20 @@ var GW3Companion = } return { colour, RF, background }; }, + /** + * @param {object} msg the msg object from chat window + * @param {string} rank the rank column to roll against + * @param {object} parameters the message content parsed as key, value pairs + * @param {Number} roll1 the ability ACT roll (i.e. number from 1 - 100) + * @param {Number} roll2 the save ACT roll (i.e. number from 1 - 100) + */ rollAct = (msg, rank, parameters = {}, roll1, roll2) => { const self = this; log("rollACT: " + rank); const data = getData(); + if (!data) { + return; + } let save, rankHTML = "", effectType = "effect", @@ -497,7 +535,8 @@ var GW3Companion = colorResult = {}, effectName = "", category = parameters["category"], - dmgTotalString = ""; + dmgTotalString = "", + orig_rank = parseInt(rank); rank = parseInt(rank); rankHTML = `${rank}`; sendChat(msg.playerid, "/roll 2d100", function (ops) { @@ -517,9 +556,9 @@ var GW3Companion = log("roll1: " + roll1); log("roll2: " + roll2); if (parameters["mod"]) { - // log('calculating rank based on mod'); + // log('calculating rank based on modifier'); // log(parameters['character']); - // log(`${parameters['mod']}_mod`); + // log(`${parameters['modifier']}_mod`); // log(getAttrByName(parameters['character'], 'PS_modifier')); const mod = parseInt( @@ -532,9 +571,9 @@ var GW3Companion = rank += mod; } if (parameters["character"]) { + character = getObj("character", parameters["character"]); log("character: "); log(character); - character = getObj("character", parameters["character"]); } if (parameters["CS"]) { log("calculating rank based on CS: " + parseInt(parameters["CS"])); @@ -585,18 +624,92 @@ var GW3Companion = // log(attribute); // }); } + // minus target's DX mod for melee attacks - if ( - parameters["category"] === "attacks" && - parameters["type"] === "melee" - ) { - let targetDXmod = getAttrByName( - targetCharacter.id, - "DX_modifier" + if (parameters["category"] === "attacks") { + let character_rank = parseInt( + getAttrByName(character.id, "character_rank") ); - log("targetDXmod: " + targetDXmod); - rankHTML += ` - ${targetDXmod}`; - rank -= parseInt(targetDXmod); + log("character"); + log(character); + log("talents"); + + rank += character_rank; + rankHTML += ` + ${character_rank}`; + if (parameters["type"] === "melee") { + let targetDXmod = getAttrByName( + targetCharacter.id, + "DX_modifier" + ); + log("targetDXmod: " + targetDXmod); + rankHTML += ` - ${targetDXmod}`; + rank -= parseInt(targetDXmod); + } + if (parameters["type"] === "throwing") { + let throwingTalent = filterObjs( + (a) => + a.get("type") === "attribute" && + a.get("characterid") === character.id && + /^repeating_talents_[^_]*_ref$/.test(a.get("name")) && + a.get("current") === "throwing" + ); + if (throwingTalent.length) { + rankHTML += ` + ${character_rank}`; + rank += character_rank; + } + } + if (parameters["type"] === "shooting") { + let shootingTalent = filterObjs( + (a) => + a.get("type") === "attribute" && + a.get("characterid") === character.id && + /^repeating_talents_[^_]*_ref$/.test(a.get("name")) && + a.get("current") === "shooting" + ); + if (shootingTalent.length) { + rankHTML += ` + ${character_rank}`; + rank += character_rank; + } + } + if (parameters["type"] === "grappling") { + let grapplingTalent = filterObjs( + (a) => + a.get("type") === "attribute" && + a.get("characterid") === character.id && + /^repeating_talents_[^_]*_ref$/.test(a.get("name")) && + a.get("current") === "grappling" + ); + if (grapplingTalent.length) { + rankHTML += ` + ${character_rank}`; + rank += character_rank; + } + } + if (parameters["type"] === "martialarts") { + let martialartsTalent = filterObjs( + (a) => + a.get("type") === "attribute" && + a.get("characterid") === character.id && + /^repeating_talents_[^_]*_ref$/.test(a.get("name")) && + a.get("current") === "martialarts" + ); + if (martialartsTalent.length) { + rankHTML += ` + ${character_rank}`; + rank += character_rank; + } + } + if (parameters["type"] === "brawling") { + let brawlingTalent = filterObjs( + (a) => + a.get("type") === "attribute" && + a.get("characterid") === character.id && + /^repeating_talents_[^_]*_ref$/.test(a.get("name")) && + a.get("current") === "brawling" + ); + if (brawlingTalent.length) { + rankHTML += ` + ${character_rank}`; + rank += character_rank; + } + } } } @@ -617,7 +730,7 @@ var GW3Companion = } colorResult = getRollColour(roll1, row); - // log('color: ' + colour); + log("colorResult: " + colorResult); // log('background: ' + background); // log('RC: ' + background); // log('RF: ' + RF); @@ -643,36 +756,53 @@ var GW3Companion = "damage parameter: " + parameters["dmg"] + " - " + - parameters["damage_type"] + parameters["dmg_type"] ); - let baseDmg, + let baseDmg = 0, DR = 0, - soaked; - if (parameters["dmg"] === "mutation") { - baseDmg = parseInt(rank) / 2; + dmgAfterDRsoak = 0; + if (parameters["dmg"] === "mutation" || parameters["dmg"] === "M") { + baseDmg = parseInt(orig_rank) / 2; } else if (parameters["dmg"].includes("/")) { + //- cater for damage ratings for different sizes let dmg = parameters["dmg"].split("/"); log("dmg: "); log(dmg); let size = getAttrByName(targetCharacter.id, "character_size") || 3; log("size: " + size); - baseDmg = parseInt(size) < 4 ? dmg[0] : dmg[1]; + baseDmg = + parseInt(size) < 4 ? parseInt(dmg[0]) : parseInt(dmg[1]); + log("baseDmg after size: " + baseDmg); + if (_.isNaN(baseDmg)) baseDmg = 0; } else { baseDmg = parseInt(parameters["dmg"]); + if (_.isNaN(baseDmg)) baseDmg = 0; } + + if (parameters["category"] === "attacks") { + if (parameters["skilldmg"]) { + log("baseDmg orig_rank: " + orig_rank); + log("baseDmg before skilldmg: " + baseDmg); + baseDmg += parseInt(orig_rank); + log("baseDmg after skilldmg: " + baseDmg); + } + } + log("baseDMG: " + baseDmg); log("RF: " + colorResult.RF); DR = getAttrByName(targetCharacter.id, "DR_physical") || 0; log("DR: " + DR); + log("DR in: " + parseInt(DR)); let dmgTotal = parseInt(colorResult.RF) * parseInt(baseDmg); - if (DR) { - soaked = dmgTotal + parseInt(DR); - } - soaked = soaked < 1 ? 0 : soaked; + if (_.isNaN(dmgTotal)) dmgTotal = 0; + dmgAfterDRsoak = dmgTotal; + dmgAfterDRsoak += parseInt(DR); + dmgAfterDRsoak = dmgAfterDRsoak < 1 ? 0 : dmgAfterDRsoak; log("dmgTotal: " + dmgTotal); - dmgTotalString = `Physical Damage: ${soaked}`; + log("dmgAfterDRsoak: " + dmgAfterDRsoak); + dmgTotalString = `Physical Damage: ${dmgAfterDRsoak}`; } content += makeResult( @@ -698,35 +828,70 @@ var GW3Companion = } }; - // check save from item or from damage type - if (parameters["damage_type"]) { - if (data["damage_types"][parameters["damage_type"]]) { - if (data["damage_types"][parameters["damage_type"]]["save"]) { - save = data["damage_types"][parameters["damage_type"]].save; + // show ability description + if (parameters["describe"] === "on") { + const description = _.defaults( + data[parameters["category"]][parameters["id"]], + { description: false } + ).description; + if (description) { + content += `
${description}
`; + } + } + + if (parameters["save"]) { + save = parameters["save"]; + } + let effectsContent = ""; + // override save type from damage type + if (parameters["dmg_type"]) { + log( + "Damage Type: " + + data["damage_types"][parameters["dmg_type"]].name + ); + if (data["damage_types"][parameters["dmg_type"]]) { + if (data["damage_types"][parameters["dmg_type"]].save) { + save = data["damage_types"][parameters["dmg_type"]].save; + } + if (data["damage_types"][parameters["dmg_type"]].effect_crit) { + parameters["effect_crit"] = + data["damage_types"][parameters["dmg_type"]].effect_crit; + } + if (data["damage_types"][parameters["dmg_type"]].effect) { + parameters["effect"] = + data["damage_types"][parameters["dmg_type"]].effect; + } + if (data["damage_types"][parameters["dmg_type"]].description) { + content += `
Damage Type: ${ + data["damage_types"][parameters["dmg_type"]].name + }

${ + data["damage_types"][parameters["dmg_type"]].description + }

`; } } } if (parameters["effect"]) { effectName = parameters["effect"]; + log("effect name: " + effectName); if ( !empty(data.effects) && !empty(data.effects[parameters["effect"]]) ) { - effectName = data.effects[parameters["effect"]].name; + effectDisplayName = data.effects[parameters["effect"]].name; + log("effect name: " + effectDisplayName); // let result = getEffectResult(parameters['effect'], colorResult.background); - content += `
Effect:
${effectName}
`; + content += `
Effect:
${effectDisplayName}
`; } else if ( !empty(data.damage_types) && data.damage_types[parameters["effect"]] ) { - log( - "damage_type based on effect: " + - parameters["effect"] + - ", " + - data.damage_types[parameters["effect"]] - ); - content += `
Effect: Critical Effect: ${ data.effects[parameters["effect_crit"]].name }
`; - } else if (data.damage_types[parameters["effect_crit"]]) { - log(data.damage_types); - log(parameters["effect_crit"]); - log(data.damage_types[parameters["effect_crit"]]); - content += `
Critical Effect: ${ - data.damage_types[parameters["effect_crit"]].name - }
`; - save = data.damage_types[parameters["effect_crit"]].save; } + // else if (data.damage_types[parameters["effect_crit"]]) { + // log("Crit effect according to Damage Type"); + // log(data.damage_types); + // log(parameters["effect_crit"]); + // log(data.damage_types[parameters["effect_crit"]]); + // content += `
Critical Effect: ${ + // data.damage_types[parameters["effect_crit"]].name + // }
`; + // save = data.damage_types[parameters["effect_crit"]].save; + // content += renderSaveRoll( + // save, + // targetCharacter, + // roll2, + // parameters, + // effectType, + // colorResult, + // effectName + // ); + // } } } - - if (parameters["save"]) { - save = save || parameters["save"]; - let saveScore = getAttrByName(targetCharacter.id, `${save}`); - let effectsActRow = getActRow(saveScore); - let effectsColorResult = getRollColour(roll2, effectsActRow); - let effectsResult = { result: effectsColorResult.background }; - let result = ""; - log("effectType: " + effectType); - log(parameters[effectType]); - if (!empty(data.effects) && data.effects[parameters[effectType]]) { - effectsResult = getEffectResult( - parameters[effectType], - effectsColorResult.background - ); - } - result = effectsResult.result; - let success = - parseInt(effectsColorResult.RF) >= parseInt(colorResult.RF); - let successMessage = success - ? `success` - : `fail`; - content += `
Save (${effectName}): ${result} ${successMessage}
`; + if (!empty(save)) { + content += renderSaveRoll( + save, + targetCharacter, + roll2, + parameters, + effectType, + colorResult, + effectsContent + ); + } else { + log('Will not render Save as the "save" parameter was not set.'); } send(msg, parameters, title, content); }); }, + renderSaveRoll = ( + save, + targetCharacter, + roll2, + parameters, + effectType, + colorResult, + effectsContent + ) => { + const data = getData(); + if (!data) { + return; + } + log("START renderSaveRoll"); + let saveScore = getAttrByName(targetCharacter.id, `${save}`); + log("saveScore: " + saveScore); + let effectsActRow = getActRow(saveScore); + log("effectsActRow"); + log(effectsActRow); + let effectsColorResult = getRollColour(roll2, effectsActRow); + let effectsResult = { result: effectsColorResult.background }; + let result = ""; + if (!empty(data.effects) && data.effects[parameters[effectType]]) { + effectsResult = getEffectResult( + parameters[effectType], + effectsColorResult.background + ); + } + result = effectsResult.result; + let success = + parseInt(effectsColorResult.RF) >= parseInt(colorResult.RF); + let successMessage = success + ? `success` + : `fail`; + + log("END renderSaveRoll"); + let content = `
Save vs. ${save}: ${result} ${successMessage}
`; + if (!success) { + content += effectsContent; + } + return content; + }, getActRow = (rank) => { log("getActRow"); rank = parseInt(rank); @@ -799,27 +1009,27 @@ var GW3Companion = A: [18, 74, 99, null, null, 100], B: [17, 73, 98, 99, null, 100], C: [16, 72, 97, 99, null, 100], - "1": [15, 71, 96, 98, 99, 100], - "2": [14, 69, 94, 97, 99, 100], - "3": [13, 68, 93, 97, 97, 100], - "4": [12, 66, 91, 96, 97, 100], - "5": [11, 62, 87, 93, 97, 99], - "6": [10, 60, 85, 92, 96, 99], - "7": [9, 58, 83, 91, 96, 99], - "8": [8, 56, 80, 89, 95, 99], - "9": [7, 54, 78, 88, 93, 99], - "10": [6, 52, 75, 86, 92, 99], - "11": [5, 49, 71, 83, 91, 98], - "12": [5, 47, 68, 81, 90, 98], - "13": [4, 44, 65, 79, 89, 98], - "14": [4, 42, 62, 77, 88, 98], - "15": [4, 40, 58, 75, 87, 98], - "16": [3, 37, 53, 72, 86, 97], - "17": [3, 35, 49, 70, 85, 97], - "18": [3, 33, 45, 68, 84, 97], - "19": [3, 30, 41, 66, 83, 97], - "20": [2, 26, 36, 63, 82, 96], - "21": [2, 23, 32, 61, 81, 96], + 1: [15, 71, 96, 98, 99, 100], + 2: [14, 69, 94, 97, 99, 100], + 3: [13, 68, 93, 97, 97, 100], + 4: [12, 66, 91, 96, 97, 100], + 5: [11, 62, 87, 93, 97, 99], + 6: [10, 60, 85, 92, 96, 99], + 7: [9, 58, 83, 91, 96, 99], + 8: [8, 56, 80, 89, 95, 99], + 9: [7, 54, 78, 88, 93, 99], + 10: [6, 52, 75, 86, 92, 99], + 11: [5, 49, 71, 83, 91, 98], + 12: [5, 47, 68, 81, 90, 98], + 13: [4, 44, 65, 79, 89, 98], + 14: [4, 42, 62, 77, 88, 98], + 15: [4, 40, 58, 75, 87, 98], + 16: [3, 37, 53, 72, 86, 97], + 17: [3, 35, 49, 70, 85, 97], + 18: [3, 33, 45, 68, 84, 97], + 19: [3, 30, 41, 66, 83, 97], + 20: [2, 26, 36, 63, 82, 96], + 21: [2, 23, 32, 61, 81, 96], X: [2, 20, 27, 59, 80, 96], Y: [2, 17, 22, 56, 78, 95], Z: [2, 13, 16, 51, 76, 94], @@ -973,21 +1183,23 @@ var GW3Companion = } if (category === "attacks" || category === "ammo") { if (category === "attacks") { - let character_rank = parseInt( - getAttrByName(character.id, "character_rank") - ); - log("character rank:" + character_rank); - if (character_rank === NaN) { - log( - "character rank was not found and thus the attack rank could not be accurately determined and will default to 1" - ); - character_rank = 1; - } - let obj = Object.assign(objTemplate, { - name: `repeating_${category}_${rowId}_rank`, - current: character_rank, - }); - createObj("attribute", obj); + //@deprecated: Attack ranks are distinct from Character ranks + // log("import attack"); + // let character_rank = parseInt( + // getAttrByName(character.id, "character_rank") + // ); + // log("character rank:" + character_rank); + // if (_.isNaN(character_rank)) { + // log( + // "character rank was not found and thus the attack rank could not be accurately determined and will default to 1" + // ); + // character_rank = 1; + // } + // let obj = Object.assign(objTemplate, { + // name: `repeating_${category}_${rowId}_rank`, + // current: character_rank, + // }); + // createObj("attribute", obj); } // also add it to gear _.each(itemAttributes, (attributeValue, attributeName) => { @@ -1138,13 +1350,13 @@ var GW3Companion = sendChat( script_name, whisper + - '
' + title + contents + - "
", + "
", null, { noarchive: true, @@ -1160,13 +1372,13 @@ var GW3Companion = sendChat( `${type}|${id}`, whisper + - '
' + title + contents + - "
", + "
", null, { noarchive: true, @@ -1261,6 +1473,10 @@ var GW3Companion = } }, getData = () => { + if (typeof compendium === "undefined") { + log("The compendium is not installed"); + return false; + } return compendium; // return {} }; From c74216572143549b4bac68b3e0ed73bbc882fdaa Mon Sep 17 00:00:00 2001 From: Noel da Costa Date: Tue, 23 Feb 2021 00:55:47 +0000 Subject: [PATCH 5/5] Update sheet.html - exposed extra fields for mutations Effect and Critical effect were not previously available, although existed in the rules. Also re-arranged field layout for weapons. --- GammaWorld3e/sheet.html | 1939 +-------------------------------------- 1 file changed, 2 insertions(+), 1937 deletions(-) diff --git a/GammaWorld3e/sheet.html b/GammaWorld3e/sheet.html index 32bb8ab371..40a6528be9 100644 --- a/GammaWorld3e/sheet.html +++ b/GammaWorld3e/sheet.html @@ -1,1939 +1,5 @@ - -
-

Gamma World 3e

- - - -
- -
-
-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
- -
-
-
-
-
-

Physical Abilities

-
-
-
Cur.
-
Orig.
-
Adv.
-
Tmp.
-
Mod.
-
Roll
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
-
-
-

Mental Abilities

-
-
-
Cur.
-
Orig.
-
Adv.
-
Tmp.
-
Mod.
-
Roll
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
-
-
-
-
-
-
-

Mutations

-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - - -
-
- y -
-
-
- -
-
- -
-
- -
-
- -
-
-
-
- -
-
- - - - -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
Show description on roll - -
-
-
-
-
-
-
-
-

Attacks

-
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
- y -
-
-
-
Type
-
- -
-
Skill
-
- -
-
-
-
-
-
Effect
-
- -
-
Critical
-
- -
-
-
-
-
-
Tech Lvl.
-
- - -
-
Tech Rank
-
- -
-
-
-
Add attack rank to damage - -
-
Notes
-
- -
-
-
-
-
-
-
-

Armour

-
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- y -
-
-
Notes
-
- -
-
Tech Lvl.
-
- -
-
Tech Rank
-
- -
-
-
-
Powered - -
-
- - - - - - - -
-
-
-
-
Air Supply (hrs)
-
- -
-
-
-
-
-
Sensors
-
- -
-
-
-
-
-
-
-
No. Cells
-
- -
-
-
-
-
-
Cells Type
-
- -
-
-
-
-
-
Power Duration (hours)
-
- -
-
-
-
-
-
-
-
Strength x
-
- -
-
-
-
-
-
Speed x
-
- -
-
-
-
-
-
Enc. x
-
- -
-
-
-
-
-
-
Shield - -
-
-
- -
-
- -
-
- -
-
- -
-
-
-
-
Helmet - -
-
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
-
-
-
-
-
-

Gear

-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
-
-
-
-
-

Movement

-
-
-
-
-
-
- -
-
- - -
-
-
-
-
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
kg.
-
-
-
-

Combat Stats

-
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
- -
-
-
-
- -
-
- -
-
- -
-
-
-
-
-
Physical
-
-
-
-
-
-
-
-
-
-
Energy
-
-
-
-
-
-
-
-
-
-
Mental
-
-
-
-
-
-
-
-
-
-
-

Notes

-
-
-
- -
-
- y -
-
-
Description
-
- -
-
-
-
-
-
-
-
-

Skills

-
-
- -
-
- -
-
- -
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- y -
-
-
Description
-
- -
-
-
-
-
-
-
-
-

Talents

-
-
- -
-
-
-
-
- - -
-
- -
-
- y -
-
-
Description
-
- -
-
-
-
-
-
-
-
-

Coins

-
-
- -
-
- -
-
-
-
Nickels
-
- -
-
-
-
Silver Coins
-
- -
-
-
-
Gold Coins
-
- -
-
-
-
Domars
-
- -
-
-
-
Dahlers
-
- -
-
-
-
Daublers
-
- -
-
-
-
-
-
-

Cells

-
-
- -
-
- -
-
-
-
Atomic
-
- -
-
-
-
Chemical
-
- -
-
-
-
Hydrogen
-
- -
-
-
-
Solar
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
- -
-

-
-
-
- -
-
- -
-
- -
-
- -
-
-
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
-

Combat Stats

-
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
- -
-
- -
-
- -
-
-
-
Physical
-
-
-
-
-
-
-
-
Energy
-
-
-
-
-
-
-
-
Mental
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-

Physical Abilities

-
-
-
Cur.
-
Orig.
-
Adv.
-
Tmp.
-
Mod.
-
Roll
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
-
-
-

Mental Abilities

-
-
-
Cur.
-
Orig.
-
Adv.
-
Tmp.
-
Mod.
-
Roll
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
-
-
-
-
-

Mutations

-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- y -
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
-

Attacks

-
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
- -
-
- -
-
- -
-
- -
-
- - -
-
- -
-
- y -
-
-
-
Type
-
- -
-
Skill
-
- -
-
-
-
-
-
Effect
-
- -
-
Critical
-
- -
-
-
-
-
-
Tech Lvl.
-
- -
-
Tech Rank
-
- -
-
-
-
Add attack rank to damage - -
-
Notes
-
- -
-
-
-
-
-
-
-
-
- -
-
- -
-
-
-
-
-
-
-
-

Ability Scores

-
- - - -
-

Hit Points

-
- - - -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file