Added "Gm Monitor" & reset void point to gm toolbox

This commit is contained in:
Vlyan
2021-08-13 16:12:49 +02:00
parent d13ec4049c
commit d7059f09fa
16 changed files with 533 additions and 54 deletions

View File

@@ -1,8 +1,10 @@
# Changelog
## 1.3.3 - Send to Chat
- Added "send to chat" header button on Actor, Item and Journal sheets.
- Added Opportunity usage helper Compendium (courteously authorized by Edge).
- Added "Gm Monitor", a little windows to see a summary of actor (drop any actor on it).
- Added "reset void point" and "Gm Monitor" button to GM toolbox.
- Added "send to chat" header button on : Actor, Item and Journal sheets.
- Added Opportunity usage helper in Journal Compendium (courteously authorized by Edge).
- Fixed Compendium entries thanks to TesserWract :
- Utaku Battle Maiden: Replace "Striking as Air" with "Courtier's Resolve".
- Weapons: Chair, lute, sake bottle and cups, and scroll case use the "Unarmed skill" and changed the umbrella's stab grip to be 2-handed.

View File

@@ -40,6 +40,7 @@
"global": {
"add": "Add",
"edit": "Edit",
"refresh": "Refresh",
"delete_confirm": "Are you sure you want to delete '{name}' ?",
"drop_here": "Drop here",
"send_to_chat": "To Chat",
@@ -134,7 +135,14 @@
"sleep": "Comfortable rest for all characters (Remove Water x2 fatigue)",
"sleep_info": "The characters had a good night's sleep.",
"scene_end": "End of scene (Conflict and Fatigue half reset for all characters)",
"scene_end_info": "The tension of the scene finally drops."
"scene_end_info": "The tension of the scene finally drops.",
"reset_void": "Start of the game: Reset the players' void points",
"reset_void_info": "Void points have been attributed."
},
"gm_monitor": {
"title": "GM Monitor",
"honor_glory_status": "H/G/S",
"focus_vigilance": "Foc./Vig."
},
"max": "Max",
"current": "Current",

View File

@@ -40,6 +40,7 @@
"global": {
"add": "Añadir",
"edit": "Editar",
"refresh": "Refresh",
"delete_confirm": "¿Estás seguro de que quieres borrar '{name}' ?",
"drop_here": "Dejar caer aquí",
"send_to_chat": "To Chat",
@@ -134,7 +135,14 @@
"sleep": "Descanso confortable para todos los personajes (Eliminar fatiga = Agua x2)",
"sleep_info": "Los personajes han dormido bien.",
"scene_end": "Final de la escena (El Conflicto y la Fatiga de los personajes se reduce hasta la mitad del máximo del valor)",
"scene_end_info": "La tensión de la escena por fin disminuye."
"scene_end_info": "La tensión de la escena por fin disminuye.",
"reset_void": "Start of the game: Reset the players' void points",
"reset_void_info": "Void points have been attributed."
},
"gm_monitor": {
"title": "GM Monitor",
"honor_glory_status": "H/G/S",
"focus_vigilance": "Foc./Vig."
},
"max": "Máx",
"current": "Actuales",

View File

@@ -40,6 +40,7 @@
"global": {
"add": "Ajouter",
"edit": "Modifier",
"refresh": "Actualiser",
"delete_confirm": "Etes-vous sûr de vouloir supprimer '{name}' ?",
"drop_here": "Déposez ici",
"send_to_chat": "Vers Conv.",
@@ -134,7 +135,14 @@
"sleep": "Repos confortable pour tous les personnages (Enlève Eau x2 de fatigue)",
"sleep_info": "Les personnages ont passé une bonne nuit de sommeil.",
"scene_end": "Fin de scène (Conflit et Fatigue à moitié pour tous les personnages dont la valeur dépasse ce seuil)",
"scene_end_info": "La tension de la scène retombe enfin"
"scene_end_info": "La tension de la scène retombe enfin",
"reset_void": "Début de partie : Réinitialiser les points du vide des joueurs",
"reset_void_info": "Les points du vide ont été attribués"
},
"gm_monitor": {
"title": "GM Monitor",
"honor_glory_status": "H/G/S",
"focus_vigilance": "Att./Vig."
},
"max": "Max",
"current": "Actuel",

