215 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			215 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { Hero6Utility } from "./hero6-utility.js";
 | |
| 
 | |
| /* -------------------------------------------- */
 | |
| export class Hero6CombatTracker extends CombatTracker {
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   static get defaultOptions() {
 | |
|     let path = "systems/fvtt-hero-system-6/templates/apps/combat-tracker.hbs";
 | |
|     return foundry.utils.mergeObject(super.defaultOptions, {
 | |
|       template: path,
 | |
|     });
 | |
|   }
 | |
| }
 | |
| 
 | |
| /* -------------------------------------------- */
 | |
| export class Hero6Combat extends Combat {
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   static ready() {
 | |
|     Hooks.on("getCombatTrackerEntryContext", (html, options) => { Hero6Combat.pushMenuOptions(html, options); });
 | |
|     game.combat.settings.resource = "characteristics.spd.value";
 | |
|   }
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   static pushMenuOptions(html, options) {
 | |
|     let newOpt
 | |
|     for (let i = 0; i < options.length; i++) {
 | |
|       let option = options[i];
 | |
|       if (option.name == 'COMBAT.CombatantReroll') { // Replace !
 | |
|         option.name = "Hold/Unhold action";
 | |
|         option.condition = true;
 | |
|         option.icon = '<i class="far fa-question-circle"></i>';
 | |
|         option.callback = target => {
 | |
|           Hero6Combat.holdAction(target.data('combatant-id'));
 | |
|         }
 | |
|         //newOpt = duplicate(option)
 | |
|       }
 | |
|     }
 | |
|     //options.push(newOpt)
 | |
|   }
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   static async holdAction(combatantId) {
 | |
|     const combatant = game.combat.combatants.get(combatantId)
 | |
|     if (combatant.actor.holdAction()) {
 | |
|       let id = combatant._id || combatant.id
 | |
|       let name = combatant.actor.name + " (H)"
 | |
|       await game.combat.updateEmbeddedDocuments("Combatant", [{ _id: id, name: name, holdAction: true }]);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   static async abortAction(actorId, abortState) {
 | |
|     const combatant = game.combat.combatants.find(c => c.actor.id == actorId)
 | |
|     if (abortState) {
 | |
|       let id = combatant._id || combatant.id
 | |
|       let name = combatant.actor.name + " (A)"
 | |
|       await game.combat.updateEmbeddedDocuments("Combatant", [{ _id: id, name: name }]);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   constructor(data, context) {
 | |
|     super(data, context);
 | |
| 
 | |
|     this.turnNumber = 0;
 | |
|     this.segmentNumber = 12;
 | |
|   }
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   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();
 | |
|   }
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   computeInitiative(c, updList) {
 | |
|     let id = c._id || c.id
 | |
|     let hasSegment = c.actor.hasPhase(this.segmentNumber)
 | |
|     let isOnHold = c.actor.getHoldAction()
 | |
|     if (hasSegment || isOnHold) {
 | |
|       let baseInit = c.actor ? c.actor.getBaseInit() : 0;
 | |
|       let name = c.actor.name
 | |
|       if (isOnHold) {
 | |
|         if (hasSegment) { // On hold + current segment -> auto-disable on hold
 | |
|           c.actor.disableHoldAction()
 | |
|         } else {
 | |
|           name = c.actor.name + " (H)"
 | |
|         }
 | |
|       }
 | |
|       if (c.actor.getAbortAction()) {
 | |
|         name = c.actor.name + " (A)"
 | |
|         c.actor.disableAbortAction()
 | |
|       }
 | |
|       updList.push({ _id: id, name: name, initiative: baseInit, holdAction: c.holdAction })
 | |
|     } else {
 | |
|       updList.push({ _id: id, name: name, initiative: 0, holdAction: c.holdAction })
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   async rollInitiative(ids, formula = undefined, messageOptions = {}) {
 | |
|     ids = typeof ids === "string" ? [ids] : ids;
 | |
| 
 | |
|     console.log("Roll INIT")
 | |
|     let updList = []
 | |
|     for (let cId = 0; cId < ids.length; cId++) {
 | |
|       const c = this.combatants.get(ids[cId])
 | |
|       this.computeInitiative(c, updList)
 | |
|     }
 | |
| 
 | |
|     if (updList.length > 0) {
 | |
|       await this.updateEmbeddedDocuments("Combatant", updList);
 | |
|     }
 | |
| 
 | |
|     return this;
 | |
|   }
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   async rebuildInitiative() {
 | |
|     let updList = []
 | |
|     for (let c of this.combatants) {
 | |
|       this.computeInitiative(c, updList)
 | |
|     }
 | |
|     if (updList.length > 0) {
 | |
|       await this.updateEmbeddedDocuments("Combatant", updList);
 | |
|       console.log("Rebuild INIT", updList)
 | |
|       for (let c of updList) {
 | |
|         if (c.initiative != 0) {
 | |
|           return true
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     return false
 | |
|   }
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   async nextRound() {
 | |
|     let hasCombatants = false
 | |
|     let nextRound = this.round
 | |
|     let advanceTime = 0
 | |
|     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")
 | |
| 
 | |
|     console.log("Next round called....", nextRound, turnData)
 | |
|     while (!hasCombatants) {
 | |
|       turn = turn; // Preserve the fact that it's no-one's turn currently.
 | |
|       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;
 | |
|       console.log("Next round called....2", nextRound, turnData)
 | |
|       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;
 | |
|       console.log("Next round called....3", nextRound, turnData)
 | |
| 
 | |
|       // Re-compute init of actors
 | |
|       hasCombatants = await this.rebuildInitiative()
 | |
|       console.log("Going round....", nextRound, hasCombatants)
 | |
|     }
 | |
| 
 | |
|     // Update the document, passing data through a hook first
 | |
|     const updateData = { round: nextRound, turn: turn, segmentNumber: turnData.segmentNumber, turnNumber: turnData.turnNumber };
 | |
|     const updateOptions = { advanceTime, direction: 1 };
 | |
|     Hooks.callAll("combatRound", this, updateData, updateOptions);
 | |
|     return this.update(updateData, updateOptions);
 | |
|   }
 | |
| 
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   async _onCreateEmbeddedDocuments(type, documents, result, options, userId) {
 | |
|     super._onCreateEmbeddedDocuments(type, documents, result, options, userId)
 | |
|   }
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   _onUpdate(changed, options, userId) {
 | |
|   }
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   static async checkTurnPosition() {
 | |
|     while (game.combat.turn > 0) {
 | |
|       await game.combat.previousTurn()
 | |
|     }
 | |
|   }
 | |
| 
 | |
| }
 |