mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-11 19:25:21 +01:00
* Added prettier with automatic useage on pre-commit to avoid style breakage * Ran Prettier on the project
199 lines
8.1 KiB
JavaScript
199 lines
8.1 KiB
JavaScript
import { GMUpdateEvent, socketEvent } from '../helpers/socket.mjs';
|
|
|
|
export default class DhpCombatTracker extends foundry.applications.sidebar.tabs.CombatTracker {
|
|
constructor(data, context) {
|
|
super(data, context);
|
|
|
|
Hooks.on(socketEvent.DhpFearUpdate, this.onFearUpdate);
|
|
}
|
|
|
|
get template() {
|
|
return 'systems/daggerheart/templates/ui/combatTracker.hbs';
|
|
}
|
|
|
|
activateListeners(html) {
|
|
super.activateListeners(html);
|
|
html.on('click', '.token-action-tokens .use-action-token', this.useActionToken.bind(this));
|
|
html.on('click', '.encounter-gm-resources .trade-actions', this.tradeActions.bind(this));
|
|
html.on('click', '.encounter-gm-resources .trade-fear', this.tradeFear.bind(this));
|
|
html.on('click', '.encounter-gm-resources .icon-button.up', this.increaseResource.bind(this));
|
|
html.on('click', '.encounter-gm-resources .icon-button.down', this.decreaseResource.bind(this));
|
|
}
|
|
|
|
async useActionToken(event) {
|
|
event.stopPropagation();
|
|
const combatant = event.currentTarget.dataset.combatant;
|
|
await game.combat.useActionToken(combatant);
|
|
}
|
|
|
|
async tradeActions(event) {
|
|
if (event.currentTarget.classList.contains('disabled')) return;
|
|
|
|
const currentFear = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear);
|
|
const value = currentFear + 1;
|
|
|
|
if (value <= 6) {
|
|
Hooks.callAll(socketEvent.GMUpdate, GMUpdateEvent.UpdateFear, null, value);
|
|
await game.socket.emit(`system.${SYSTEM.id}`, {
|
|
action: socketEvent.GMUpdate,
|
|
data: { action: GMUpdateEvent.UpdateFear, update: value }
|
|
});
|
|
await game.combat.update({ 'system.actions': game.combat.system.actions - 2 });
|
|
}
|
|
}
|
|
|
|
async tradeFear() {
|
|
if (event.currentTarget.classList.contains('disabled')) return;
|
|
|
|
const currentFear = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear);
|
|
const value = currentFear - 1;
|
|
if (value >= 0) {
|
|
Hooks.callAll(socketEvent.GMUpdate, GMUpdateEvent.UpdateFear, null, value);
|
|
await game.socket.emit(`system.${SYSTEM.id}`, {
|
|
action: socketEvent.GMUpdate,
|
|
data: { action: GMUpdateEvent.UpdateFear, update: value }
|
|
});
|
|
await game.combat.update({ 'system.actions': game.combat.system.actions + 2 });
|
|
}
|
|
}
|
|
|
|
async increaseResource(event) {
|
|
if (event.currentTarget.dataset.type === 'action') {
|
|
await game.combat.update({ 'system.actions': game.combat.system.actions + 1 });
|
|
}
|
|
|
|
const currentFear = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear);
|
|
const value = currentFear + 1;
|
|
if (event.currentTarget.dataset.type === 'fear' && value <= 6) {
|
|
Hooks.callAll(socketEvent.GMUpdate, GMUpdateEvent.UpdateFear, null, value);
|
|
await game.socket.emit(`system.${SYSTEM.id}`, {
|
|
action: socketEvent.GMUpdate,
|
|
data: { action: GMUpdateEvent.UpdateFear, update: value }
|
|
});
|
|
}
|
|
|
|
this.render();
|
|
}
|
|
|
|
async decreaseResource(event) {
|
|
if (event.currentTarget.dataset.type === 'action' && game.combat.system.actions - 1 >= 0) {
|
|
await game.combat.update({ 'system.actions': game.combat.system.actions - 1 });
|
|
}
|
|
|
|
const currentFear = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear);
|
|
const value = currentFear - 1;
|
|
if (event.currentTarget.dataset.type === 'fear' && value >= 0) {
|
|
Hooks.callAll(socketEvent.GMUpdate, GMUpdateEvent.UpdateFear, null, value);
|
|
await game.socket.emit(`system.${SYSTEM.id}`, {
|
|
action: socketEvent.GMUpdate,
|
|
data: { action: GMUpdateEvent.UpdateFear, update: value }
|
|
});
|
|
}
|
|
|
|
this.render();
|
|
}
|
|
|
|
async getData(options = {}) {
|
|
let context = await super.getData(options);
|
|
|
|
// Get the combat encounters possible for the viewed Scene
|
|
const combat = this.viewed;
|
|
const hasCombat = combat !== null;
|
|
const combats = this.combats;
|
|
const currentIdx = combats.findIndex(c => c === combat);
|
|
const previousId = currentIdx > 0 ? combats[currentIdx - 1].id : null;
|
|
const nextId = currentIdx < combats.length - 1 ? combats[currentIdx + 1].id : null;
|
|
const settings = game.settings.get('core', Combat.CONFIG_SETTING);
|
|
|
|
// Prepare rendering data
|
|
context = foundry.utils.mergeObject(context, {
|
|
combats: combats,
|
|
currentIndex: currentIdx + 1,
|
|
combatCount: combats.length,
|
|
hasCombat: hasCombat,
|
|
combat,
|
|
turns: [],
|
|
previousId,
|
|
nextId,
|
|
started: this.started,
|
|
control: false,
|
|
settings,
|
|
linked: combat?.scene !== null,
|
|
labels: {}
|
|
});
|
|
context.labels.scope = game.i18n.localize(`COMBAT.${context.linked ? 'Linked' : 'Unlinked'}`);
|
|
if (!hasCombat) return context;
|
|
|
|
// Format information about each combatant in the encounter
|
|
let hasDecimals = false;
|
|
const turns = [];
|
|
for (let [i, combatant] of combat.turns.entries()) {
|
|
if (!combatant.visible) continue;
|
|
|
|
// Prepare turn data
|
|
const resource =
|
|
combatant.permission >= CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER ? combatant.resource : null;
|
|
const turn = {
|
|
id: combatant.id,
|
|
name: combatant.name,
|
|
img: await this._getCombatantThumbnail(combatant),
|
|
active: combatant.id === combat.system.activeCombatant,
|
|
owner: combatant.isOwner,
|
|
defeated: combatant.isDefeated,
|
|
hidden: combatant.hidden,
|
|
initiative: combatant.initiative,
|
|
hasRolled: combatant.initiative !== null,
|
|
hasResource: resource !== null,
|
|
resource: resource,
|
|
canPing: combatant.sceneId === canvas.scene?.id && game.user.hasPermission('PING_CANVAS'),
|
|
playerCharacter: game.user?.character?.id === combatant.actor.id,
|
|
ownedByPlayer: combatant.hasPlayerOwner
|
|
};
|
|
if (turn.initiative !== null && !Number.isInteger(turn.initiative)) hasDecimals = true;
|
|
turn.css = [turn.active ? 'active' : '', turn.hidden ? 'hidden' : '', turn.defeated ? 'defeated' : '']
|
|
.join(' ')
|
|
.trim();
|
|
|
|
// Actor and Token status effects
|
|
turn.effects = new Set();
|
|
if (combatant.token) {
|
|
combatant.token.effects.forEach(e => turn.effects.add(e));
|
|
if (combatant.token.overlayEffect) turn.effects.add(combatant.token.overlayEffect);
|
|
}
|
|
if (combatant.actor) {
|
|
for (const effect of combatant.actor.temporaryEffects) {
|
|
if (effect.statuses.has(CONFIG.specialStatusEffects.DEFEATED)) turn.defeated = true;
|
|
else if (effect.icon) turn.effects.add(effect.icon);
|
|
}
|
|
}
|
|
turns.push(turn);
|
|
}
|
|
|
|
// Format initiative numeric precision
|
|
const precision = CONFIG.Combat.initiative.decimals;
|
|
turns.forEach(t => {
|
|
if (t.initiative !== null) t.initiative = t.initiative.toFixed(hasDecimals ? precision : 0);
|
|
});
|
|
|
|
const fear = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Resources.Fear);
|
|
|
|
// Merge update data for rendering
|
|
return foundry.utils.mergeObject(context, {
|
|
round: combat.round,
|
|
turn: combat.turn,
|
|
turns: turns,
|
|
control: combat.combatant?.players?.includes(game.user),
|
|
fear: fear
|
|
});
|
|
}
|
|
|
|
onFearUpdate = async () => {
|
|
this.render(true);
|
|
};
|
|
|
|
async close(options) {
|
|
Hooks.off(socketEvent.DhpFearUpdate, this.onFearUpdate);
|
|
|
|
return super.close(options);
|
|
}
|
|
}
|