Inital
This commit is contained in:
87
scripts/combat/Combat2d20.js
Normal file
87
scripts/combat/Combat2d20.js
Normal file
@ -0,0 +1,87 @@
|
||||
const KEY = "dune";
|
||||
|
||||
export default class Combat2d20 extends Combat {
|
||||
|
||||
get combatantsTurnDone() {
|
||||
return this.getFlag(KEY, "combatantsTurnDone") ?? [];
|
||||
}
|
||||
|
||||
|
||||
get combatantsTurnsDoneThisRound() {
|
||||
const combatantsTurnDone = this.combatantsTurnDone;
|
||||
return combatantsTurnDone[this.round] ?? {};
|
||||
}
|
||||
|
||||
async rollInitiative() {
|
||||
return this;
|
||||
}
|
||||
|
||||
async setTurn(newTurn) {
|
||||
this.turn = newTurn;
|
||||
|
||||
// Update the document, passing data through a hook first
|
||||
const updateData = {round: this.round, turn: newTurn};
|
||||
const updateOptions = {advanceTime: CONFIG.time.turnTime, direction: 1};
|
||||
Hooks.callAll("combatTurn", this, updateData, updateOptions);
|
||||
return this.update(updateData, updateOptions);
|
||||
}
|
||||
|
||||
|
||||
setupTurns() {
|
||||
// Determine the turn order and the current turn
|
||||
const turns = this.combatants.contents;
|
||||
|
||||
// Sort alphabetically by name first
|
||||
turns.sort((a, b) => {
|
||||
if (a.name < b.name) {
|
||||
return -1;
|
||||
}
|
||||
if (a.name > b.name) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
// Then make sure the player characters are first
|
||||
turns.sort(
|
||||
(a, b) => Number(b.hasPlayerOwner) - Number(a.hasPlayerOwner)
|
||||
);
|
||||
|
||||
if (this.turn !== null) this.turn =
|
||||
Math.clamp(this.turn, 0, turns.length - 1);
|
||||
|
||||
// Update state tracking
|
||||
let c = turns[this.turn];
|
||||
this.current = {
|
||||
round: this.round,
|
||||
turn: this.turn,
|
||||
combatantId: c ? c.id : null,
|
||||
tokenId: c ? c.tokenId : null,
|
||||
};
|
||||
|
||||
// One-time initialization of the previous state
|
||||
if (!this.previous) this.previous = this.current;
|
||||
|
||||
// Return the array of prepared turns
|
||||
return this.turns = turns;
|
||||
}
|
||||
|
||||
|
||||
async toggleTurnDone(combatantId) {
|
||||
if (!game.user.isGM) return;
|
||||
if (!this.started) return;
|
||||
|
||||
const combatantsTurnsDoneThisRound = this.combatantsTurnsDoneThisRound;
|
||||
|
||||
const turnDone = !(combatantsTurnsDoneThisRound[combatantId] ?? false);
|
||||
combatantsTurnsDoneThisRound[combatantId] = turnDone;
|
||||
|
||||
const combatantsTurnDone = this.combatantsTurnDone;
|
||||
combatantsTurnDone[this.round] = combatantsTurnsDoneThisRound;
|
||||
|
||||
this.setFlag(KEY, "combatantsTurnDone", combatantsTurnDone);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
99
scripts/combat/CombatTracker2d20V2.js
Normal file
99
scripts/combat/CombatTracker2d20V2.js
Normal file
@ -0,0 +1,99 @@
|
||||
export default class CombatTracker2d20V2
|
||||
extends foundry.applications.sidebar.tabs.CombatTracker {
|
||||
|
||||
/** @inheritDoc */
|
||||
static DEFAULT_OPTIONS = {
|
||||
actions: {
|
||||
toggleCombatantTurnDone: CombatTracker2d20V2._onDuneCombatantControl,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
static PARTS = {
|
||||
header: {
|
||||
// We're still using the default Foundry template for this part
|
||||
template: "templates/sidebar/tabs/combat/header.hbs",
|
||||
},
|
||||
tracker: {
|
||||
template: "modules/duneinichecker/templates/tracker.hbs",
|
||||
},
|
||||
footer: {
|
||||
// We're still using the default Foundry template for this part
|
||||
template: "templates/sidebar/tabs/combat/footer.hbs",
|
||||
},
|
||||
};
|
||||
|
||||
_onCombatantMouseDown(event, target) {
|
||||
super._onCombatantMouseDown(event, target);
|
||||
|
||||
const isInputElement = (event.target instanceof HTMLInputElement);
|
||||
const isButtonElement = (event.target instanceof HTMLButtonElement);
|
||||
|
||||
if (isInputElement || isButtonElement) return;
|
||||
|
||||
if (game.user.isGM && this.viewed.started) {
|
||||
const { combatantId } = target?.dataset ?? {};
|
||||
|
||||
const combat = this.viewed;
|
||||
|
||||
const currentTurn = combat.turn ?? -1;
|
||||
|
||||
let newTurn = currentTurn;
|
||||
|
||||
for (let [i, turn] of combat.turns.entries() ) {
|
||||
if (turn.isDefeated) continue;
|
||||
if (turn.id === combatantId) {
|
||||
newTurn = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newTurn !== currentTurn) {
|
||||
combat.setTurn(newTurn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static async _onDuneCombatantControl(event, target) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
if (!game.user.isGM) return;
|
||||
|
||||
if (!this.viewed.started) {
|
||||
ui.notifications.warn(
|
||||
game.i18n.localize("COMBAT.NotStarted")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const { combatantId } = target.closest("[data-combatant-id]")?.dataset ?? {};
|
||||
const combatant = this.viewed?.combatants.get(combatantId);
|
||||
if ( !combatant ) return;
|
||||
|
||||
if (combatant.isOwner) {
|
||||
this.viewed.toggleTurnDone(combatant.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepare render context for the tracker part.
|
||||
* @param {ApplicationRenderContext} context
|
||||
* @param {HandlebarsRenderOptions} options
|
||||
* @returns {Promise<void>}
|
||||
* @protected
|
||||
*/
|
||||
async _prepareTrackerContext(context, options) {
|
||||
await super._prepareTrackerContext(context, options);
|
||||
|
||||
const combat = this.viewed;
|
||||
if ( !combat ) return;
|
||||
|
||||
const combatantsTurnDone = combat.combatantsTurnsDoneThisRound;
|
||||
for (const turn of context.turns) {
|
||||
turn.turnDone = combatantsTurnDone[turn.id] ?? false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user