View File

@@ -0,0 +1,315 @@
/**
* L5R GM Monitor Windows
* @extends {FormApplication}
*/
export class GmMonitor extends FormApplication {
/**
* Settings
*/
object = {
actors: [],
};
/**
* Assign the default options
* @override
*/
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
id: "l5r5e-gm-monitor",
classes: ["l5r5e", "gm-monitor"],
template: CONFIG.l5r5e.paths.templates + "gm/gm-monitor.html",
title: game.i18n.localize("l5r5e.gm_monitor.title"),
width: 640,
height: 300,
resizable: true,
closeOnSubmit: false,
submitOnClose: false,
submitOnChange: true,
dragDrop: [{ dragSelector: null, dropSelector: null }],
});
}
/**
* Add the Refresh button on top of sheet
* @override
*/
_getHeaderButtons() {
let buttons = super._getHeaderButtons();
// Send To Chat
buttons.unshift({
label: game.i18n.localize("l5r5e.global.refresh"),
class: "refresh",
icon: "fas fa-sync-alt",
onclick: async () => this.refresh(),
});
return buttons;
}
/**
* Constructor
* @param {ApplicationOptions} options
*/
constructor(options = {}) {
super(options);
this._initialize();
}
/**
* Refresh data (used from socket)
*/
async refresh() {
if (!game.user.isGM) {
return;
}
this._initialize();
this.render(false);
}
/**
* Initialize the values
* @private
*/
_initialize() {
let actors;
const ids = game.settings.get("l5r5e", "gm-monitor-actors");
if (ids.length > 0) {
// get actors with stored ids
actors = game.actors.filter((e) => ids.includes(e.id));
} else {
// If empty add pc with owner
actors = game.actors.filter((actor) => actor.data.type === "character" && actor.hasPlayerOwner);
this._saveActorsIds();
}
// Sort by name asc
actors.sort((a, b) => {
return a.name.localeCompare(b.name);
});
this.object = {
actors,
};
}
/**
* Prevent non GM to render this windows
* @override
*/
render(force = false, options = {}) {
if (!game.user.isGM) {
return false;
}
// this.position.width = "auto";
// this.position.height = "auto";
return super.render(force, options);
}
/**
* Construct and return the data object used to render the HTML template for this form application.
* @param options
* @return {Object}
* @override
*/
getData(options = null) {
return {
...super.getData(options),
data: this.object,
};
}
/**
* Listen to html elements
* @param {jQuery} html HTML content of the sheet.
* @override
*/
activateListeners(html) {
super.activateListeners(html);
if (!game.user.isGM) {
return;
}
// Open sheet
html.find(`.actor-sheet-control`).on("click", this._openActorSheet.bind(this));
// Delete
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();
const id = $(event.currentTarget).data("actor-id");
if (!id) {
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
}
/**
* This method is called upon form submission after form data is validated
* @param event The initial triggering submission event
* @param formData The object of validated form data with which to update the object
* @returns A Promise which resolves once the update operation has completed
* @override
*/
async _updateObject(event, formData) {
this.render(false);
}
/**
* Handle dropped data on the Actor sheet
* @param {DragEvent} event
*/
async _onDrop(event) {
// *** Everything below here is only needed if the sheet is editable ***
if (!this.isEditable) {
return;
}
const json = event.dataTransfer.getData("text/plain");
if (!json) {
return;
}
const data = JSON.parse(json);
if (!data || data.type !== "Actor" || !data.id || !!this.object.actors.find((e) => e.id === data.id)) {
return;
}
const actor = game.actors.filter((e) => e.id === data.id);
if (!actor) {
return;
}
this.object.actors.push(actor[0]);
await this._saveActorsIds();
return this.refresh();
}
/**
* Save the actors ids in settings
* @return {Promise<*>}
* @private
*/
async _saveActorsIds() {
return game.settings.set(
"l5r5e",
"gm-monitor-actors",
this.object.actors.map((e) => e.id)
);
}
/**
* Open the Sheet for this actor
* @param {Event} event
* @return {Promise<void>}
* @private
*/
async _openActorSheet(event) {
event.preventDefault();
event.stopPropagation();
const id = $(event.currentTarget).data("actor-id");
if (!id) {
return;
}
this.object.actors.find((e) => e.id === id)?.sheet?.render(true);
}
/**
* Remove the link to a property for the current item
* @param {Event} event
* @return {Promise<void>}
* @private
*/
async _removeActor(event) {
event.preventDefault();
event.stopPropagation();
const id = $(event.currentTarget).data("actor-id");
if (!id) {
return;
}
this.object.actors = this.object.actors.filter((e) => e.id !== id);
await this._saveActorsIds();
return this.refresh();
}
/**
* Get tooltips informations for this actor
* @param {BaseSheetL5r5e} actor
* @return {string}
* @private
*/
async _getTooltipForActor(actor) {
const data = actor.data.data;
// Peculiarities
const pec = actor.items.filter((e) => e.type === "peculiarity");
const adv = pec
.filter((e) => ["distinction", "passion"].includes(e.data.data.peculiarity_type))
.map((e) => e.name)
.join(", ");
const dis = pec
.filter((e) => ["adversity", "anxiety"].includes(e.data.data.peculiarity_type))
.map((e) => e.name)
.join(", ");
// Equipped Armors & Weapons
const arm = 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(", ");
// *** Template ***
return renderTemplate(`${CONFIG.l5r5e.paths.templates}gm/gm-monitor-tooltip.html`, {
actorData: data,
advantages: adv,
disadvantages: dis,
armors: arm,
weapons: wea,
});
}
}

