Feat: Decks page.
This commit is contained in:
@@ -150,6 +150,7 @@ export default class BasePage {
|
||||
toggleShowButtonsSaveCancel(show, buttonContainerSelector = null) { // , buttonSave = null, buttonCancel = null
|
||||
if (Validation.isEmpty(buttonContainerSelector)) buttonContainerSelector = '.' + flagContainer + '.' + flagSave + '.' + flagCancel;
|
||||
let buttonSave = document.querySelector(buttonContainerSelector + ' ' + idButtonSave);
|
||||
if (buttonSave == null) return;
|
||||
let buttonCancel = document.querySelector(buttonContainerSelector + ' ' + idButtonCancel);
|
||||
Utils.consoleLogIfNotProductionEnvironment({ show, buttonContainerSelector, buttonCancel, buttonSave });
|
||||
if (show) {
|
||||
|
||||
@@ -335,6 +335,7 @@ export default class TableBasePage extends BasePage {
|
||||
cacheRowBlank() {
|
||||
let selectorRowNew = idTableMain + ' tbody tr.' + flagRowNew;
|
||||
let rowBlankTemp = document.querySelector(selectorRowNew);
|
||||
if (rowBlankTemp == null) return;
|
||||
Utils.consoleLogIfNotProductionEnvironment("row blank temp: ", rowBlankTemp);
|
||||
let countRows = document.querySelectorAll(idTableMain + ' > tbody > tr').length;
|
||||
_rowBlank = rowBlankTemp.cloneNode(true);
|
||||
@@ -734,11 +735,15 @@ export default class TableBasePage extends BasePage {
|
||||
}
|
||||
|
||||
updateAndToggleShowButtonsSaveCancel() {
|
||||
let pageBody = document.querySelector(idPageBody);
|
||||
// let pageBody = document.querySelector(idPageBody);
|
||||
let isDirty = DOM.hasDirtyChildrenContainer(pageBody);
|
||||
|
||||
console.log({ pageBody, isDirty });
|
||||
let buttonContainerSelector = '.' + flagContainer + '.' + flagSave + '.' + flagCancel;
|
||||
let buttonSave = document.querySelector(buttonContainerSelector + ' ' + idButtonSave);
|
||||
let areVisibleSaveCancelButtons = !buttonSave.classList.contains(flagIsCollapsed);
|
||||
|
||||
console.log({ pageBody, isDirty, areVisibleSaveCancelButtons });
|
||||
|
||||
this.toggleShowButtonsSaveCancel(isDirty);
|
||||
this.toggleShowButtonsSaveCancel(isDirty || areVisibleSaveCancelButtons);
|
||||
}
|
||||
}
|
||||
|
||||
110
static/js/pages/tcg/mtg_decks.js
Normal file
110
static/js/pages/tcg/mtg_decks.js
Normal file
@@ -0,0 +1,110 @@
|
||||
|
||||
import API from "../../api.js";
|
||||
import Events from "../../lib/events.js";
|
||||
import TableBasePage from "../base_table.js";
|
||||
import Utils from "../../lib/utils.js";
|
||||
|
||||
export default class PageMtgDecks extends TableBasePage {
|
||||
static hash = hashPageMtgDecks;
|
||||
static attrIdRowObject = attrDeckId;
|
||||
callSaveTableContent = API.saveDeck;
|
||||
|
||||
constructor(router) {
|
||||
super(router);
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.sharedInitialize();
|
||||
}
|
||||
hookupFilters() {
|
||||
/*
|
||||
this.sharedHookupFilters();
|
||||
this.hookupFilterActive();
|
||||
*/
|
||||
}
|
||||
|
||||
loadRowTable(rowJson) {
|
||||
if (rowJson == null) return;
|
||||
if (_verbose) { Utils.consoleLogIfNotProductionEnvironment("applying data row: ", rowJson); }
|
||||
}
|
||||
getJsonRow(row) {
|
||||
return;
|
||||
}
|
||||
initialiseRowNew(tbody, row) {
|
||||
}
|
||||
postInitialiseRowNewCallback(tbody) {
|
||||
let newRows = tbody.querySelectorAll('tr.' + flagRowNew);
|
||||
let newestRow = newRows[0];
|
||||
let clickableElementsSelector = [
|
||||
'td.' + attrCommanderBracketId + ' div.' + attrCommanderBracketId
|
||||
].join('');
|
||||
newestRow.querySelectorAll(clickableElementsSelector).forEach((clickableElement) => {
|
||||
clickableElement.click();
|
||||
});
|
||||
}
|
||||
|
||||
hookupTableMain() {
|
||||
super.hookupTableMain();
|
||||
this.hookupTableMainRows();
|
||||
this.hookupFieldsNameTable();
|
||||
this.hookupTableMainIsCommanderCheckboxes();
|
||||
this.hookupTableMainCommanderBracketPreviews();
|
||||
this.hookupFieldsActive();
|
||||
}
|
||||
hookupTableMainRows() {
|
||||
return;
|
||||
let rowSelector = 'table.' + flagTableMain + ' tbody tr';
|
||||
Events.hookupEventHandler("click", rowSelector, (event, row) => {
|
||||
let isRowExpanded = row.classList.contains(flagActive);
|
||||
let showSection;
|
||||
if (isRowExpanded) {
|
||||
showSection = false;
|
||||
PageMtgDecks.toggleShowDeckStatisticsSection(showSection);
|
||||
}
|
||||
else {
|
||||
showSection = true;
|
||||
let deckId = row.getAttribute(attrDeckId);
|
||||
let statisticsSectionTableBody = document.querySelector('table.' + flagStatistics + ' tbody');
|
||||
statisticsSectionTableBody.innerHTML = '';
|
||||
let deck = decks.filter(d => d[attrDeckId] == deckId)[0];
|
||||
if (deck[flagStatistics].length > 0) {
|
||||
let newStatisticRowsHtml = '';
|
||||
deck[flagStatistics]
|
||||
.sort((a, b) => a[flagDisplayOrder] - b[flagDisplayOrder])
|
||||
.forEach((statistic) => {
|
||||
newStatisticRowsHtml += `
|
||||
<tr ${attrStatisticId}="${statistic[attrStatisticId]}">
|
||||
<td class="${flagName}">${statistic[flagName]}</td>
|
||||
<td class="${flagValue}">${statistic[flagValue]}</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
statisticsSectionTableBody.innerHTML = newStatisticRowsHtml;
|
||||
}
|
||||
PageMtgDecks.toggleShowDeckStatisticsSection(showSection);
|
||||
}
|
||||
});
|
||||
}
|
||||
static toggleShowDeckStatisticsSection(showSection) {
|
||||
let statisticsSectionTableBody = document.querySelector('table.' + flagStatistics + ' tbody');
|
||||
if (showSection) {
|
||||
statisticsSectionTableBody.classList.remove(flagIsCollapsed);
|
||||
}
|
||||
else {
|
||||
statisticsSectionTableBody.classList.add(flagIsCollapsed);
|
||||
}
|
||||
}
|
||||
hookupTableMainIsCommanderCheckboxes() {
|
||||
this.hookupChangeHandlerTableCells(idTableMain + ' td.' + flagIsCommander + ' .' + flagIsCommander);
|
||||
}
|
||||
hookupTableMainCommanderBracketPreviews() {
|
||||
this.hookupTableCellDdlPreviews(
|
||||
attrCommanderBracketId
|
||||
, Utils.getListFromDict(commanderBrackets)
|
||||
);
|
||||
}
|
||||
|
||||
leave() {
|
||||
super.leave();
|
||||
}
|
||||
}
|
||||
@@ -195,30 +195,19 @@ export default class PageMtgGame extends TableBasePage {
|
||||
renderPlayers() {
|
||||
const grid = document.getElementById('playersGrid');
|
||||
grid.innerHTML = '';
|
||||
|
||||
// Build a damage lookup: { playerId: { fromPlayerId: damageAmount } }
|
||||
/*
|
||||
const damageLookup = {};
|
||||
damageRecords.forEach(damage => {
|
||||
if (!damageLookup[damage.player_id]) {
|
||||
damageLookup[damage.player_id] = {};
|
||||
}
|
||||
if (damage.received_from_commander_player_id) {
|
||||
damageLookup[damage.player_id][damage.received_from_commander_player_id] = damage.health_change || 0;
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
let activeRoundId = PageMtgGame.getActiveRoundId();
|
||||
// let activeRoundId = PageMtgGame.getActiveRoundId();
|
||||
const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel();
|
||||
if (activeRoundId < 0) {
|
||||
const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel));
|
||||
rounds.push(PageMtgGame.makeDefaultGameRound(currentRoundDisplayOrder));
|
||||
activeRoundId = PageMtgGame.getActiveRoundId();
|
||||
const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel));
|
||||
let activeRound = rounds.filter(round => round[flagDisplayOrder] == currentRoundDisplayOrder)[0];
|
||||
if (activeRound == null) {
|
||||
activeRound = PageMtgGame.makeDefaultGameRound(currentRoundDisplayOrder);
|
||||
rounds.push(activeRound);
|
||||
}
|
||||
const latestRound = rounds.filter(round => round[attrRoundId] == activeRoundId)[0];
|
||||
DOM.setElementValueCurrent(roundDisplayOrderLabel, latestRound[flagDisplayOrder]);
|
||||
DOM.setElementValueCurrent(roundDisplayOrderLabel, activeRound[flagDisplayOrder]);
|
||||
|
||||
const previousRoundIds = rounds.filter(round => round[flagDisplayOrder] <= currentRoundDisplayOrder)
|
||||
.map(round => round[attrRoundId]);
|
||||
players.forEach((player, index) => {
|
||||
// Build display name: prefer user_name + deck_name, fallback to player name
|
||||
const playerId = player[attrPlayerId];
|
||||
@@ -228,7 +217,8 @@ export default class PageMtgGame extends TableBasePage {
|
||||
damagePlayerPairs.forEach(damagePlayerPair => {
|
||||
const sourceId = damagePlayerPair[attrPlayerId];
|
||||
const filteredPlayerDamages = damageRecords.filter(damage => (
|
||||
damage[attrRoundId] == activeRoundId
|
||||
damage[attrRoundId] == activeRound[attrRoundId]
|
||||
// previousRoundIds.includes(damage[attrRoundId])
|
||||
&& damage[attrPlayerId] == playerId
|
||||
&& damage[attrReceivedFromCommanderPlayerId] == sourceId
|
||||
)); //[playerId] || {};
|
||||
@@ -240,20 +230,30 @@ export default class PageMtgGame extends TableBasePage {
|
||||
, damageRecords.filter(damage => (
|
||||
damage[attrPlayerId] == playerId
|
||||
&& damage[attrReceivedFromCommanderPlayerId] == sourceId
|
||||
&& damage[attrReceivedFromCommanderPlayerId] != null
|
||||
&& previousRoundIds.includes(damage[attrRoundId])
|
||||
))
|
||||
.map(damage => damage[flagHealthChange])
|
||||
.reduce((acc, curr) => acc + curr, 0)
|
||||
.map(damage => damage[flagLifeLoss])
|
||||
.reduce((a, b) => a + b, 0)
|
||||
);
|
||||
});
|
||||
|
||||
const totalDamage = damageRecords.filter(damage => ( damage[attrPlayerId] == playerId ))
|
||||
.map(damage => damage[flagHealthChange])
|
||||
.reduce((acc, curr) => acc + curr, 0);
|
||||
let life = startingLife + totalDamage;
|
||||
const totalDamage = damageRecords.filter(damage => (
|
||||
damage[attrPlayerId] == playerId
|
||||
&& previousRoundIds.includes(damage[attrRoundId])
|
||||
))
|
||||
.map(damage => damage[flagLifeLoss] - damage[flagLifeGain])
|
||||
.reduce((a, b) => a + b, 0);
|
||||
let life = startingLife - totalDamage;
|
||||
|
||||
let isEliminatedByForce = damageRecords.filter(damage => ( damage[attrPlayerId] == playerId ))
|
||||
let isEliminatedByForce = damageRecords.filter(damage => (
|
||||
damage[attrPlayerId] == playerId
|
||||
&& previousRoundIds.includes(damage[attrRoundId])
|
||||
))
|
||||
.map(damage => damage[flagIsEliminated])
|
||||
.some(Boolean);
|
||||
console.log("renderPlayers");
|
||||
console.log({isEliminatedByForce, player, life, maxCommanderDamageReceived});
|
||||
const isEliminated = (
|
||||
isEliminatedByForce
|
||||
|| !player[flagActive]
|
||||
@@ -261,11 +261,13 @@ export default class PageMtgGame extends TableBasePage {
|
||||
|| maxCommanderDamageReceived >= 21
|
||||
);
|
||||
|
||||
const playerOwnDamage = damageRecords.filter(damage => (
|
||||
const totalCommanderDeaths = damageRecords.filter(damage => (
|
||||
damage[attrPlayerId] == playerId
|
||||
&& damage[attrReceivedFromCommanderPlayerId] == null
|
||||
&& damage[attrRoundId] == activeRoundId
|
||||
))[0];
|
||||
&& damage[attrRoundId] == activeRound[attrRoundId]
|
||||
))
|
||||
.map(damage => damage[flagCommanderDeaths])
|
||||
.reduce((a, b) => a + b, 0);
|
||||
const card = document.createElement('div');
|
||||
card.className = `player-card ${isEliminated ? 'eliminated' : ''}`;
|
||||
card.style.animationDelay = `${index * 0.1}s`;
|
||||
@@ -281,7 +283,7 @@ export default class PageMtgGame extends TableBasePage {
|
||||
<span>Commander Deaths:</span>
|
||||
<div class="death-counter">
|
||||
<button class="death-btn death-minus" data-player-id="${playerId}">−</button>
|
||||
<span class="death-display" data-player-id="${playerId}" ${attrValuePrevious}="${playerOwnDamage[flagCommanderDeaths]}">${playerOwnDamage[flagCommanderDeaths]}</span>
|
||||
<span class="death-display" data-player-id="${playerId}" ${attrValuePrevious}="${totalCommanderDeaths}">${totalCommanderDeaths}</span>
|
||||
<button class="death-btn death-plus" data-player-id="${playerId}">+</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -294,11 +296,19 @@ export default class PageMtgGame extends TableBasePage {
|
||||
<div class="life-total">
|
||||
<input type="hidden" class="life-value" data-player-id="${playerId}" value="${life}">
|
||||
<div class="life-display" data-player-id="${playerId}" ${attrValuePrevious}="${life}">${life}</div>
|
||||
<div class="life-controls">
|
||||
<button class="life-btn" data-player-id="${playerId}" data-amount="-5">-5</button>
|
||||
<button class="life-btn" data-player-id="${playerId}" data-amount="-1">-1</button>
|
||||
<button class="life-btn" data-player-id="${playerId}" data-amount="1">+1</button>
|
||||
<button class="life-btn" data-player-id="${playerId}" data-amount="5">+5</button>
|
||||
<label>Gain</label>
|
||||
<div class="life-gain-controls">
|
||||
<button class="life-gain-btn" data-player-id="${playerId}" data-amount="-5">-5</button>
|
||||
<button class="life-gain-btn" data-player-id="${playerId}" data-amount="-1">-1</button>
|
||||
<button class="life-gain-btn" data-player-id="${playerId}" data-amount="1">+1</button>
|
||||
<button class="life-gain-btn" data-player-id="${playerId}" data-amount="5">+5</button>
|
||||
</div>
|
||||
<label>Loss</label>
|
||||
<div class="life-loss-controls">
|
||||
<button class="life-loss-btn" data-player-id="${playerId}" data-amount="-5">-5</button>
|
||||
<button class="life-loss-btn" data-player-id="${playerId}" data-amount="-1">-1</button>
|
||||
<button class="life-loss-btn" data-player-id="${playerId}" data-amount="1">+1</button>
|
||||
<button class="life-loss-btn" data-player-id="${playerId}" data-amount="5">+5</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -325,22 +335,25 @@ export default class PageMtgGame extends TableBasePage {
|
||||
this.hookupPlayerCardEvents();
|
||||
}
|
||||
static renderCommanderDamageLog() {
|
||||
const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel();
|
||||
const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel));
|
||||
const currentRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder();
|
||||
|
||||
const damageTableBody = document.querySelector('.' + flagDamageLog + '.' + flagContainer + ' table tbody');
|
||||
damageTableBody.innerHTML = '';
|
||||
|
||||
const previousRoundIds = rounds.filter(round => round[flagDisplayOrder] <= currentRoundDisplayOrder)
|
||||
.map(round => round[attrRoundId]);
|
||||
let newTableBodyHtml = '';
|
||||
damageRecords.forEach((damage) => {
|
||||
if (
|
||||
damage[flagActive]
|
||||
&& (
|
||||
damage[flagCommanderDeaths] > 0
|
||||
|| damage[flagHealthChange] != 0
|
||||
|| damage[flagLifeGain] != 0
|
||||
|| damage[flagLifeLoss] != 0
|
||||
|| damage[flagIsEliminated]
|
||||
)
|
||||
&& rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0][flagDisplayOrder] <= currentRoundDisplayOrder
|
||||
// && rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0][flagDisplayOrder] <= currentRoundDisplayOrder
|
||||
&& previousRoundIds.includes(damage[attrRoundId])
|
||||
) {
|
||||
let round = rounds.filter(r => r[attrRoundId] == damage[attrRoundId])[0];
|
||||
let player = players.filter(p => p[attrPlayerId] == damage[attrPlayerId])[0];
|
||||
@@ -350,7 +363,8 @@ export default class PageMtgGame extends TableBasePage {
|
||||
<td class="${attrRoundId}">${round[flagDisplayOrder]}</td>
|
||||
<td class="${attrPlayerId}">${player[flagName]}</td>
|
||||
<td class="${attrReceivedFromCommanderPlayerId}">${receivedFromPlayer[flagName]}</td>
|
||||
<td class="${flagHealthChange}">${damage[flagHealthChange]}</td>
|
||||
<td class="${flagLifeGain}">${damage[flagLifeGain]}</td>
|
||||
<td class="${flagLifeLoss}">${damage[flagLifeLoss]}</td>
|
||||
<td class="${flagCommanderDeaths}">${damage[flagCommanderDeaths]}</td>
|
||||
<td class="${flagIsEliminated}">${damage[flagIsEliminated]}</td>
|
||||
</tr>
|
||||
@@ -366,8 +380,10 @@ export default class PageMtgGame extends TableBasePage {
|
||||
, [attrRoundId]: roundId
|
||||
, [attrPlayerId]: playerId
|
||||
, [attrReceivedFromCommanderPlayerId]: receivedFromCommanderPlayerId
|
||||
, [flagHealthChange]: 0
|
||||
, [flagLifeGain]: 0
|
||||
, [flagLifeLoss]: 0
|
||||
, [flagCommanderDeaths]: 0
|
||||
, [flagIsEliminated]: false
|
||||
, [flagActive]: true
|
||||
};
|
||||
}
|
||||
@@ -384,10 +400,13 @@ export default class PageMtgGame extends TableBasePage {
|
||||
}
|
||||
return roundId;
|
||||
}
|
||||
static getActiveRoundId() {
|
||||
static getActiveRoundDisplayOrder() {
|
||||
const roundDisplayOrderLabel = PageMtgGame.getRoundDisplayOrderLabel();
|
||||
const currentRoundDisplayOrder = Number(DOM.getElementValueCurrent(roundDisplayOrderLabel));
|
||||
let roundId = -1;
|
||||
return Number(DOM.getElementValueCurrent(roundDisplayOrderLabel));
|
||||
}
|
||||
static getActiveRoundId() {
|
||||
const currentRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder();
|
||||
let roundId = 0;
|
||||
if (rounds.length > 0) {
|
||||
let filteredRounds = rounds.filter(round => round[flagDisplayOrder] == currentRoundDisplayOrder);
|
||||
if (filteredRounds.length > 0) roundId = filteredRounds[0][attrRoundId];
|
||||
@@ -406,7 +425,9 @@ export default class PageMtgGame extends TableBasePage {
|
||||
return player[flagName] || `${(user == null) ? 'Error' : user[flagName]} - ${(deck == null) ? 'Error' : deck[flagName]}`;
|
||||
}
|
||||
static renderCommanderDamageRows(playerId) {
|
||||
// const roundId = PageMtgGame.getLatestRoundId();
|
||||
const activeRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder();
|
||||
const previousRoundIds = rounds.filter(round => round[flagDisplayOrder] <= activeRoundDisplayOrder)
|
||||
.map(round => round[attrRoundId]);
|
||||
return players
|
||||
.filter(otherPlayer => otherPlayer[attrPlayerId] !== playerId)
|
||||
.map(otherPlayer => {
|
||||
@@ -415,10 +436,12 @@ export default class PageMtgGame extends TableBasePage {
|
||||
const totalDamage = damageRecords.filter(damage => (
|
||||
damage[attrPlayerId] == playerId
|
||||
&& damage[attrReceivedFromCommanderPlayerId] == sourceId
|
||||
// && damage[attrRoundId] == roundId
|
||||
&& previousRoundIds.includes(damage[attrRoundId])
|
||||
))
|
||||
.map(damage => -damage[flagHealthChange])
|
||||
.reduce((acc, curr) => acc + curr, 0);
|
||||
const isLethal = totalDamage >= 21;
|
||||
.map(damage => damage[flagLifeLoss])
|
||||
.reduce((acc, curr) => acc + curr, 0);
|
||||
const isLethal = (totalDamage >= 21);
|
||||
|
||||
return `
|
||||
<div class="damage-row" data-player-id="${playerId}" data-source-id="${sourceId}">
|
||||
@@ -460,9 +483,9 @@ export default class PageMtgGame extends TableBasePage {
|
||||
};
|
||||
}
|
||||
hookupPlayerCardEvents() {
|
||||
// Life buttons
|
||||
let lifeButtonSelector = '.life-btn';
|
||||
Events.hookupEventHandler("click", lifeButtonSelector, (event, button) => {
|
||||
// Life gain buttons
|
||||
let lifeGainButtonSelector = '.life-gain-btn';
|
||||
Events.hookupEventHandler("click", lifeGainButtonSelector, (event, button) => {
|
||||
const playerId = button.dataset.playerId;
|
||||
const amount = parseInt(button.dataset.amount);
|
||||
const activeRoundId = PageMtgGame.getActiveRoundId();
|
||||
@@ -474,6 +497,27 @@ export default class PageMtgGame extends TableBasePage {
|
||||
this.changeLife(
|
||||
playerId // playerId
|
||||
, amount // amount
|
||||
, true // isLifeGainNotLoss
|
||||
, true // updateDamage
|
||||
, damageIndex // damageIndex
|
||||
);
|
||||
});
|
||||
|
||||
// Life loss buttons
|
||||
let lifeLossButtonSelector = '.life-loss-btn';
|
||||
Events.hookupEventHandler("click", lifeLossButtonSelector, (event, button) => {
|
||||
const playerId = button.dataset.playerId;
|
||||
const amount = parseInt(button.dataset.amount);
|
||||
const activeRoundId = PageMtgGame.getActiveRoundId();
|
||||
const damageIndex = damageRecords.findIndex(damage => (
|
||||
damage[attrRoundId] == activeRoundId
|
||||
&& damage[attrPlayerId] == playerId
|
||||
&& damage[attrReceivedFromCommanderPlayerId] == null
|
||||
));
|
||||
this.changeLife(
|
||||
playerId // playerId
|
||||
, amount // amount
|
||||
, false // isLifeGainNotLoss
|
||||
, true // updateDamage
|
||||
, damageIndex // damageIndex
|
||||
);
|
||||
@@ -506,22 +550,24 @@ export default class PageMtgGame extends TableBasePage {
|
||||
});
|
||||
}
|
||||
|
||||
changeLife(playerId, amount, updateDamage = false, damageIndex = null) {
|
||||
changeLife(playerId, amount, isLifeGainNotLoss = false, updateDamage = false, damageIndex = null) {
|
||||
const card = document.querySelector(`.player-card[data-player-id="${playerId}"]`);
|
||||
if (!card || card.classList.contains('eliminated')) return;
|
||||
// if (!card || card.classList.contains('eliminated')) return;
|
||||
|
||||
const lifeInput = card.querySelector(`.life-value[data-player-id="${playerId}"]`);
|
||||
const lifeDisplay = card.querySelector(`.life-display[data-player-id="${playerId}"]`);
|
||||
|
||||
const currentLife = parseInt(lifeInput.value) || 0;
|
||||
const newLife = Math.max(0, currentLife + amount);
|
||||
const newLife = currentLife + amount * ((isLifeGainNotLoss) ? 1 : -1);
|
||||
|
||||
DOM.setElementAttributeValueCurrent(lifeDisplay, newLife);
|
||||
DOM.isElementDirty(lifeDisplay);
|
||||
lifeInput.value = newLife;
|
||||
lifeDisplay.textContent = newLife;
|
||||
|
||||
if (updateDamage) {
|
||||
damageRecords[damageIndex][flagHealthChange] += amount;
|
||||
let fieldFlag = (isLifeGainNotLoss) ? flagLifeGain : flagLifeLoss;
|
||||
damageRecords[damageIndex][fieldFlag] += amount;
|
||||
}
|
||||
|
||||
PageMtgGame.renderCommanderDamageLog();
|
||||
@@ -532,7 +578,7 @@ export default class PageMtgGame extends TableBasePage {
|
||||
|
||||
changeCommanderDamage(playerId, sourceId, amount) {
|
||||
const card = document.querySelector(`.player-card[data-player-id="${playerId}"]`);
|
||||
if (!card || card.classList.contains('eliminated')) return;
|
||||
// if (!card || card.classList.contains('eliminated')) return;
|
||||
|
||||
const damageInput = card.querySelector(`.damage-value[data-player-id="${playerId}"][data-source-id="${sourceId}"]`);
|
||||
const damageDisplay = card.querySelector(`.damage-display[data-player-id="${playerId}"][data-source-id="${sourceId}"]`);
|
||||
@@ -558,11 +604,13 @@ export default class PageMtgGame extends TableBasePage {
|
||||
&& damageRecord[attrPlayerId] == playerId
|
||||
&& damageRecord[attrReceivedFromCommanderPlayerId] == sourceId
|
||||
));
|
||||
damageRecords[damageIndex][flagHealthChange] -= amount;
|
||||
damageRecords[damageIndex][flagLifeLoss] += amount;
|
||||
|
||||
let isLifeGainNotLoss = false;
|
||||
this.changeLife(
|
||||
playerId // playerId
|
||||
, -amount // amount
|
||||
, isLifeGainNotLoss // isLifeGainNotLoss
|
||||
, false // updateDamage
|
||||
, damageIndex // damageIndex
|
||||
);
|
||||
@@ -571,7 +619,7 @@ export default class PageMtgGame extends TableBasePage {
|
||||
|
||||
changeCommanderDeaths(playerId, amount) {
|
||||
const card = document.querySelector(`.player-card[data-player-id="${playerId}"]`);
|
||||
if (!card || card.classList.contains('eliminated')) return;
|
||||
// if (!card || card.classList.contains('eliminated')) return;
|
||||
|
||||
const deathDisplay = card.querySelector(`.death-display[data-player-id="${playerId}"]`);
|
||||
const currentDeaths = parseInt(deathDisplay.textContent) || 0;
|
||||
@@ -641,14 +689,14 @@ export default class PageMtgGame extends TableBasePage {
|
||||
, [flagDisplayOrder]: index
|
||||
});
|
||||
});
|
||||
let activeRoundId = PageMtgGame.getActiveRoundId();
|
||||
let activeRoundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder();
|
||||
let newPlayerGridInnerHTML = '';
|
||||
let playerIdA, playerIdB, isEliminatedAsIntA, isEliminatedAsIntB, playerA, playerB, indexPlayerCard;
|
||||
playerCardMetas.sort((a, b) => {
|
||||
playerIdA = a[attrPlayerId];
|
||||
playerIdB = b[attrPlayerId];
|
||||
isEliminatedAsIntA = PageMtgGame.isPlayerEliminated(playerIdA, activeRoundId) ? 1 : 0;
|
||||
isEliminatedAsIntB = PageMtgGame.isPlayerEliminated(playerIdB, activeRoundId) ? 1 : 0;
|
||||
isEliminatedAsIntA = PageMtgGame.isPlayerEliminated(playerIdA, activeRoundDisplayOrder) ? 1 : 0;
|
||||
isEliminatedAsIntB = PageMtgGame.isPlayerEliminated(playerIdB, activeRoundDisplayOrder) ? 1 : 0;
|
||||
playerA = players.filter(p => p[attrPlayerId] == playerIdA)[0];
|
||||
playerB = players.filter(p => p[attrPlayerId] == playerIdB)[0];
|
||||
return (
|
||||
@@ -671,35 +719,41 @@ export default class PageMtgGame extends TableBasePage {
|
||||
|
||||
this.hookupPlayerCardEvents();
|
||||
}
|
||||
static isPlayerEliminated(playerId, roundId = null) {
|
||||
if (roundId == null) roundId = PageMtgGame.getActiveRoundId();
|
||||
static isPlayerEliminated(playerId, roundDisplayOrder = null) {
|
||||
if (roundDisplayOrder == null) roundDisplayOrder = PageMtgGame.getActiveRoundDisplayOrder();
|
||||
const filteredRoundIds = rounds.filter(round => round[flagDisplayOrder] <= roundDisplayOrder)
|
||||
.map(round => round[attrRoundId]);
|
||||
let hasDamageWithIsEliminated = damageRecords.filter(damage => (
|
||||
damage[attrRoundId] <= roundId
|
||||
// damage[attrRoundId] <= roundDisplayOrder
|
||||
filteredRoundIds.includes(damage[attrRoundId])
|
||||
&& damage[attrPlayerId] == playerId
|
||||
&& damage[flagIsEliminated]
|
||||
)).length > 0;
|
||||
let damageFromOtherPlayers = {};
|
||||
let otherPlayerId;
|
||||
damageRecords.filter(damage => (
|
||||
damage[attrRoundId] <= roundId
|
||||
// damage[attrRoundId] <= roundId
|
||||
filteredRoundIds.includes(damage[attrRoundId])
|
||||
&& damage[attrPlayerId] == playerId
|
||||
&& damage[attrReceivedFromCommanderPlayerId] != null
|
||||
))
|
||||
.forEach((damage) => {
|
||||
otherPlayerId = damage[attrReceivedFromCommanderPlayerId];
|
||||
damageFromOtherPlayers[otherPlayerId] =
|
||||
damage[flagHealthChange]
|
||||
damage[flagLifeLoss]
|
||||
+ ((damageFromOtherPlayers[otherPlayerId] == null) ? 0 : damageFromOtherPlayers[otherPlayerId]);
|
||||
});
|
||||
let maxDamageFromOtherCommander = Math.max(Object.keys(damageFromOtherPlayers)
|
||||
.map((playerId) => damageFromOtherPlayers[playerId]));
|
||||
// .reduce((acc, cur) => acc + cur, 0);
|
||||
let maxDamageFromOtherCommander = Object.keys(damageFromOtherPlayers)
|
||||
.map((playerId) => damageFromOtherPlayers[playerId])
|
||||
.reduce((acc, cur) => Math.max(acc, cur), 0);
|
||||
let totalDamageTaken = damageRecords.filter(damage => (
|
||||
damage[attrRoundId] <= roundId
|
||||
// damage[attrRoundId] <= roundId
|
||||
filteredRoundIds.includes(damage[attrRoundId])
|
||||
&& damage[attrPlayerId] == playerId
|
||||
))
|
||||
.map((damage) => damage[flagHealthChange])
|
||||
.reduce((acc, cur) => acc + cur, 0);
|
||||
.map((damage) => damage[flagLifeLoss] - damage[flagLifeGain])
|
||||
.reduce((a, b) => a + b, 0);
|
||||
console.log({ roundDisplayOrder, filteredRoundIds, hasDamageWithIsEliminated, maxDamageFromOtherCommander, totalDamageTaken });
|
||||
return (
|
||||
hasDamageWithIsEliminated
|
||||
|| maxDamageFromOtherCommander >= 21
|
||||
@@ -771,7 +825,7 @@ export default class PageMtgGame extends TableBasePage {
|
||||
|
||||
userId = DOM.getElementValueCurrent(userDdl);
|
||||
deckId = DOM.getElementValueCurrent(deckDdl);
|
||||
name = nameInput ? nameInput.value.trim() || `Player ${i + 1}` : `Player ${i + 1}`;
|
||||
name = nameInput ? nameInput.value.trim() || null : null; // `Player ${i + 1}` : `Player ${i + 1}`;
|
||||
|
||||
playerId = playerSetupWrapper.getAttribute(attrPlayerId);
|
||||
player = players.filter(p => p[attrPlayerId] == playerId)[0];
|
||||
|
||||
@@ -14,12 +14,34 @@ export default class PageMtgGames extends TableBasePage {
|
||||
|
||||
initialize() {
|
||||
this.sharedInitialize();
|
||||
}
|
||||
hookupFilters() {
|
||||
/*
|
||||
this.sharedHookupFilters();
|
||||
this.hookupFilterActive();
|
||||
*/
|
||||
}
|
||||
|
||||
loadRowTable(rowJson) {
|
||||
if (rowJson == null) return;
|
||||
if (_verbose) { Utils.consoleLogIfNotProductionEnvironment("applying data row: ", rowJson); }
|
||||
}
|
||||
getJsonRow(row) {
|
||||
return;
|
||||
}
|
||||
initialiseRowNew(tbody, row) {
|
||||
}
|
||||
postInitialiseRowNewCallback(tbody) {
|
||||
}
|
||||
|
||||
hookupTableMain() {
|
||||
super.hookupTableMain();
|
||||
// this.hookupTableMainRows();
|
||||
this.hookupTcgGames();
|
||||
// PageMtgGames.hideNewGameForm();
|
||||
}
|
||||
hookupTcgGames() {
|
||||
this.initGamesPage();
|
||||
}
|
||||
initGamesPage() {
|
||||
console.log("hookupTableMain PageMtgGames");
|
||||
// Initialize form submission
|
||||
const newGameForm = document.getElementById('newGameForm');
|
||||
if (newGameForm) {
|
||||
@@ -55,7 +77,7 @@ export default class PageMtgGames extends TableBasePage {
|
||||
newGameButton.addEventListener('click', PageMtgGames.showNewGameForm);
|
||||
}
|
||||
const cancelNewGameButtons = document.querySelectorAll(
|
||||
'#newGameForm .form-actions .btn-tcg.btn-tcg-secondary'
|
||||
'#newGameForm .form-actions .btn-tcg.btn-tcg-secondary'
|
||||
+ ','
|
||||
+ '#newGameModal .modal-content .modal-header .modal-close'
|
||||
);
|
||||
@@ -69,7 +91,7 @@ export default class PageMtgGames extends TableBasePage {
|
||||
static showNewGameForm() {
|
||||
const modal = document.getElementById('newGameModal');
|
||||
if (modal) {
|
||||
modal.classList.remove('hidden');
|
||||
modal.classList.remove(flagIsCollapsed);
|
||||
document.body.style.overflow = 'hidden';
|
||||
|
||||
// Focus on first input
|
||||
@@ -82,7 +104,7 @@ export default class PageMtgGames extends TableBasePage {
|
||||
static hideNewGameForm() {
|
||||
const modal = document.getElementById('newGameModal');
|
||||
if (modal) {
|
||||
modal.classList.add('hidden');
|
||||
modal.classList.add(flagIsCollapsed);
|
||||
document.body.style.overflow = '';
|
||||
|
||||
// Reset form
|
||||
@@ -182,7 +204,7 @@ export default class PageMtgGames extends TableBasePage {
|
||||
if (errorLabel) {
|
||||
errorLabel.textContent = message;
|
||||
}
|
||||
errorOverlay.classList.remove('hidden');
|
||||
errorOverlay.classList.remove(flagIsCollapsed);
|
||||
errorOverlay.style.display = 'flex';
|
||||
} else {
|
||||
// Fallback to alert
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Pages
|
||||
// Core
|
||||
// TCG
|
||||
import PageMtgDecks from './pages/tcg/mtg_decks.js';
|
||||
import PageMtgGame from './pages/tcg/mtg_game.js';
|
||||
import PageMtgGames from './pages/tcg/mtg_games.js';
|
||||
import PageMtgHome from './pages/tcg/mtg_home.js';
|
||||
@@ -28,6 +29,7 @@ export default class Router {
|
||||
this.pages = {};
|
||||
// Core
|
||||
// TCG
|
||||
this.pages[hashPageMtgDecks] = { name: 'PageMtgDecks', module: PageMtgDecks };
|
||||
this.pages[hashPageMtgGame] = { name: 'PageMtgGame', module: PageMtgGame };
|
||||
this.pages[hashPageMtgGames] = { name: 'PageMtgGames', module: PageMtgGames };
|
||||
this.pages[hashPageMtgHome] = { name: 'PageMtgGame', module: PageMtgHome };
|
||||
@@ -45,6 +47,7 @@ export default class Router {
|
||||
this.routes = {};
|
||||
// Core
|
||||
// TCG
|
||||
this.routes[hashPageMtgDecks] = (isPopState = false) => this.navigateToHash(hashPageMtgDecks, isPopState);
|
||||
this.routes[hashPageMtgGame] = (isPopState = false) => this.navigateToHash(hashPageMtgGame, isPopState);
|
||||
this.routes[hashPageMtgGames] = (isPopState = false) => this.navigateToHash(hashPageMtgGames, isPopState);
|
||||
this.routes[hashPageMtgHome] = (isPopState = false) => this.navigateToHash(hashPageMtgHome, isPopState);
|
||||
|
||||
Reference in New Issue
Block a user