-
-
- D+
-
-
+
+
+ D+
+
+
diff --git a/js/sr2ini.js b/js/sr2ini.js
index d0e33e9..84baf6e 100644
--- a/js/sr2ini.js
+++ b/js/sr2ini.js
@@ -2,6 +2,28 @@
* helper functions
*/
+const penalty = [0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4];
+
+const damageMonitorHTML = ['
\n',
+ '\n',
+ ' |  |
\n',
+ '\n',
+ '\n',
+ '| 0 | 0 |
\n',
+ '| L | L |
\n',
+ ' | |
\n',
+ '| M | M |
\n',
+ ' | |
\n',
+ ' | |
\n',
+ '| S | S |
\n',
+ ' | |
\n',
+ ' | |
\n',
+ ' | |
\n',
+ '| D | D |
\n',
+ '\n',
+'
'].join("");
+
+
// roll for initiative with the given reaction and number of ini dice
function rollForInitiative(dice, rea) {
let ini = 0;
@@ -62,6 +84,28 @@ function sortTable() {
}
+// returns a combatant's effective ini value (modified by wound penalties)
+function getEffectiveIni(value, dmgLvl1, dmgLvl2) {
+ let effectiveIni;
+
+ // was function called with 1 argument (tr jQuery object)?
+ if ( arguments.length == 1 && $(value).is("tr.combatantRow") ) {
+ let trueIni = parseInt($(value).attr("data-true-ini"));
+ let dmgStun = parseInt($(value).attr("data-damage-stun")) || 0;
+ let dmgPhysical = parseInt($(value).attr("data-damage-physical")) || 0;
+ effectiveIni = trueIni - penalty[dmgStun] - penalty[dmgPhysical];
+ }
+ // or with 3 arguments (ini and dmg levels)?
+ else if ( arguments.length == 3 ) {
+ effectiveIni = parseInt(value) - penalty[parseInt(dmgLvl1)] - penalty[parseInt(dmgLvl2)];
+ }
+ //
+ else { return NaN; }
+console.log("effectiveIni is ", effectiveIni);
+ return effectiveIni < 0 ? 0 : effectiveIni;
+}
+
+
/*
* Event handler functions
*/
@@ -70,13 +114,14 @@ function sortTable() {
function handleActButtonClick (e) {
// find current table row
let $tr = $(e.target).parents(".combatantRow");
- let ini = $tr.find(".combatantIni").text();
+ let ini = $tr.attr("data-true-ini");
// reduce ini by 10 but not lower than 0
ini = Math.max(parseInt(ini) - 10, 0);
// set new ini value
- $tr.find(".combatantIni").text(ini);
+ $tr.attr("data-true-ini", ini);
+ $tr.find(".combatantIni").text(getEffectiveIni($tr));
// resort table
sortTable();
@@ -103,12 +148,49 @@ function handleAddButtonClick (e) {
$("#combatantModal").modal("show");
}
-
-function handleDamageButtonHover (e) {
-
+// click handler for damage buttons
+function handleDamageButtonClick (e) {
+ let display = $(e.target).parents(".damage-dropdown").find(".damage-monitor").css("display");
+ $(e.target).parents(".damage-dropdown").find(".damage-monitor").css("display", display == "block" ? "none" : "block");
+ return false;
}
+// click handler for damage monitor fields
+function handleDamageMonitorClick (e) {
+ let $td = $(e.target);
+ let $tr = $td.parents("tr.combatantRow");
+ let damageType;
+ let otherDamageLevel
+
+ // calculate new damage level and type
+ let damageLevel = $td.parent().index();
+ if ( $td.hasClass("damage-stun") ) {
+ damageType = "stun";
+ otherDamageLevel = $tr.attr("data-damage-physical") ? parseInt($tr.attr("data-damage-physical")) : 0;
+ } else if ( $td.hasClass("damage-physical") ) {
+ damageType = "physical";
+ otherDamageLevel = $tr.attr("data-damage-stun") ? parseInt($tr.attr("data-damage-stun")) : 0;
+ } else {
+ return false;
+ }
+
+ // add damage level to table row as as data attribute
+ $tr.attr("data-damage-" + damageType, damageLevel);
+
+ // select/unselect damage boxes
+ $td.addClass("selected");
+ $td.parent().nextAll().children("td.damage-" + damageType).removeClass("selected");
+ $td.parent().prevAll().children("td.damage-" + damageType).addClass("selected");
+
+ // recalculate effective ini and resort
+ $tr.find(".combatantIni").text(getEffectiveIni($tr));
+ sortTable();
+
+
+ return false;
+}
+
// click handler for edit buttons
function handleEditButtonClick (e) {
// find current table row
@@ -123,7 +205,8 @@ function handleEditButtonClick (e) {
$("#combatantModalName").val($tr.find(".combatantName").text());
$("#combatantModalDice").val($tr.find(".combatantDice").text());
$("#combatantModalRea").val($tr.find(".combatantRea").text());
- $("#combatantModalIni").val($tr.find(".combatantIni").text());
+ $("#combatantModalIni").val($tr.attr("data-true-ini"));
+ //TODO: show effective ini in modal
// mark which row is being edited
$("#combatantModal").attr("data-row", $(".combatantRow").index($tr));
@@ -223,34 +306,48 @@ function addCombatant (e) {
let ini = $("#combatantModalIni").val().trim();
let dice = $("#combatantModalDice").val().trim();
let rea = $("#combatantModalRea").val().trim();
+ //TODO: retrieve initial damage levels
- // roll for initiative if ini is empty
+ // roll for initiative if necessary
ini = (ini != "") ? ini : rollForInitiative(dice, rea);
+ // TODO: actually calculate effective ini
+ let effectiveIni = getEffectiveIni(ini, 0, 0);
+console.log("effective ini = ", effectiveIni);
+
// construct jQuery object for table row
let $tr = $($.parseHTML( [
- '
\n',
- '| ', name, ' | \n',
- '', ini, ' | \n',
- '', dice, 'D+', rea, ' | \n',
- '\n',
- '\n',
- ' \n',
- ' \n',
- ' \n',
- ' \n',
- ' | \n',
- '
'].join("")
+'
\n', //TODO: add data-damage-* attributes with initial damage levels
+ '| ', name, ' | \n',
+ '', effectiveIni, ' | \n',
+ '', dice, 'D+', rea, ' | \n',
+ '\n',
+ '\n',
+ ' \n',
+ ' \n',
+ ' \n',
+ ' \n',
+ damageMonitorHTML + "\n",
+ ' \n',
+ ' \n',
+ ' | \n',
+'
'].join("")
));
+//TODO: mark initial damage levels with .selected class
+
// add handlers to table row buttons
$tr.find("button.edit-button").on("click", handleEditButtonClick);
$tr.find("button.act-button").on("click", handleActButtonClick);
$tr.find("button.remove-button").on("click", handleRemoveButtonClick);
+ $tr.find("button.damage-button").on("click", handleDamageButtonClick);
- // add handlers to table cells (click to edit)
+ // add handler to table cells (click to edit)
$tr.find(".combatantName, .combatantIni, .combatantDiceAndRea").on("click", handleEditButtonClick);
+ // add handler to damage monitor
+ $tr.find(".damage-stun, .damage-physical").on("click", handleDamageMonitorClick);
+
// add row to table and sort
$("#combatantsTable").append($tr);
sortTable();
@@ -286,7 +383,8 @@ function editCombatant (e) {
$tr.find(".combatantName").text(name);
$tr.find(".combatantDice").text(dice);
$tr.find(".combatantRea").text(rea);
- $tr.find(".combatantIni").text(ini);
+ $tr.attr("data-true-ini", ini);
+ $tr.find(".combatantIni").text(getEffectiveIni($tr));
// sort table
sortTable();
@@ -305,13 +403,14 @@ function newRound() {
// reset ini values
$(".combatantRow").each( function() {
- let $ini = $(this).find(".combatantIni");
- let $dice = $(this).find(".combatantDice");
- if ( $dice.text() == "" ) {
- $ini.text(1);
+ let effectiveIni = $(this).find(".combatantIni").text();
+ let dice = $(this).find(".combatantDice").text();
+ if ( dice == "" ) {
+ $(this).attr("data-true-ini", "1");
} else {
- $ini.text(rollForInitiative($dice.text(), $(this).find(".combatantRea").text()));
+ $(this).attr("data-true-ini", rollForInitiative(dice, $(this).find(".combatantRea").text()));
}
+ $(this).find(".combatantIni").text(getEffectiveIni($(this)));
});
// resort table
@@ -348,12 +447,16 @@ $(document).ready(function(){
// always focus name input field when combatant modal appears
$('#combatantModal').on('shown.bs.modal', function() {
$('#combatantModalName').focus();
- })
-
+ });
// always empty input fields when combatant modal disappears
$("#combatantModal").on('hidden.bs.modal', function (e) {
$("#combatantModal input[id*='combatantModal']").val("");
- })
+ });
+
+ // Hide damage monitors if mouse is clicked outside
+ $("html").on("click", function(e) {
+ $(".damage-monitor:visible").css("display", "none");
+ });
addTestCombatant();