diff --git a/src/lang/en.json b/src/lang/en.json index 48cf4a9..f7ef30b 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -4,6 +4,7 @@ "OSE.Show": "Show", "OSE.Add": "Add", "OSE.Ok": "Ok", + "OSE.Update": "Update", "OSE.Reset": "Reset", "OSE.Cancel": "Cancel", "OSE.Roll": "Roll", @@ -11,6 +12,9 @@ "OSE.Failure": "Failure", "OSE.dialog.tweaks": "Tweaks", + "OSE.dialog.partysheet": "Party Overview", + "OSE.dialog.selectActors": "Select PCs", + "OSE.dialog.dealXP": "Deal XP", "OSE.Formula": "Formula", "OSE.SitMod": "Situational Modifier", @@ -137,6 +141,7 @@ "OSE.NPCReaction": "NPC Reaction", "OSE.RetainersMax": "#Retainers", + "OSE.category.saves": "Saves", "OSE.category.attributes": "Attributes", "OSE.category.inventory": "Inventory", "OSE.category.abilities": "Abilities", diff --git a/src/lang/es.json b/src/lang/es.json index 800fd7e..6ad6fca 100644 --- a/src/lang/es.json +++ b/src/lang/es.json @@ -11,6 +11,7 @@ "OSE.Failure": "Fallo", "OSE.dialog.tweaks": "Ajustes", + "OSE.dialog.partysheet": "Party Sheet", "OSE.Formula": "Formula", "OSE.SitMod": "Mod. Situational", diff --git a/src/lang/fr.json b/src/lang/fr.json index 324b119..5968803 100644 --- a/src/lang/fr.json +++ b/src/lang/fr.json @@ -11,6 +11,7 @@ "OSE.Failure": "Échec", "OSE.dialog.tweaks": "Ajuster", + "OSE.dialog.partysheet": "Fiche de Groupe", "OSE.Formula": "Formule", "OSE.SitMod": "Mod. de situation", @@ -137,6 +138,7 @@ "OSE.NPCReaction": "Réaction", "OSE.RetainersMax": "#Suivants", + "OSE.category.saves": "Sauvegardes", "OSE.category.attributes": "Stats", "OSE.category.inventory": "Inventaire", "OSE.category.abilities": "Aptitudes", diff --git a/src/module/combat.js b/src/module/combat.js index 30f7d94..290da28 100644 --- a/src/module/combat.js +++ b/src/module/combat.js @@ -19,6 +19,9 @@ export class OseCombat { // Set init for (let i = 0; i < data.combatants.length; ++i) { + if (!data.combatants[i].actor) { + return; + } if (data.combatants[i].actor.data.data.isSlow) { data.combatants[i].initiative = -789; } else { @@ -118,6 +121,9 @@ export class OseCombat { }); html.find('.combat-control[data-control="reroll"]').click((ev) => { + if (!game.combat) { + return; + } let data = {}; OseCombat.rollInitiative(game.combat, data); game.combat.update({ data: data }); diff --git a/src/module/dialog/party-sheet.js b/src/module/dialog/party-sheet.js new file mode 100644 index 0000000..4042664 --- /dev/null +++ b/src/module/dialog/party-sheet.js @@ -0,0 +1,119 @@ +export class OsePartySheet extends FormApplication { + static get defaultOptions() { + const options = super.defaultOptions; + (options.classes = ["ose", "dialog", "party-sheet"]), + (options.id = "party-sheet"); + options.template = "systems/ose/templates/apps/party-sheet.html"; + options.width = 700; + return options; + } + + /* -------------------------------------------- */ + + /** + * Add the Entity name into the window title + * @type {String} + */ + get title() { + return game.i18n.localize("OSE.dialog.partysheet"); + } + + /* -------------------------------------------- */ + + /** + * Construct and return the data object used to render the HTML template for this form application. + * @return {Object} + */ + getData() { + let data = { + data: this.object, + config: CONFIG.OSE, + user: game.user + }; + return data; + } + + _onDrop(event) { + event.preventDefault(); + + console.log("DROPPING"); + let data; + try { + data = JSON.parse(event.dataTransfer.getData("text/plain")); + if (data.type !== "Item") return; + } catch (err) { + return false; + } + console.log(data); + } + /* -------------------------------------------- */ + + _dealXP(ev) { + // Grab experience + const template = ` +
`; + let pcs = this.object.entities.filter((e) => { + return e.data.type == "character"; + }); + new Dialog({ + title: "Deal Experience", + content: template, + buttons: { + set: { + icon: '', + label: game.i18n.localize("OSE.dialog.dealXP"), + callback: (html) => { + let toDeal = html.find('input[name="total"]').val(); + const value = parseFloat(toDeal) / pcs.length; + if (value) { + // Give experience + pcs.forEach((t) => { + t.getExperience(Math.floor(value)); + }); + } + }, + }, + }, + }).render(true); + } + + async _selectActors(ev) { + const template = "/systems/ose/templates/apps/party-select.html"; + const templateData = { + actors: this.object.entities + } + const content = await renderTemplate(template, templateData); + new Dialog({ + title: "Select Party Characters", + content: content, + buttons: { + set: { + icon: '', + label: game.i18n.localize("OSE.Update"), + callback: (html) => { + let checks = html.find("input[data-action='select-actor']"); + checks.each(async (_, c) => { + let key = c.getAttribute('name'); + await this.object.entities[key].setFlag('ose', 'party', c.checked); + }); + }, + }, + }, + }).render(true); + } + + /** @override */ + activateListeners(html) { + super.activateListeners(html); + html + .find("button[data-action='select-actors']") + .click(this._selectActors.bind(this)); + html.find("button[data-action='deal-xp']").click(this._dealXP.bind(this)); + html.find("a.resync").click(() => this.render(true)); + } +} diff --git a/src/module/party.js b/src/module/party.js new file mode 100644 index 0000000..4caa3d6 --- /dev/null +++ b/src/module/party.js @@ -0,0 +1,17 @@ +import { OsePartySheet } from "./dialog/party-sheet.js"; + +export const addControl = (object, html) => { + let control = ``; + html.find(".fas.fa-search").replaceWith($(control)) + html.find('.ose-party-sheet').click(ev => { + showPartySheet(object); + }) +} + +export const showPartySheet = (object) => { + event.preventDefault(); + new OsePartySheet(object, { + top: window.screen.height / 2, + left:window.screen.width / 2, + }).render(true); +} \ No newline at end of file diff --git a/src/ose.js b/src/ose.js index 6292c80..8d6a38e 100644 --- a/src/ose.js +++ b/src/ose.js @@ -11,6 +11,7 @@ import { registerHelpers } from "./module/helpers.js"; import * as chat from "./module/chat.js"; import * as treasure from "./module/treasure.js"; import * as macros from "./module/macros.js"; +import * as party from "./module/party.js"; import { OseCombat } from "./module/combat.js"; /* -------------------------------------------- */ @@ -83,6 +84,9 @@ Hooks.once("ready", async () => { // License and KOFI infos Hooks.on("renderSidebarTab", async (object, html) => { + if (object instanceof ActorDirectory) { + party.addControl(object, html); + } if (object instanceof Settings) { const template = "systems/ose/templates/chat/license.html"; const rendered = await renderTemplate(template); diff --git a/src/scss/apps.scss b/src/scss/apps.scss index 40473ce..98ba8ec 100644 --- a/src/scss/apps.scss +++ b/src/scss/apps.scss @@ -5,6 +5,67 @@ } } +.ose.dialog.party-sheet { + .window-content { + padding: 0; + height: 200px; + } + .header { + color: whitesmoke; + background: $darkBackground; + padding: 4px 0; + text-align: center; + } + .actor-list { + margin: 0; + overflow: auto; + height: 180px; + list-style: none; + padding: 0; + .actor { + &:nth-child(even) { + background-color: rgba(0, 0, 0, 0.1); + } + padding: 2px; + font-size: 12px; + height: 35px; + text-align: center; + line-height: 35px; + .field-img { + flex: 0 0 32px; + img { + border: none; + width: 32px; + height: 32px; + } + } + } + } + .field-name { + text-align: left; + text-indent: 10px; + } + .field-short { + flex: 0 0 45px; + } + .field-long { + flex: 0 0 80px; + } + .field-longer { + flex: 0 0 180px; + } +} + +#sidebar #actors .directory-header .header-search { + .ose-party-sheet { + width: 30px; + text-align: center; + } + input { + width: calc(100% - 30px); + } +} + .ose.dialog.modifiers { .attribute-bonuses { label { diff --git a/src/templates/apps/party-select.html b/src/templates/apps/party-select.html new file mode 100644 index 0000000..8aa86b5 --- /dev/null +++ b/src/templates/apps/party-select.html @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/src/templates/apps/party-sheet.html b/src/templates/apps/party-sheet.html new file mode 100644 index 0000000..74c33ef --- /dev/null +++ b/src/templates/apps/party-sheet.html @@ -0,0 +1,59 @@ + \ No newline at end of file diff --git a/src/templates/apps/trait-selector.html b/src/templates/apps/trait-selector.html deleted file mode 100644 index 46a01c6..0000000 --- a/src/templates/apps/trait-selector.html +++ /dev/null @@ -1,13 +0,0 @@ -