more tooltips and color for "Gm Monitor"

This commit is contained in:
Vlyan
2021-08-14 13:17:17 +02:00
parent c426e457ff
commit f4de1e9fc8
11 changed files with 219 additions and 117 deletions

View File

@@ -96,7 +96,17 @@ export class ActorL5r5e extends Actor {
}
// Now using updateDocuments
return Actor.updateDocuments([data], context);
return Actor.updateDocuments([data], context).then(() => {
// Notify the "Gm Monitor" if this actor is watched
if (game.settings.get("l5r5e", "gm-monitor-actors").find((e) => e === this.id)) {
game.l5r5e.sockets.refreshAppId("l5r5e-gm-monitor");
if (game.user.isGM) {
Object.values(ui.windows)
.find((e) => e.id === "l5r5e-gm-monitor")
?.refresh();
}
}
});
}
/** @override */
@@ -201,4 +211,28 @@ export class ActorL5r5e extends Actor {
}
return tpl;
}
/**
* Return true if a weapon is equipped
* @return {boolean}
*/
haveWeaponEquipped() {
return this.items.some((e) => e.type === "weapon" && !!e.data.data.equipped);
}
/**
* Return true if a weapon is readied
* @return {boolean}
*/
haveWeaponReadied() {
return this.items.some((e) => e.type === "weapon" && !!e.data.data.equipped && !!e.data.data.readied);
}
/**
* Return true if a armor is equipped
* @return {boolean}
*/
haveArmorEquipped() {
return this.items.some((e) => e.type === "armor" && !!e.data.data.equipped);
}
}

View File