View File

@@ -2,7 +2,7 @@
* L5R GM Toolbox dialog
* @extends {FormApplication}
*/
export class GmToolsDialog extends FormApplication {
export class GmToolbox extends FormApplication {
/**
* Settings
*/
@@ -16,11 +16,11 @@ export class GmToolsDialog extends FormApplication {
const x = $(window).width();
const y = $(window).height();
return foundry.utils.mergeObject(super.defaultOptions, {
id: "l5r5e-gm-tools-dialog",
classes: ["l5r5e", "gm-tools-dialog"],
template: CONFIG.l5r5e.paths.templates + "dialogs/gm-tools-dialog.html",
id: "l5r5e-gm-toolbox",
classes: ["l5r5e", "gm-toolbox"],
template: CONFIG.l5r5e.paths.templates + "gm/gm-toolbox.html",
title: game.i18n.localize("l5r5e.gm_toolbox.title"),
left: x - 512,
left: x - 605,
top: y - 98,
closeOnSubmit: false,
submitOnClose: false,
@@ -152,12 +152,25 @@ export class GmToolsDialog extends FormApplication {
game.settings.set("l5r5e", "initiative-difficulty-value", this.object.difficulty).then(() => this.submit());
});
// Scene End & Sleep
// Scene End, Sleep, void pt
html.find(`.gm_actor_updates`).on("click", (event) => {
event.preventDefault();
event.stopPropagation();
this._updatesActors($(event.currentTarget).data("type"));
});
// GM Monitor
html.find(`.gm_monitor`).on("click", (event) => {
event.preventDefault();
event.stopPropagation();
const app = Object.values(ui.windows).find((e) => e.id === "l5r5e-gm-monitor");
if (app) {
app.close();
} else {
new game.l5r5e.GmMonitor().render(true);
}
});
}
/**
@@ -202,6 +215,14 @@ export class GmToolsDialog extends FormApplication {
Math.ceil(actor.data.data.strife.max / 2)
);
break;
case "reset_void":
// only pc
if (actor.data.type !== "character" || !actor.hasPlayerOwner) {
return;
}
actor.data.data.void_points.value = Math.ceil(actor.data.data.void_points.max / 2);
break;
}
actor.update({
@@ -212,6 +233,9 @@ export class GmToolsDialog extends FormApplication {
strife: {
value: actor.data.data.strife.value,
},
void_points: {
value: actor.data.data.void_points.value,
},
},
});
});

View File

@@ -253,33 +253,34 @@ export class HelpersL5r5e {
static getPackNameForCoreItem(documentId) {
const core = new Map();
// Items
core.set("Arm", "l5r5e.core-armors");
core.set("Bon", "l5r5e.core-bonds");
core.set("Itp", "l5r5e.core-item-patterns");
core.set("Ite", "l5r5e.core-items");
core.set("Pro", "l5r5e.core-properties");
core.set("Kat", "l5r5e.core-techniques-kata");
core.set("Kih", "l5r5e.core-techniques-kiho");
core.set("Tit", "l5r5e.core-titles");
core.set("Sig", "l5r5e.core-signature-scrolls");
core.set("Wea", "l5r5e.core-weapons");
core.set("Ins", "l5r5e.core-techniques-inversion");
core.set("Inv", "l5r5e.core-techniques-invocations");
core.set("Kat", "l5r5e.core-techniques-kata");
core.set("Kih", "l5r5e.core-techniques-kiho");
core.set("Mah", "l5r5e.core-techniques-maho");
core.set("Mas", "l5r5e.core-techniques-mastery");
core.set("Nin", "l5r5e.core-techniques-ninjutsu");
core.set("Rit", "l5r5e.core-techniques-rituals");
core.set("Shu", "l5r5e.core-techniques-shuji");
core.set("Mah", "l5r5e.core-techniques-maho");
core.set("Nin", "l5r5e.core-techniques-ninjutsu");
core.set("Sch", "l5r5e.core-techniques-school");
core.set("Mas", "l5r5e.core-techniques-mastery");
core.set("Ite", "l5r5e.core-items");
core.set("Arm", "l5r5e.core-armors");
core.set("Wea", "l5r5e.core-weapons");
core.set("Bon", "l5r5e.core-bonds");
core.set("Tit", "l5r5e.core-titles");
core.set("Itp", "l5r5e.core-item-patterns");
core.set("Sig", "l5r5e.core-signature-scrolls");
core.set("Dis", "l5r5e.core-peculiarities-distinctions");
core.set("Pas", "l5r5e.core-peculiarities-passions");
core.set("Adv", "l5r5e.core-peculiarities-adversities");
core.set("Anx", "l5r5e.core-peculiarities-anxieties");
core.set("Dis", "l5r5e.core-peculiarities-distinctions");
core.set("Pas", "l5r5e.core-peculiarities-passions");
// Journal
core.set("Csc", "l5r5e.core-journal-school-curriculum");
core.set("Con", "l5r5e.core-journal-conditions");
core.set("Opp", "l5r5e.core-journal-opportunities");
core.set("Csc", "l5r5e.core-journal-school-curriculum");
core.set("Ter", "l5r5e.core-journal-terrain-qualities");
return core.get(documentId.replace(/L5RCore(\w{3})\d+/gi, "$1"));
@@ -344,7 +345,7 @@ export class HelpersL5r5e {
* Notify Applications using Difficulty settings that the values was changed
*/
static notifyDifficultyChange() {
["l5r5e-dice-picker-dialog", "l5r5e-gm-tools-dialog"].forEach((appId) => {
["l5r5e-dice-picker-dialog", "l5r5e-gm-toolbox"].forEach((appId) => {
const app = Object.values(ui.windows).find((e) => e.id === appId);
if (app && typeof app.refresh === "function") {
app.refresh();
@@ -407,21 +408,6 @@ export class HelpersL5r5e {
});
// Item detail tooltips
const fctPos = (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" };
};
html.find(".l5r5e-tooltip")
.on("mouseenter", async (event) => {
$(document.body).find("#l5r5e-tooltip-ct").remove();
@@ -436,15 +422,14 @@ export class HelpersL5r5e {
return;
}
const popup = $(document.body).append(
$(document.body).append(
`<div id="l5r5e-tooltip-ct" class="l5r5e-tooltip l5r5e-tooltip-ct">${tpl}</div>`
);
popup.css(fctPos(event, popup));
})
.on("mousemove", (event) => {
const popup = $(document.body).find("#l5r5e-tooltip-ct");
if (popup) {
popup.css(fctPos(event, popup));
popup.css(HelpersL5r5e.popupPosition(event, popup));
}
})
.on("mouseleave", () => {
@@ -452,6 +437,28 @@ 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

@@ -31,7 +31,7 @@ export default class HooksL5r5e {
// Settings TN and EncounterType
if (game.user.isGM) {
new game.l5r5e.GmToolsDialog().render(true);
new game.l5r5e.GmToolbox().render(true);
}
// ***** UI *****

View File

@@ -19,7 +19,6 @@ import { RollL5r5e } from "./dice/roll.js";
import { DicePickerDialog } from "./dice/dice-picker-dialog.js";
import { RollnKeepDialog } from "./dice/roll-n-keep-dialog.js";
import { CombatL5r5e } from "./combat.js";
import { GmToolsDialog } from "./dialogs/gm-tools-dialog.js";
// Items
import { ItemL5r5e } from "./item.js";
import { ItemSheetL5r5e } from "./items/item-sheet.js";
@@ -38,6 +37,8 @@ import { JournalL5r5e } from "./journal.js";
import { BaseJournalSheetL5r5e } from "./journals/base-journal-sheet.js";
// Specific
import { MigrationL5r5e } from "./migration.js";
import { GmToolbox } from "./gm/gm-toolbox.js";
import { GmMonitor } from "./gm/gm-monitor.js";
/* ------------------------------------ */
/* Initialize system */
@@ -84,7 +85,8 @@ Hooks.once("init", async () => {
ActorL5r5e,
DicePickerDialog,
RollnKeepDialog,
GmToolsDialog,
GmToolbox,
GmMonitor,
HelpDialog,
sockets: new SocketHandlerL5r5e(),
migrations: MigrationL5r5e,

View File

@@ -100,4 +100,15 @@ export const RegisterSettings = function () {
type: String,
default: "null",
});
/* ------------------------------------ */
/* GM Monitor windows (GM only) */
/* ------------------------------------ */
game.settings.register("l5r5e", "gm-monitor-actors", {
name: "Gm Monitor",
scope: "world", // for sync between gm
config: false,
type: Array,
default: [],
});
};

File diff suppressed because one or more lines are too long

View File

@@ -399,7 +399,25 @@
}
}
#l5r5e-gm-tools-dialog {
#l5r5e-gm-monitor {
min-height: 270px;
min-width: 500px;
.window-content {
th,
td {
border: 1px solid #5a6e5a;
padding: 0.25em;
}
img {
border: none;
max-width: 28px;
max-height: 28px;
}
}
}
#l5r5e-gm-toolbox {
//bottom: 0;
//right: 0.5rem;
display: flex;
@@ -473,7 +491,9 @@
padding: 0.5rem;
}
.fa-bed,
.fa-star-half-alt {
.fa-star-half-alt,
.fa-table,
.fa-podcast {
width: 100%;
padding: 0.5rem;
}

View File

@@ -5,6 +5,10 @@ button {
cursor: url("../assets/cursors/pointer.webp"), pointer;
}
.pointer {
cursor: url("../assets/cursors/pointer.webp"), pointer;
}
// sidebar
#sidebar {
padding: 0.5rem 0.25rem 0.5rem 0.5rem;

View File

@@ -0,0 +1,19 @@
<section>
<ul>
{{!-- Ninjo/Giri --}}
<li><b>{{localize 'l5r5e.social.ninjo'}}</b> : {{actorData.social.ninjo}}</li>
<li><b>{{localize 'l5r5e.social.giri'}}</b> : {{actorData.social.giri}}</li>
{{!-- Bushido Tenet --}}
<li><b>{{localize 'l5r5e.social.bushido_tenets.paramount'}}</b> : {{actorData.social.bushido_tenets.paramount}}</li>
<li><b>{{localize 'l5r5e.social.bushido_tenets.less_significant'}}</b> : {{actorData.social.bushido_tenets.less_significant}}</li>
{{!-- Peculiarities --}}
<li><b>{{localize 'l5r5e.social.npc.advantages'}}</b> : {{advantages}}</li>
<li><b>{{localize 'l5r5e.social.npc.disadvantages'}}</b> : {{disadvantages}}</li>
{{!-- Equipped Armors & Weapons --}}
<li><b>{{localize 'l5r5e.armors.title'}}</b> : {{{armors}}}</li>
<li><b>{{localize 'l5r5e.weapons.title'}}</b> : {{{weapons}}}</li>
</ul>
</section>

View File

@@ -0,0 +1,45 @@
<form class="l5r5e gm-monitor" autocomplete="off">
<table>
<thead>
<th class="img"></th>
<th class="stance"></th>
<th class="name">{{localize 'l5r5e.name'}}</th>
<th class="rank"><i class="i_bushi"></i> / <i class="i_courtier"></i></th>
<th class="social">{{localize 'l5r5e.gm_monitor.honor_glory_status'}}</th>
<th class="fatigue">{{localize 'l5r5e.attributes.fatigue'}}</th>
<th class="strife">{{localize 'l5r5e.attributes.strife'}}</th>
<th class="vigilance">{{localize 'l5r5e.gm_monitor.focus_vigilance'}}</th>
<th class="void"><i class="i_void"></i></th>
<th class=""></th>
<th class=""></th>
</thead>
<tbody>
{{#each data.actors as |actor|}}
<tr>
<td><img class="profile actor-profile" title="{{actor.name}}" src="{{actor.img}}"></td>
<td><i class="{{actor.data.data.stance}} i_{{actor.data.data.stance}}"></i></td>
<td>
<a data-actor-id="{{actor.id}}" class="actor-sheet-control">{{actor.name}}</a>
{{#if actor.data.data.attitude}}<br>({{actor.data.data.attitude}}){{/if}}
</td>
<td>
{{#if actor.data.data.identity.school_rank}}
{{actor.data.data.identity.school_rank}}
{{else}}
{{actor.data.data.conflict_rank.martial}} / {{actor.data.data.conflict_rank.social}}
{{/if}}
</td>
<td>
{{actor.data.data.social.honor}} / {{actor.data.data.social.glory}} / {{actor.data.data.social.status}}
</td>
<td>{{actor.data.data.fatigue.value}} / {{actor.data.data.fatigue.max}}</td>
<td>{{actor.data.data.strife.value}} / {{actor.data.data.strife.max}}</td>
<td>{{actor.data.data.focus}} / {{actor.data.data.vigilance}}</td>
<td>{{actor.data.data.void_points.value}} / {{actor.data.data.void_points.max}}</td>
<td><i data-actor-id="{{actor.id}}" class="fas fa-question-circle actor-infos-control"></i></td>
<td><span data-actor-id="{{actor.id}}" class="actor-remove-control pointer" title="{{localize 'Delete'}}"><i class="fas fa-trash"></i></span></td>
</tr>
{{/each}}
</tbody>
</table>
</form>

View File

@@ -1,9 +1,15 @@
<form class="l5r5e gm-tools-dialog" autocomplete="off">
<form class="l5r5e gm-toolbox" autocomplete="off">
<ul class="gm-tools-container">
<li class="gm_monitor" title="{{localize 'l5r5e.gm_monitor.title'}}">
<i class="fas fa-table"></i>
</li>
<li class="difficulty_hidden" title="{{localize 'l5r5e.gm_toolbox.difficulty_hidden'}}">
<i class="fa fa-eye{{#if data.difficultyHidden}}-slash{{/if}}"></i>
<strong class="difficulty" title="{{localize 'l5r5e.gm_toolbox.difficulty'}}">{{data.difficulty}}</strong>
</li>
<li class="gm_actor_updates reset_void" data-type="reset_void" title="{{localize 'l5r5e.gm_toolbox.reset_void'}}">
<i class="fas fa-podcast"></i>
</li>
<li class="gm_actor_updates sleep" data-type="sleep" title="{{localize 'l5r5e.gm_toolbox.sleep'}}">
<i class="fa fa-bed"></i>
</li>