From 95a595773d6913c8583162e9e7a58e6f8fb45cfe Mon Sep 17 00:00:00 2001
From: Johannes Loher <johannes.loher@fg4f.de>
Date: Mon, 10 Jul 2023 02:12:42 +0200
Subject: [PATCH] fix: correctly calculate tick value when stopping to wait

---
 jsconfig.json                   |  3 ++-
 src/data/documents/combatant.js | 17 ++++++++++-------
 src/systems/ds4.js              |  4 ++--
 3 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/jsconfig.json b/jsconfig.json
index 8b929d6..566129b 100644
--- a/jsconfig.json
+++ b/jsconfig.json
@@ -1,7 +1,8 @@
 {
   "compilerOptions": {
     "module": "es2022",
-    "target": "ES2022"
+    "target": "ES2022",
+    "strict": true
   },
   "exclude": ["node_modules", "dist"],
   "include": ["src", "client", "common"]
diff --git a/src/data/documents/combatant.js b/src/data/documents/combatant.js
index f548cfe..e6e435d 100644
--- a/src/data/documents/combatant.js
+++ b/src/data/documents/combatant.js
@@ -112,14 +112,16 @@ const CombatantMixin = (BaseCombatant) => {
      * @param {object} data The data of the creation / update
      */
     async #updateTiebreakerData(data) {
-      if ('initiative' in data) {
+      const waiting = data.flags?.[packageId]?.waiting;
+      if ('initiative' in data || waiting !== undefined) {
+        const newInitiative = data.initiative ?? this.initiative;
         const combatantsWithSameTickValue =
           this.parent?.combatants.filter((combatant) => {
             const otherInitiative =
               combatant._newInitiative !== undefined ? combatant._newInitiative : combatant.initiative;
-            return otherInitiative === data.initiative;
+            return otherInitiative === newInitiative && combatant !== this;
           }) ?? [];
-        const tiebreaker = await this.#getTiebreaker(combatantsWithSameTickValue);
+        const tiebreaker = await this.#getTiebreaker(combatantsWithSameTickValue, waiting);
         foundry.utils.setProperty(data, `flags.${packageId}.tiebreaker`, tiebreaker);
         this._newInitiative = data.initiative;
         this._newTiebreaker = tiebreaker;
@@ -129,11 +131,12 @@ const CombatantMixin = (BaseCombatant) => {
     /**
      * Get a tiebreaker between this combatant and the given other combatants.
      * @param {TickwerkCombatant[]} combatants  The other combatants among which to find a tiebreaker
+     * @param {boolean | undefined} waiting     The change of the waiting state of the combatanmt
      * @returns {Promise<number>} A promise that resolves to the tiebreaker
      */
-    async #getTiebreaker(combatants) {
+    async #getTiebreaker(combatants, waiting) {
       const getTiebreaker = CONFIG.tickwerk?.getTiebreaker ?? defaultGetTiebreaker;
-      return getTiebreaker(this, combatants);
+      return getTiebreaker(this, combatants, waiting);
     }
 
     /** @override */
@@ -179,14 +182,14 @@ const CombatantMixin = (BaseCombatant) => {
 
 /**
  * A function to get a tiebreaker for a combatant
- * @typedef {(combatant: TickwerkCombatant, combatants: TickwerkCombatant[]) => Promise<number>} GetTiebreaker
+ * @typedef {(combatant: TickwerkCombatant, combatants: TickwerkCombatant[], waiting: boolean | undefined) => Promise<number>} GetTiebreaker
  */
 
 /**
  * Default implementation to get a tiebreaker for a combatant.
  * @type {GetTiebreaker}
  */
-const defaultGetTiebreaker = async (combatant, combatants) => {
+export const defaultGetTiebreaker = async (combatant, combatants) => {
   if (combatants.length === 0) return 0;
   const tiebreakers = combatants.map((combatant) => {
     return (
diff --git a/src/systems/ds4.js b/src/systems/ds4.js
index b9c01c7..ff06933 100644
--- a/src/systems/ds4.js
+++ b/src/systems/ds4.js
@@ -14,7 +14,7 @@ export const registerDS4SpecificFunctionality = () => {
 };
 
 /** @type {import("../data/documents/combatant").GetTiebreaker} */
-const getTiebreaker = async (combatant, combatants) => {
+const getTiebreaker = async (combatant, combatants, waiting) => {
   if (combatants.length === 0) return 0;
 
   /** @type {number[]} */
@@ -26,7 +26,7 @@ const getTiebreaker = async (combatant, combatants) => {
 
   for (const other of combatants) {
     const tiebreaker = other._newTiebreaker ?? other.getFlag(packageId, 'tiebreaker') ?? 0;
-    if (getInitiative(other) > getInitiative(combatant)) {
+    if (getInitiative(other) > getInitiative(combatant) || waiting === false) {
       lowerBounds.push(tiebreaker);
     } else if (getInitiative(other) < getInitiative(combatant)) {
       upperBounds.push(tiebreaker);