import { SoSCardDeck } from "./sos-card-deck.js"; import { SoSUtility } from "./sos-utility.js"; import { SoSFlipDialog } from "./sos-flip-dialog.js"; import { SoSDialogCombatActions } from "./sos-dialog-combat-actions.js"; /* -------------------------------------------- */ export class SoSCombat extends Combat { /* -------------------------------------------- */ requestActions() { if (game.user.isGM && !this.actionsRequested) { console.log("REQUEST ACTIONS !!!") this.actionsRequested = true; this.phaseSetup = {}; // Reset each new round/update for (let combatant of this.combatants) { this.setInitiative(combatant.id, -1); // Reset init let uniq = randomID(16) const name = combatant.actor ? combatant.actor.name : combatant.name; if (combatant.players && combatant.players[0] ) { // A player controls this combatant -> message ! ChatMessage.create({ content: `New round ! Click on the button below to declare the actions of ${name} for round ${this.round} !
Declare actions`, whisper: [combatant.players[0].id] }); } else { ChatMessage.create({ content: `New round ! Click on the button below to declare the actions of ${name} for round ${this.round} !
Declare actions`, whisper: ChatMessage.getWhisperRecipients("GM"), }); } } } } /* -------------------------------------------- */ async nextRound() { this.actionsRequested = false; super.nextRound(); } /* -------------------------------------------- */ gotoNextTurn() { this.phaseNumber -= 1; if (this.phaseNumber <= 0) { this.applyConsequences(); this.nextRound(); // Auto-switch to next round } else { this.nextTurn(); } } /* -------------------------------------------- */ async nextTurn() { console.log("Going to phase !", this.phaseNumber); // Get all actions for this phase let phaseIndex = this.phaseNumber - 1; let actionList = []; let actionMsg = `

Actions for phase ${this.phaseNumber}

`; for (let combatantId in this.phaseSetup) { let actionData = this.phaseSetup[combatantId]; if (actionData.phaseArray[phaseIndex].name != 'No Action') { let combatant = this.combatants.find(comb => comb._id == actionData.combatantId); const name = combatant.actor ? combatant.actor.name : combatant.name; actionList.push({ combatant: combatant, action: actionData.phaseArray[phaseIndex], isDone: false }); actionMsg += `
${name} is going to : ${actionData.phaseArray[phaseIndex].name}`; } } if (actionList.length == 0) { actionMsg += "
No actions for the phase !"; this.gotoNextTurn(); } // Display a nice message ChatMessage.create({ content: actionMsg }); // Now push specific messages for (let action of actionList) { let uniq = randomID(16); action.uniqId = uniq; // Easy tracking with chat messages const name = action.combatant.actor ? action.combatant.actor.name : action.combatant.name; if (action.combatant.players[0]) { // A player controls this combatant -> message ! ChatMessage.create({ content: `Phase ${this.phaseNumber} ! ${name} must perform a ${action.action.name} action. When done, click on the button below to close the action. Action is done !`, whisper: [action.combatant.players[0].id] }); } else { ChatMessage.create({ content: `Phase ${this.phaseNumber} ! ${name} must perform a ${action.action.name} action.
When done, click on the button below to close the action. Action is done !`, whisper: ChatMessage.getWhisperRecipients("GM") }); } } // Save for easy access this.currentActions = actionList; } /* -------------------------------------------- */ applyConsequences() { if (game.user.isGM) { for (let combatant of this.combatants) { if (!combatant.actor) continue; // Can't check tokens without assigned actors, Maybe print chat message about bleeding happening so that the GM can manually track this? let bleeding = combatant.actor.items.find(item => item.type == 'consequence' && item.name == 'Bleeding'); combatant.actor.applyConsequenceWound(bleeding.system.severity, "bleeding"); } } } /* -------------------------------------------- */ closeAction(uniqId) { // Delete message ! const toDelete = game.messages.filter(it => it.content.includes(uniqId)); toDelete.forEach(it => it.delete()) let action = this.currentActions.find(_action => _action.uniqId == uniqId); if (action) { action.isDone = true; let filtered = this.currentActions.filter(_action => action.isDone); if (filtered.length == this.currentActions.length) { // All actions closed ! console.log("Going next turn !!!"); this.gotoNextTurn(); } } } /* -------------------------------------------- */ getPhaseRank(actionConf) { for (let i = 2; i >= 0; i--) { let action = actionConf.phaseArray[i]; if (action.name != "No Action") { return i + 1; } } return 0; } /* -------------------------------------------- */ getAPFromActor(actorId) { for (let combatant of this.combatants) { //console.log(combatant); if (combatant.actor.id == actorId) { let phase = this.phaseSetup[combatant.id]; return phase.remainingAP; } } return 0; } /* -------------------------------------------- */ decreaseAPFromActor(actorId) { for (let combatant of this.combatants) { //console.log(combatant); if (combatant.actor.id == actorId) { let phase = this.phaseSetup[combatant.id]; phase.remainingAP -= 1; if (phase.remainingAP < 0) phase.remainingAP = 0; } } } /* -------------------------------------------- */ async setupActorActions(actionConf) { console.log("Setting combat for phase : ", actionConf, actionConf.uniqId); // Delete message ! const toDelete = game.messages.filter(it => it.content.includes(actionConf.uniqId)); toDelete.forEach(it => it.delete()); if (!this.phaseSetup) this.phaseSetup = {}; // Opportunistic init // Keep track this.phaseSetup[actionConf.combatantId] = actionConf; console.log(this.combatants); //let combatant = this.combatants.find( comb => comb._id == actionConf.combatantId); await this.setInitiative(actionConf.combatantId, this.getPhaseRank(actionConf)); let actionsDone = true for (let combatant of this.combatants) { if (combatant.initiative == -1) actionsDone = false; } if (actionsDone) { this.actionsRequested = false; ChatMessage.create({ content: `Action declaration has been completed ! Now proceeding with actions.`, whisper: ChatMessage.getWhisperRecipients("GM") }) this.phaseNumber = 3; this.nextTurn(); } } }