fvtt-hero-system-6/modules/hero6-combat.js

238 lines
7.7 KiB
JavaScript
Raw Permalink Normal View History

2022-12-15 21:44:23 +01:00
import { Hero6Utility } from "./hero6-utility.js";
2023-04-06 16:57:19 +02:00
/* -------------------------------------------- */
export class Hero6CombatTracker extends CombatTracker {
/* -------------------------------------------- */
static get defaultOptions() {
2023-06-30 17:21:11 +02:00
let path = "systems/fvtt-hero-system-6/templates/apps/combat-tracker.hbs";
2023-04-06 16:57:19 +02:00
return foundry.utils.mergeObject(super.defaultOptions, {
template: path,
});
}
}
2022-12-15 21:44:23 +01:00
/* -------------------------------------------- */
export class Hero6Combat extends Combat {
2023-04-06 16:57:19 +02:00
/* -------------------------------------------- */
2023-06-30 21:11:29 +02:00
static ready() {
2023-04-06 16:57:19 +02:00
Hooks.on("getCombatTrackerEntryContext", (html, options) => { Hero6Combat.pushMenuOptions(html, options); });
2023-06-30 21:11:29 +02:00
game.combat.settings.resource = "characteristics.spd.value";
2023-04-06 16:57:19 +02:00
}
2023-06-30 21:11:29 +02:00
2023-04-06 16:57:19 +02:00
/* -------------------------------------------- */
static pushMenuOptions(html, options) {
let newOpt
for (let i = 0; i < options.length; i++) {
let option = options[i];
if (option.name == 'COMBAT.CombatantReroll') { // Replace !
2023-06-30 21:11:29 +02:00
option.name = "Hold/Unhold action";
2023-04-06 16:57:19 +02:00
option.condition = true;
option.icon = '<i class="far fa-question-circle"></i>';
option.callback = target => {
2023-07-24 13:35:35 +02:00
let id = target.data('combatant-id')
let c = game.combat.combatants.get(id)
c.actor.holdAction()
2023-04-06 16:57:19 +02:00
}
2023-06-30 21:11:29 +02:00
//newOpt = duplicate(option)
2023-04-06 16:57:19 +02:00
}
}
2023-06-30 21:11:29 +02:00
//options.push(newOpt)
2023-04-06 16:57:19 +02:00
}
/* -------------------------------------------- */
2023-07-16 14:33:26 +02:00
holdAction(combatantId) {
this.rebuildInitiative()
console.log("Rebuilding.....")
2023-07-07 15:35:24 +02:00
}
/* -------------------------------------------- */
2023-07-16 14:33:26 +02:00
abortAction(actorId, abortState) {
this.rebuildInitiative()
2023-04-06 16:57:19 +02:00
}
/* -------------------------------------------- */
constructor(data, context) {
super(data, context);
2023-06-30 17:21:11 +02:00
this.turnNumber = 0;
2023-04-06 16:57:19 +02:00
this.segmentNumber = 12;
}
/* -------------------------------------------- */
2023-06-30 21:11:29 +02:00
async startCombat() {
game.combat.settings.resource = "characteristics.spd.value";
let updList = []
for (let c of this.combatants) {
this.computeInitiative(c, updList)
await c.actor.cleanCombat()
}
if (updList.length > 0) {
await this.updateEmbeddedDocuments("Combatant", updList);
}
super.startCombat();
}
2023-07-16 14:33:26 +02:00
/* -------------------------------------------- */
forceHold(actor, isHold) {
let updList = []
let c = this.combatants.find(c => c.actor._id == actor.id)
let name = actor.name + ((isHold) ? " (H)" : "")
updList.push({ _id: c.id || c._id, name: name, initiative: actor.getBaseInit(this.segmentNumber) })
this.updateEmbeddedDocuments("Combatant", updList)
}
/* -------------------------------------------- */
forceAbort(actor, isAbort) {
let updList = []
let c = this.combatants.find(c => c.actor._id == actor.id)
let name = actor.name + ((isAbort) ? " (A)" : "")
updList.push({ _id: c.id || c._id, name: name, initiative: actor.getBaseInit(this.segmentNumber) })
this.updateEmbeddedDocuments("Combatant", updList)
}
2023-06-30 21:11:29 +02:00
/* -------------------------------------------- */
computeInitiative(c, updList) {
2023-04-06 16:57:19 +02:00
let id = c._id || c.id
2023-07-06 13:10:41 +02:00
let hasSegment = c.actor.hasPhase(this.segmentNumber)
2023-07-06 21:28:52 +02:00
let isOnHold = c.actor.getHoldAction()
2023-07-16 14:33:26 +02:00
let isOnAbort = c.actor.getAbortAction()
let name = c.actor.name
if (hasSegment || isOnHold || isOnAbort) {
let baseInit = c.actor ? c.actor.getBaseInit(this.segmentNumber) : 0;
2023-07-06 13:10:41 +02:00
if (isOnHold) {
if (hasSegment) { // On hold + current segment -> auto-disable on hold
c.actor.disableHoldAction()
} else {
name = c.actor.name + " (H)"
}
2023-06-30 21:11:29 +02:00
}
2023-07-16 14:33:26 +02:00
if (isOnAbort) {
2023-06-30 21:11:29 +02:00
name = c.actor.name + " (A)"
2023-07-24 13:35:35 +02:00
if ( c.actor.incAbortActionCount() ) {
2023-07-16 14:33:26 +02:00
c.actor.disableAbortAction()
}
2023-06-30 21:11:29 +02:00
}
updList.push({ _id: id, name: name, initiative: baseInit, holdAction: c.holdAction })
2023-04-06 16:57:19 +02:00
} else {
2023-06-30 21:11:29 +02:00
updList.push({ _id: id, name: name, initiative: 0, holdAction: c.holdAction })
2023-04-06 16:57:19 +02:00
}
}
2023-06-30 21:11:29 +02:00
2022-12-15 21:44:23 +01:00
/* -------------------------------------------- */
2023-04-06 16:57:19 +02:00
async rollInitiative(ids, formula = undefined, messageOptions = {}) {
2022-12-15 21:44:23 +01:00
ids = typeof ids === "string" ? [ids] : ids;
2023-06-30 21:11:29 +02:00
let updList = []
2022-12-15 21:44:23 +01:00
for (let cId = 0; cId < ids.length; cId++) {
2023-04-06 16:57:19 +02:00
const c = this.combatants.get(ids[cId])
2023-06-30 21:11:29 +02:00
this.computeInitiative(c, updList)
}
if (updList.length > 0) {
await this.updateEmbeddedDocuments("Combatant", updList);
2022-12-15 21:44:23 +01:00
}
return this;
}
2023-06-30 21:11:29 +02:00
/* -------------------------------------------- */
async rebuildInitiative() {
let updList = []
for (let c of this.combatants) {
this.computeInitiative(c, updList)
}
if (updList.length > 0) {
await this.updateEmbeddedDocuments("Combatant", updList);
2023-07-06 13:10:41 +02:00
console.log("Rebuild INIT", updList)
2023-07-07 15:35:24 +02:00
for (let c of updList) {
if (c.initiative != 0) {
2023-07-06 13:10:41 +02:00
return true
}
}
2023-06-30 21:11:29 +02:00
}
2023-07-06 13:10:41 +02:00
return false
2023-06-30 21:11:29 +02:00
}
2023-07-21 14:52:22 +02:00
/* -------------------------------------------- */
nextTurn() {
let nbC = this.combatants.filter(c => c.initiative > 0).length
//console.log("Next turn called....", this.turn, nbC)
if (this.turn < nbC-1) {
super.nextTurn()
} else {
this.nextRound()
}
}
2023-04-06 16:57:19 +02:00
/* -------------------------------------------- */
2023-07-06 13:10:41 +02:00
async nextRound() {
let hasCombatants = false
let nextRound = this.round
let advanceTime = 0
2023-04-06 16:57:19 +02:00
let turn = this.turn === null ? null : 0; // Preserve the fact that it's no-one's turn currently.
let turnData = this.getFlag("world", "hero6-turn-data")
2023-07-07 15:35:24 +02:00
2023-07-21 14:52:22 +02:00
//console.log("Next round called....", nextRound, turnData)
2023-07-06 13:10:41 +02:00
while (!hasCombatants) {
if (this.settings.skipDefeated && (turn !== null)) {
turn = this.turns.findIndex(t => !t.isDefeated);
if (turn === -1) {
ui.notifications.warn("COMBAT.NoneRemaining", { localize: true });
turn = 0;
}
}
advanceTime = Math.max(this.turns.length - this.turn, 0) * CONFIG.time.turnTime;
advanceTime += CONFIG.time.roundTime;
nextRound = nextRound + 1;
2023-07-21 14:52:22 +02:00
//console.log("Next round called....2", nextRound, turnData)
2023-07-06 13:10:41 +02:00
turnData = this.getFlag("world", "hero6-turn-data")
if (!turnData) {
turnData = { turnNumber: 0, segmentNumber: 12 }
this.setFlag("world", "hero6-turn-data", turnData)
}
turnData = duplicate(turnData)
turnData.segmentNumber += 1
if (turnData.segmentNumber > 12) {
turnData.segmentNumber = 1
turnData.turnNumber++
}
await this.setFlag("world", "hero6-turn-data", turnData)
this.turnNumber = turnData.turnNumber;
this.segmentNumber = turnData.segmentNumber;
2023-07-21 14:52:22 +02:00
//console.log("Next round called....3", nextRound, turnData)
2023-07-06 13:10:41 +02:00
// Re-compute init of actors
hasCombatants = await this.rebuildInitiative()
2023-07-21 14:52:22 +02:00
//console.log("Going round....", nextRound, hasCombatants)
2023-04-06 16:57:19 +02:00
}
// Update the document, passing data through a hook first
2023-07-06 13:10:41 +02:00
const updateData = { round: nextRound, turn: turn, segmentNumber: turnData.segmentNumber, turnNumber: turnData.turnNumber };
2023-04-06 16:57:19 +02:00
const updateOptions = { advanceTime, direction: 1 };
Hooks.callAll("combatRound", this, updateData, updateOptions);
return this.update(updateData, updateOptions);
}
/* -------------------------------------------- */
async _onCreateEmbeddedDocuments(type, documents, result, options, userId) {
2023-07-16 14:33:26 +02:00
//console.log("Added...")
await super._onCreateEmbeddedDocuments(type, documents, result, options, userId)
await this.rebuildInitiative()
2023-04-06 16:57:19 +02:00
}
2023-07-16 14:33:26 +02:00
/* --------------------------------------------
2022-12-15 21:44:23 +01:00
_onUpdate(changed, options, userId) {
2023-07-16 14:33:26 +02:00
}*/
2022-12-15 21:44:23 +01:00
/* -------------------------------------------- */
static async checkTurnPosition() {
while (game.combat.turn > 0) {
await game.combat.previousTurn()
}
}
}