Files
thetempusproject/app/plugins/initiativetracker/js/initiative.js
2024-08-04 21:15:59 -04:00

415 lines
13 KiB
JavaScript

$(document).ready(function() {
// Top Checkbox Controls
$('input[type="checkbox"]').change(function() {
var name = $(this).attr('name');
if ( 'trackAC' == name ) {
var eles = document.getElementsByClassName('ac-tracker');
}
if ( 'trackHP' == name ) {
var eles = document.getElementsByClassName('hp-tracker');
}
if ( 'trackRounds' == name ) {
var eles = document.getElementsByClassName('rounds-tracker');
}
if ($(this).is(':checked')) {
Array.prototype.forEach.call(eles, function(ele) {
ele.style.display = '';
});
} else {
Array.prototype.forEach.call(eles, function(ele) {
ele.style.display = 'none';
});
}
});
$(document).on('click', '.character-remove', function() {
var characterId = $(this).closest('tr').data('character-id');
var allTrsWithCharacterId = document.querySelectorAll(`tr[data-round-character-id="${characterId}"]`);
allTrsWithCharacterId.forEach(function(tr) {
tr.remove();
});
var allTrsWithCharacterId = document.querySelectorAll(`tr[data-character-id="${characterId}"]`);
allTrsWithCharacterId.forEach(function(tr) {
tr.remove();
});
findByIdAndRemove( characterId, characterInitiativeList );
});
$(document).on('click', '.hp-minus', function() {
var characterId = $(this).closest('tr').data('character-id');
var dataValue = parseInt($(this).data('value'), 10);
var allTrsWithCharacterId = document.querySelectorAll(`tr[data-character-id="${characterId}"]`);
allTrsWithCharacterId.forEach(function(tr) {
var $input = $(tr).find('input[name="hp"]');
var newValue = parseInt($input.val(), 10) - dataValue;
$input.val(newValue);
});
var hpIndex = findById( characterId );
hpIndex.hp = parseInt(hpIndex.hp) - dataValue;
});
$(document).on('click', '.hp-plus', function() {
var characterId = $(this).closest('tr').data('character-id');
var dataValue = parseInt($(this).data('value'), 10);
var allTrsWithCharacterId = document.querySelectorAll(`tr[data-character-id="${characterId}"]`);
allTrsWithCharacterId.forEach(function(tr) {
var $input = $(tr).find('input[name="hp"]');
var newValue = parseInt($input.val(), 10) + dataValue;
$input.val(newValue);
});
var hpIndex = findById( characterId );
hpIndex.hp = parseInt(hpIndex.hp) + dataValue;
});
});
let currentCharacter;
let roundCount = 0;
let roundHistory = [];
let characterInitiativeList = [];
function findById(id) {
return characterInitiativeList.find(item => item.id === id);
}
function findByIdAndRemove(id, array) {
const index = array.findIndex(item => item.id === id);
if (index !== -1) {
array.splice(index, 1);
}
}
const resetCharBtn = document.getElementById('character-reset');
const resetCharacter = async function (event) {
formReset();
}
const resetListBtn = document.getElementById('list-reset');
const resetListEvent = async function (event) {
resetList();
}
const nextCharBtn = document.getElementById('list-next');
const nextCharacter = async function (event) {
cycleCharacter();
}
function cycleCharacter() {
if ( !currentCharacter ) {
currentCharacter = 0;
}
if ( currentCharacter == characterInitiativeList.length ) {
currentCharacter = 0;
roundCount++;
addRoundHistory();
updateRoundCount();
}
if ( !characterInitiativeList[currentCharacter] ) {
currentCharacter = 0;
}
var allTrs = document.querySelectorAll(`tr`);
allTrs.forEach(function(tr) {
tr.classList.remove("success");
});
var allTrsWithCharacterId = document.querySelectorAll(`tr[data-character-id="${characterInitiativeList[currentCharacter].id}"]`);
allTrsWithCharacterId.forEach(function(tr) {
tr.classList.add("success");
});
currentCharacter++;
}
const clearListBtn = document.getElementById('list-clear');
const clearListEvent = async function (event) {
clearList();
hideList();
}
const sortCharBtn = document.getElementById('character-sort');
const sortCharacters = async function (event) {
event.preventDefault();
sortthem();
}
function sortthem() {
var fieldName = document.getElementById('sortBy').value;
clearListHTML();
resetList();
var newList = sortCharacterListByField( fieldName, characterInitiativeList );
for (let i = 0; i < newList.length; i++) {
addCharacterRow( newList[i] );
}
}
function sortCharacterListByField( fieldName, list ) {
if ( 'id' == fieldName ) {
return list;
}
let sortedList = [...list];
sortedList.sort( ( a, b ) => {
let fieldA = a[fieldName];
let fieldB = b[fieldName];
if ( 'type' == fieldName || 'name' == fieldName ) {
return fieldA.localeCompare(fieldB);
}
if (fieldA > fieldB) {
return -1;
}
if (fieldA < fieldB) {
return 1;
}
return 0;
});
return sortedList;
}
const addCharBtn = document.getElementById('character-add');
const addCharacter = function (event) {
createCharacterFromForm();
}
function createCharacterFromForm() {
showList();
var id = Date.now().toString(36) + Math.random().toString(36).substring(2);;
var name = document.getElementById('name').value;
if ( !name ) {
name = '4816';
}
var initiative = document.getElementById('initiative').value;
if ( !initiative ) {
initiative = getRandomInt( 1, 21 );
}
initiative = parseInt( initiative );
var ac = document.getElementById('ac').value;
if ( !ac ) {
ac = 0;
}
ac = parseInt( ac );
var hp = document.getElementById('hp').value;
if ( !hp ) {
hp = 0;
}
hp = parseInt( hp );
var characterType = document.querySelector('input[name="characterType"]:checked').value;
var character = {
id: id,
name: name,
initiative: initiative,
ac: ac,
hp: hp,
type: characterType,
};
characterInitiativeList.push( character );
// re-order the list by initiative to keep the next character working properly
characterInitiativeList = sortCharacterListByField( 'initiative', characterInitiativeList );
addCharacterRow( character );
addRoundRow( character );
}
const d20Btn = document.getElementById('d20-roll');
const rollD20 = async function (event) {
event.preventDefault();
var resultDiv = document.getElementById('initiative');
resultDiv.value = getRandomInt( 1, 21 );
}
const resetRoundsBtn = document.getElementById('rounds-reset');
const resetRoundsEvent = async function (event) {
resetRoundCount();
}
const clearRoundsBtn = document.getElementById('rounds-clear');
const clearRoundsEvent = async function (event) {
clearRounds();
}
window.addEventListener('DOMContentLoaded', (event) => {
d20Btn.addEventListener('click', rollD20);
addCharBtn.addEventListener('click', addCharacter);
resetCharBtn.addEventListener('click', resetCharacter);
resetListBtn.addEventListener('click', resetListEvent);
clearListBtn.addEventListener('click', clearListEvent);
nextCharBtn.addEventListener('click', nextCharacter);
resetRoundsBtn.addEventListener('click', resetRoundsEvent);
clearRoundsBtn.addEventListener('click', clearRoundsEvent);
sortCharBtn.addEventListener('click', sortCharacters);
updateRoundCount();
});
function formReset() {
document.getElementById('name').value = null;
document.getElementById('initiative').value = null;
document.getElementById('ac').value = null;
document.getElementById('hp').value = null;
}
function showList() {
var tbody = document.getElementById('character-container');
tbody.style.display = '';
}
function addCharacterRow( character ) {
var characterList = document.getElementById('character-list');
var pcList = document.getElementById('character-list-pc');
var npcList = document.getElementById('character-list-npc');
var row = document.createElement('tr');
row.setAttribute('data-character-id', character.id);
var hpStyle = '';
var acStyle = '';
var checkbox = document.getElementById('trackHP');
if ( !checkbox.checked ) {
var hpStyle = 'style="display: none;"';
}
var checkbox = document.getElementById('trackAC');
if ( !checkbox.checked ) {
var acStyle = 'style="display: none;"';
}
row.innerHTML = `
<td>${character.name}</td>
<td class="text-center">${character.initiative}</td>
<td class="ac-tracker text-center"${acStyle}>${character.ac}</td>
<td class="hp-tracker text-center"${hpStyle}>
<div class="form-group hp-tracker list-controls-center">
<div class="input-group col-lg-6">
<div class="input-group-btn">
<button class="hp-minus btn btn-danger" data-value="1" aria-label="Remove 1 hp">-1</button>
<button class="hp-minus btn btn-danger" data-value="5" aria-label="Remove 5 hp">-5</button>
<button class="hp-minus btn btn-danger" data-value="10" aria-label="Remove 10 hp">-10</button>
</div>
<input type="number" class="form-control" name="hp" value="${character.hp}">
<div class="input-group-btn">
<button class="hp-plus btn btn-success" data-value="10" aria-label="Add 10 hp">+10</button>
<button class="hp-plus btn btn-success" data-value="5" aria-label="Add 5 hp">+5</button>
<button class="hp-plus btn btn-success" data-value="1" aria-label="Add 1 hp">+1</button>
</div>
</div>
</div>
</td>
<td class="text-center">${character.type}</td>
<td class="text-right"><button class="btn btn-danger btn-sm character-remove" aria-label="Add 10 hp"><span class="glyphicon glyphicon-trash"></span></button></td>
`;
// Append the new row to the table body
characterList.appendChild(row);
if ( 'pc' == character.type ) {
var pc_row = row.cloneNode(true);
pcList.appendChild(pc_row);
}
if ( 'npc' == character.type ) {
var npc_row = row.cloneNode(true);
npcList.appendChild(npc_row);
}
}
function hideList() {
var tbody = document.getElementById('character-container');
tbody.style.display = 'none';
}
function clearList() {
characterInitiativeList = [];
clearListHTML();
}
function clearListHTML() {
var tbody = document.getElementById('character-list');
tbody.innerHTML = '';
var tbody = document.getElementById('character-list-pc');
tbody.innerHTML = '';
var tbody = document.getElementById('character-list-npc');
tbody.innerHTML = '';
}
function resetList() {
currentCharacter = 0;
var allTrsWithCharacterId = document.querySelectorAll(`tr`);
allTrsWithCharacterId.forEach(function(tr) {
tr.classList.remove("success");
});
}
function clearRounds() {
var headers = document.getElementById('rounds-history-header-row');
var thElements = headers.getElementsByTagName('th');
// Loop through the th elements in reverse order to safely remove them without affecting the iteration
for (var i = thElements.length - 1; i > 0; i--) {
thElements[i].parentNode.removeChild(thElements[i]);
}
var history = document.getElementById('rounds-history');
var trElements = history.getElementsByTagName('tr');
for (var i = 0; i < trElements.length; i++) {
var elements = trElements[i].getElementsByTagName('td');
for (var x = elements.length - 1; x > 0; x--) {
elements[x].parentNode.removeChild(elements[x]);
}
}
roundCount = 0;
updateRoundCount();
}
function clearCharacters() {
var history = document.getElementById('rounds-history');
var trElements = history.getElementsByTagName('tr');
for (var i = 0; i < trElements.length; i++) {
trElements[i].remove();
}
}
function resetRoundCount() {
roundCount = 0;
updateRoundCount();
}
function updateRoundCount() {
var round = document.getElementById('round-count');
round.innerText = roundCount;
}
function addRoundRow( character ) {
var characterList = document.getElementById('rounds-history');
var row = document.createElement('tr');
row.setAttribute('data-round-character-id', character.id);
row.innerHTML = `<td class="char-name">${character.name}</td>`;
characterList.appendChild(row);
}
function addRoundHistory() {
var headers = document.getElementById('rounds-history-header');
var newHeader = document.createElement('th');
newHeader.innerText = "Round " + roundCount;
newHeader.classList.add("text-center");
headers.after( newHeader );
for (let i = 0; i < characterInitiativeList.length; i++) {
var char = characterInitiativeList[i];
var newCol = document.createElement('td');
newCol.innerText = char.hp;
newCol.classList.add("text-center");
var allTrsWithCharacterId = document.querySelector(`tr[data-round-character-id="${char.id}"]`);
var indexd = allTrsWithCharacterId.getElementsByClassName('char-name');
indexd[0].after( newCol );
}
}