Fixed minor bugs in sortTable() and handleEditButtonClick()

This commit is contained in:
Tobias 2023-04-26 14:39:29 +02:00
parent 04375e7d49
commit 3221947519

View File

@ -15,14 +15,18 @@ if ("serviceWorker" in navigator) {
/*
* import libraries
*/
const bs = require("../../node_modules/bootstrap/js/dist/modal.js");
const $ = require("../../node_modules/jquery/dist/jquery.js");
/*
* constants definitions
*/
const DAMAGE_PENALTY = [0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4];
const DAMAGE_NIVEAU = ["", "L", "M", "S", "D"];
const COMBATANT_TABLE_ROW = [
'<tr class="combatant-row" data-true-ini="" data-augmented-ui="tl-scoop bl-clip-y tr-clip-y br-scoop">\n', //TODO: add data-damage-* attributes with initial damage levels
'<td class="combatant-name" title="Combatant\'s name" data-bs-toggle="modal" data-bs-target="#combatant-modal" data-augmented-ui="tl-scoop bl-clip-y both"></td>\n',
@ -30,7 +34,6 @@ const COMBATANT_TABLE_ROW = [
'<td class="combatant-dice-and-rea" title="Iniative dice and reaction" data-bs-toggle="modal" data-bs-target="#combatant-modal" data-augmented-ui="both"><span class="combatant-dice"></span>D+<span class="combatant-rea"></span></td>\n',
'<td class="combatant-actions" data-augmented-ui="tr-clip-y br-scoop both">\n',
'<button type="button" class="sr2-button act-button" title="Act and reduce ini by 10"><svg class="icon" viewBox="0 0 512 512"><path d="M 0 272 h 96 v 64 h -96 Z" /><path d="M 160 64 h 64 v 384 h -64 v -296 l -64 64 l -40 -40 Z" /><path d="M 352 64 h 96 l 64 64 v 256 l -64 64 h -96 l -64 -64 v -256 l 64 -64 l 32 64 h 32 l 32 32 v 192 l -32 32 h -32 l -32 -32 v -192 l 32 -32" fill-rule="evenodd" /></svg></button>\n',
//<svg><use href="icons.svg#act" /></svg>
'<div class="damage-dropdown">\n',
'<button type="button" class="sr2-button damage-button" title="Take damage"><svg class="icon" viewBox="0 0 512 512"><path d="M 0 288 L 144 224 L 64 32 L 224 128 L 272 0 L 336 144 L 480 96 L 400 224 L 512 304 L 384 352 L 432 512 L 272 416 L 128 512 L 160 352 L 0 288 L 166 267 L 222 290 L 211 346 L 262 312 L 318 346 L 301 290 L 346 273 L 306 245 L 334 200 L 284 217 L 262 166 L 245 211 L 189 178 L 217 245 L 166 267" fill-rule="evenodd" /></svg></button>\n',
'</div>\n',
@ -44,6 +47,7 @@ const COMBATANT_TABLE_ROW = [
'</div>\n',
'</td>\n',
'</tr>'].join("");
const DAMAGE_MONITOR_HTML = [
'<div class="damage-monitor" data-augmented-ui="tl-scoop bl-clip-y tr-clip-y br-scoop both">\n',
'<table>\n',
@ -59,16 +63,21 @@ const DAMAGE_MONITOR_HTML = [
'<tr><td><button type="button" class="damage-stun active" title="K.O." tabindex="-1"><img src="zzz.png" height="16" /></button></td><td><button type="button" class="damage-physical active" title="dead" tabindex="-1" ><img src="cross.png" height="16"/></button></td></tr>\n',
'</table>\n',
'</div>'].join("");
const STUN_BADGE_HTML = '<sup><span class="badge bg-warning position-absolute translate-middle stun-badge" title="Stun damage niveau"></span></sup>';
const PHYSICAL_BADGE_HTML = '<sub><span class="badge bg-danger position-absolute translate-middle physical-badge" title="Physical damage niveau"></span></sub>';
/*
* helper functions
*/
// roll for initiative with the given reaction and number of ini dice
function rollForInitiative(dice, rea) {
let diceRolls = Array.from({ length: parseInt(dice) }, () => Math.ceil(Math.random() * 6));
return diceRolls.reduce((a, b) => a + b, 0) + parseInt(rea);
}
// figure out whose action comes first out of two combatants a and b
function whoGoesFirst(a, b) {
// check for K.O./death
@ -88,7 +97,8 @@ function whoGoesFirst(a, b) {
}
}
}
// returns a combatant's effective ini value (modified by wound penalties)
// compute a combatant's effective ini value (modified by wound penalties)
function getEffectiveIni(tr) {
// return -1 if combatant is K.O. or dead
if ($(tr).hasClass("ko-or-dead")) {
@ -98,6 +108,7 @@ function getEffectiveIni(tr) {
let effectiveIni = parseInt($(tr).attr("data-true-ini")) - DAMAGE_PENALTY[parseInt($(tr).attr("data-damage-stun")) || 0] - DAMAGE_PENALTY[parseInt($(tr).attr("data-damage-physical")) || 0];
return Math.max(effectiveIni, 0);
}
// add test combatant for testing purposes (duh)
function addTestCombatant() {
// Eclipse
@ -108,9 +119,12 @@ function addTestCombatant() {
// $("#combatant-modal-ini").val(12);
setTimeout( () => $("#combatant-modal-add-ok-button").click(), 500);
}
/*
* Event handler functions
*/
// click handler for act buttons; reduces ini by 10
function handleActButtonClick(e) {
// reduce ini by 10 but not lower than 0
@ -120,6 +134,7 @@ function handleActButtonClick(e) {
// resort table
sortTable();
}
// click handler for add buttons
function handleAddButtonClick(e) {
// restyle modal
@ -132,6 +147,7 @@ function handleAddButtonClick(e) {
$("#combatant-modal input[id*='combatant-modal']").off("keydown");
$("#combatant-modal input[id*='combatant-modal']").on("keydown", (e) => { if (e.which == 13 || e.which == 10) { addCombatant(e); } });
}
// click handler for clone buttons -> like handleAddButtonClick but with a pre-filled modal
function handleCloneButtonClick(e) {
// find current table row
@ -153,6 +169,7 @@ function handleCloneButtonClick(e) {
$("#combatant-modal input[id*='combatant-modal']").off("keydown");
$("#combatant-modal input[id*='combatant-modal']").on("keydown", (e) => { if (e.which == 13 || e.which == 10) { addCombatant(e); } });
}
// click handler for damage buttons; basically toggles visibility of table.damage-monitor
function handleDamageButtonClick(e) {
// get visibility status at click time
@ -165,14 +182,15 @@ function handleDamageButtonClick(e) {
}
return false;
}
// click handler for edit buttons
function handleEditButtonClick(e) {
// find current table row
let $tr = $(e.target).parents(".combatant-row");
// restyle modal
$("#combatant-modal .modal-title").text("Edit Combatant");
$("#combatant-modal-add-ok-button, #combatant-modal-add-apply-button").removeClass("seen");
$("#combatant-modal-edit-ok-button").removeClass("d-none");
$("#combatant-modal-add-ok-button, #combatant-modal-add-apply-button").addClass("d-none");
// populate modal with values from row
$("#combatant-modal-name").val($tr.find(".combatant-name").text());
$("#combatant-modal-dice").val($tr.find(".combatant-dice").attr("data-combatant-dice"));
@ -181,11 +199,12 @@ function handleEditButtonClick(e) {
$("#combatant-modal-stun").val($tr.attr("data-damage-stun") || "0");
$("#combatant-modal-physical").val($tr.attr("data-damage-physical") || "0");
// mark which row is being edited
$("#combatant-modal").data("row", $(".combatant-row").index($tr)); // here it's okay to use .data() b/c HTML/CSS does not care about this value
$("#combatant-modal").data("row", $(".combatant-row").index($tr)); // here it's okay to use the jQuery data() function (which is not the same as using a data attribute) b/c this value is used only in this script and not via HTML or CSS
// add handler for enter key
$("#combatant-modal input[id*='combatant-modal']").off("keydown");
$("#combatant-modal input[id*='combatant-modal']").on("keydown", (e) => { if (e.which == 13 || e.which == 10) { editCombatant(e); } });
}
// click handler for the more-actions menus
function handleMoreActionsButtonClick(e) {
// get visibility status at click time
@ -217,9 +236,12 @@ function handleRemoveButtonClick(e) {
// mark which row is being removed
$("#confirm-modal").data("row", $(".combatant-row").index($(e.target).parents(".combatant-row"))); // here it's okay to use .data() b/c HTML/CSS does not care about this value
}
/*
* Main functions
*/
// add new combatant
function addCombatant(e) {
// e.preventDefault();
@ -243,22 +265,21 @@ function addCombatant(e) {
$tr.find(".damage-stun").addClass("active").slice(0, parseInt($tr.attr("data-damage-stun")) || 0).removeClass("active");
$tr.attr("data-damage-physical", $("#combatant-modal-physical").val() || "0");
$tr.find(".damage-physical").addClass("active").slice(0, parseInt($tr.attr("data-damage-physical")) || 0).removeClass("active");
// add click handler to table cells
$tr.find(".combatant-name, .combatant-ini, .combatant-dice-and-rea").on("click", handleEditButtonClick);
// add handlers to action buttons
// add event handlers
$tr.find("button.act-button").on("click", handleActButtonClick);
$tr.find("button.damage-button").on("click", handleDamageButtonClick);
$tr.find("button.actions-button").on("click", handleMoreActionsButtonClick);
$tr.find("button.edit-button").on("click", handleEditButtonClick);
$tr.find("button.edit-button, .combatant-name, .combatant-ini, .combatant-dice-and-rea").on("click", handleEditButtonClick);
$tr.find("button.clone-button").on("click", handleCloneButtonClick);
$tr.find("button.remove-button").on("click", handleRemoveButtonClick);
// add handler to damage monitor
// add event handler to damage monitor
$tr.find(".damage-stun, .damage-physical").on("click", applyDamage);
// add row to table and sort
// append row to table and sort
$(".combatants-table").append($tr);
sortTable();
}
// event handler for when any damage monitor is clicked
// apply damage to combatant
function applyDamage(e) {
let $btn = $(e.target).is("button") ? $(e.target) : $(e.target).parent();
// retrieve new damage level and type from button position and "damage-[type]" class
@ -276,6 +297,7 @@ console.log("damageType is", damageType);
$btn.parent().parent().nextAll().find("button.damage-" + damageType + ":not(.active)").addClass("active");
sortTable();
}
// edit combatant
function editCombatant(e) {
// e.preventDefault();
@ -307,6 +329,7 @@ function editCombatant(e) {
// clean up
$("#combatant-modal").data("row", "");
}
// remove combatant
function removeCombatant(e) {
e.preventDefault();
@ -317,6 +340,7 @@ function removeCombatant(e) {
// clean up
$("#confirm-modal").data("row", "");
}
// start a new combat round
function startNewRound(e) {
e.preventDefault();
@ -335,14 +359,15 @@ function startNewRound(e) {
// resort table
sortTable();
}
// add contextual classes and sort combatants by ini value
// sort combatants by ini value and add contextual classes
function sortTable() {
// do some clean up: remove previous classes from rows, disable act buttons, remove effective ini and damage badges
$(".combatant-row").removeClass("ko-or-dead max-ini zero-ini"); //REGULAR_INI
$(".combatant-row").find(".act-button").prop("disabled", true).attr("aria-disabled", "true");
$(".combatant-ini").empty();
// mark KO or death with class
$(".combatant-row").each( () => {
$(".combatant-row").each(function() {
if (parseInt($(this).attr("data-damage-stun")) == 10 || parseInt($(this).attr("data-damage-physical")) == 10) {
$(this).addClass("ko-or-dead");
}
@ -387,6 +412,7 @@ function sortTable() {
}
return;
}
// validate a combatant row form by checking for all conditions, including regular HTML5 validation
function validateCombatant() {
// get input elements
@ -424,9 +450,12 @@ function validateCombatant() {
// ok then
return true;
}
/*
* Initialize document
*/
$(document).ready(function () {
// add event handlers to navbar buttons
$("#add-combatant-button").on("click", handleAddButtonClick);