415 lines
13 KiB
JavaScript
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 );
|
|
}
|
|
}
|