Initial commit
This commit is contained in:
414
app/plugins/initiativetracker/js/initiative.js
Normal file
414
app/plugins/initiativetracker/js/initiative.js
Normal file
@ -0,0 +1,414 @@
|
||||
$(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 );
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user