@@ -187,17 +187,7 @@ export class BaseSheetL5r5e extends ActorSheet {
formData["data.description"] = game.l5r5e.HelpersL5r5e.convertSymbols(formData["data.description"], true);
}
return super._updateObject(event, formData).then(() => {
// Notify the "Gm Monitor" if this actor is watched
if (game.settings.get("l5r5e", "gm-monitor-actors").find((e) => e === this.actor.id)) {
game.l5r5e.sockets.refreshAppId("l5r5e-gm-monitor");
if (game.user.isGM) {
Object.values(ui.windows)
.find((e) => e.id === "l5r5e-gm-monitor")
?.refresh();
}
}
});
return super._updateObject(event, formData);
}
/**

View File

@@ -20,7 +20,7 @@ export class GmMonitor extends FormApplication {
classes: ["l5r5e", "gm-monitor"],
template: CONFIG.l5r5e.paths.templates + "gm/gm-monitor.html",
title: game.i18n.localize("l5r5e.gm_monitor.title"),
width: 640,
width: 700,
height: 300,
resizable: true,
closeOnSubmit: false,
@@ -120,34 +120,33 @@ export class GmMonitor extends FormApplication {
html.find(`.actor-remove-control`).on("click", this._removeActor.bind(this));
// Tooltips
html.find(".actor-infos-control")
.on("mouseenter", async (event) => {
$(document.body).find("#l5r5e-tooltip-ct").remove();
game.l5r5e.HelpersL5r5e.popupManager(html.find(".actor-infos-control"), async (event) => {
const type = $(event.currentTarget).data("type");
if (!type) {
return;
}
if (type === "text") {
return $(event.currentTarget).data("text");
}
const id = $(event.currentTarget).data("actor-id");
if (!id) {
return;
}
const id = $(event.currentTarget).data("actor-id");
if (!id) {
return;
}
const actor = this.object.actors.find((e) => e.id === id);
if (!actor) {
return;
}
const actor = this.object.actors.find((e) => e.id === id);
if (!actor) {
return;
}
const tpl = await this._getTooltipForActor(actor);
$(document.body).append(
`<div id="l5r5e-tooltip-ct" class="l5r5e-tooltip l5r5e-tooltip-ct">${tpl}</div>`
);
})
.on("mousemove", (event) => {
const popup = $(document.body).find("#l5r5e-tooltip-ct");
if (popup) {
popup.css(game.l5r5e.HelpersL5r5e.popupPosition(event, popup));
}
})
.on("mouseleave", () => {
$(document.body).find("#l5r5e-tooltip-ct").remove();
}); // tooltips
switch (type) {
case "armors":
return await this._getTooltipArmors(actor);
case "weapons":
return await this._getTooltipWeapons(actor);
case "global":
return await this._getTooltipGlobal(actor);
}
});
}
/**
@@ -176,7 +175,8 @@ export class GmMonitor extends FormApplication {
this.object.actors.push(actor[0]);
return this._saveAndRefresh();
await this._saveActorsIds();
return this.refresh();
}
/**
@@ -192,16 +192,6 @@ export class GmMonitor extends FormApplication {
);
}
/**
* Save ids and refresh the windows (local and socket)
* @return {Promise<void>}
*/
async _saveAndRefresh() {
await this._saveActorsIds();
game.l5r5e.sockets.refreshAppId("l5r5e-gm-monitor");
return this.refresh();
}
/**
* Open the Sheet for this actor
* @param {Event} event
@@ -237,7 +227,8 @@ export class GmMonitor extends FormApplication {
this.object.actors = this.object.actors.filter((e) => e.id !== id);
return this._saveAndRefresh();
await this._saveActorsIds();
return this.refresh();
}
/**
@@ -246,7 +237,7 @@ export class GmMonitor extends FormApplication {
* @return {string}
* @private
*/
async _getTooltipForActor(actor) {
async _getTooltipGlobal(actor) {
const data = actor.data.data;
// Peculiarities
@@ -260,33 +251,67 @@ export class GmMonitor extends FormApplication {
.map((e) => e.name)
.join(", ");
// Equipped Armors & Weapons
const arm = actor.items
// *** Template ***
return renderTemplate(`${CONFIG.l5r5e.paths.templates}gm/monitor-tooltips/global.html`, {
actorData: data,
advantages: adv,
disadvantages: dis,
});
}
/**
* Get weapons informations for this actor
* @param {BaseSheetL5r5e} actor
* @return {string}
* @private
*/
async _getTooltipWeapons(actor) {
const display = (e) => {
return (
e.name +
` (<i class="fas fa-arrows-alt-h"> ${e.data.data.range || 0}</i>` +
` / <i class="fas fa-tint"> ${e.data.data.damage}</i>` +
` / <i class="fas fa-skull"> ${e.data.data.deadliness}</i>)`
);
};
// Readied Weapons
const readied = actor.items
.filter((e) => e.type === "weapon" && e.data.data.equipped && !!e.data.data.readied)
.map((e) => display(e));
// Equipped Weapons
const sheathed = actor.items
.filter((e) => e.type === "weapon" && e.data.data.equipped && !e.data.data.readied)
.map((e) => display(e));
// *** Template ***
return renderTemplate(`${CONFIG.l5r5e.paths.templates}gm/monitor-tooltips/weapons.html`, {
readied,
sheathed,
});
}
/**
* Get armors informations for this actor
* @param {BaseSheetL5r5e} actor
* @return {string}
* @private
*/
async _getTooltipArmors(actor) {
// Equipped Armors
const armors = actor.items
.filter((e) => e.type === "armor" && e.data.data.equipped)
.map(
(e) =>
e.name +
`(<i class="fas fa-tint">${e.data.data.armor.physical}</i> / <i class="fas fa-bolt">${e.data.data.armor.supernatural}</i>)`
)
.join(", ");
const wea = actor.items
.filter((e) => e.type === "weapon" && e.data.data.equipped)
.map(
(e) =>
e.name +
`(<i class="fas fa-arrows-alt-h"> ${e.data.data.range || 0}</i> / <i class="fas fa-tint"> ${
e.data.data.damage
}</i> / <i class="fas fa-skull"> ${e.data.data.deadliness}</i>)`
)
.join(", ");
` (<i class="fas fa-tint">${e.data.data.armor.physical}</i>` +
` / <i class="fas fa-bolt">${e.data.data.armor.supernatural}</i>)`
);
// *** Template ***
return renderTemplate(`${CONFIG.l5r5e.paths.templates}gm/gm-monitor-tooltip.html`, {
actorData: data,
advantages: adv,
disadvantages: dis,
armors: arm,
weapons: wea,
return renderTemplate(`${CONFIG.l5r5e.paths.templates}gm/monitor-tooltips/armors.html`, {
armors,
});
}
}

View File

@@ -408,16 +408,42 @@ export class HelpersL5r5e {
});
// Item detail tooltips
html.find(".l5r5e-tooltip")
this.popupManager(html.find(".l5r5e-tooltip"), async (event) => {
const item = await HelpersL5r5e.getEmbedItemByEvent(event, actor);
if (!item) {
return;
}
return await item.renderTextTemplate();
});
}
/**
* Do the Popup for the selected element
* @param {Selector} selector HTML Selector
* @param {function} callback Callback function(event), must return the html to display
*/
static popupManager(selector, callback) {
const popupPosition = (event, popup) => {
let left = +event.clientX + 60,
top = +event.clientY;
let maxY = window.innerHeight - popup.outerHeight();
if (top > maxY) {
top = maxY - 10;
}
let maxX = window.innerWidth - popup.outerWidth();
if (left > maxX) {
left -= popup.outerWidth() + 100;
}
return { left: left + "px", top: top + "px", visibility: "visible" };
};
selector
.on("mouseenter", async (event) => {
$(document.body).find("#l5r5e-tooltip-ct").remove();
const item = await HelpersL5r5e.getEmbedItemByEvent(event, actor);
if (!item) {
return;
}
const tpl = await item.renderTextTemplate();
const tpl = await callback(event);
if (!tpl) {
return;
}
@@ -429,7 +455,7 @@ export class HelpersL5r5e {
.on("mousemove", (event) => {
const popup = $(document.body).find("#l5r5e-tooltip-ct");
if (popup) {
popup.css(HelpersL5r5e.popupPosition(event, popup));
popup.css(popupPosition(event, popup));
}
})
.on("mouseleave", () => {
@@ -437,28 +463,6 @@ export class HelpersL5r5e {
}); // tooltips
}
/**
* Return the Popup position avoiding screen borders
* @param {Event} event HTML Event
* @param popup
* @return {{top: string, visibility: string, left: string}}
*/
static popupPosition(event, popup) {
let left = +event.clientX + 60,
top = +event.clientY;
let maxY = window.innerHeight - popup.outerHeight();
if (top > maxY) {
top = maxY - 10;
}
let maxX = window.innerWidth - popup.outerWidth();
if (left > maxX) {
left -= popup.outerWidth() + 100;
}
return { left: left + "px", top: top + "px", visibility: "visible" };
}
/**
* Get a Item from a Actor Sheet
* @param {Event} event HTML Event

View File

@@ -110,5 +110,6 @@ export const RegisterSettings = function () {
config: false,
type: Array,
default: [],
onChange: () => game.l5r5e.sockets.refreshAppId("l5r5e-gm-monitor"),
});
};