// SPDX-FileCopyrightText: 2022 Johannes Loher // // SPDX-License-Identifier: MIT import { packageId } from '../constants'; import type { TickwerkCombatant } from '../data/documents/combatant'; export const registerDS4SpecificFunctionality = () => { if (CONFIG.tickwerk === undefined) CONFIG.tickwerk = {}; foundry.utils.mergeObject(CONFIG.tickwerk, { getTiebreaker, getInitiativeFormula }); }; const getTiebreaker = async (combatant: TickwerkCombatant, combatants: TickwerkCombatant[]): Promise => { const ds4combatant = combatant as DS4TickwerkCombatant; const ds4combatants = combatants as DS4TickwerkCombatant[]; if (combatants.length === 0) return 0; const lowerBounds: number[] = []; const upperBounds: number[] = []; const equals: number[] = []; for (const combatant of ds4combatants) { const tiebreaker = combatant._newTiebreaker ?? combatant.getFlag(packageId, 'tiebreaker') ?? 0; if ( (combatant.actor?.data.data.combatValues.initiative.total ?? -Infinity) > (ds4combatant.actor?.data.data.combatValues.initiative.total ?? -Infinity) ) { lowerBounds.push(tiebreaker); } else if ( (combatant.actor?.data.data.combatValues.initiative.total ?? -Infinity) < (ds4combatant.actor?.data.data.combatValues.initiative.total ?? -Infinity) ) { upperBounds.push(tiebreaker); } else { equals.push(tiebreaker); } } equals.sort(); const positionAmongEquals = Math.floor(twist.random() * (equals.length + 1)); equals.forEach((equal, index) => { if (index < positionAmongEquals) { lowerBounds.push(equal); } else { upperBounds.push(equal); } }); const lowerBound = Math.max(...lowerBounds); const upperBound = Math.min(...upperBounds); if (lowerBound === -Infinity) { if (upperBound === Infinity) { return 0; } else { return upperBound - 1; } } else { if (upperBound === Infinity) { return lowerBound + 1; } else { return (lowerBound + upperBound) / 2; } } }; const getInitiativeFormula = (combatant: TickwerkCombatant) => { const started = combatant.combat?.started ?? false; if (!started) return '-@combatValues.initiative.total'; const tickValue = combatant.combat?.round ?? 0; return `max(${tickValue} + 10 - @combatValues.initiative.total, ${tickValue})`; }; type DS4TickwerkCombatant = TickwerkCombatant & { actor: (Actor & { data: { data: ActorData } }) | null }; interface ActorData { combatValues: { initiative: { total: number; }; }; }