Skip to content

Commit

Permalink
Move common functions from actor/item sheets to base actor/item sheets.
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickburk1988 committed Feb 1, 2024
1 parent 506f7dd commit 6ff5423
Show file tree
Hide file tree
Showing 12 changed files with 282 additions and 564 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## v1.2.1

- Moved common functions from actor sheets to `base-actor-sheet.js`.
- Moved common functions from item sheets to `base-item-sheet.js`.

## v1.2.0

- Moved roll modifier to chat message flavor text.
- Fixed identity feature non-English localization issues.

## v1.1.9

- Added option to modify rolls via popup when right-clicking roll button (or when left-clicking while holding shift, control or alt).
Expand Down
179 changes: 179 additions & 0 deletions module/actor/base-actor-sheet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
export default class UABaseActorSheet extends ActorSheet
{
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
dragDrop: [{
dragSelector: ".item-list__item" // FIX
// FIX dropSelector: null
}],
tabs: [{
navSelector: ".tab-buttons",
contentSelector: ".tab-panels",
initial: "main"
}],
width: 800
});
}

get template() {
return "systems/unknownarmies/template/actor/" + (game.user.isGM || !this.actor.limited ? "" : "limited-") + this.constructor.name.replaceAll(/UA|Sheet/g, "").toLowerCase() + "-sheet.hbs";
}

async getData (options) {
let data = await super.getData(options);
data.enrichedPublicNotes = await TextEditor.enrichHTML(this.object.system.notes.public, {
async: true
});
data.enrichedPrivateNotes = await TextEditor.enrichHTML(this.object.system.notes.private, {
async: true
});
return data;
}

activateListeners (html) {
super.activateListeners(html);
html.find("input").on("keydown", this._onInputKeydown.bind(this));
let showImage = html.find("[data-action='show-image']");
showImage.on("click", this._onShowImage.bind(this));
showImage.prop("disabled", false);
html.find("[data-action='create-item']").on("click", this._onCreateItem.bind(this));
html.find("[data-action='edit-item']").on("click", this._onEditItem.bind(this));
html.find("[data-action='destroy-item']").on("click", this._onDestroyItem.bind(this));
html.find("[data-action='roll']").on("click contextmenu", this._onRoll.bind(this));
html.find(".editor-content--extra-small").parent().addClass("editor--extra-small");
html.find(".editor-content--small").parent().addClass("editor--small");
html.find(".editor-content--large").parent().addClass("editor--large");
}

setPosition (position) {
if ($(this.form).hasClass("main-form--limited")) {
// MAYBE && position.width == 800 && position.height == 905
position.width = 650;
position.height = 600;
}
super.setPosition(position);
}

_onInputKeydown (event) {
if (event.keyCode === 13) {
event.preventDefault();
super.submit();
$(event.currentTarget)[0].blur();
}
}

_onShowImage (event) {
event.preventDefault();
new ImagePopout(this.actor.img, {
title: this.actor.name
}).render(true);
}

_onCreateItem (event) {
let type = $(event.currentTarget).data("item-type");
this.actor.createEmbeddedDocuments("Item", [{
name: game.i18n.localize("UA.New" + type.charAt(0).toUpperCase() + type.slice(1)),
type: type,
}]).then(item => {
item[0].sheet.render(true);
});
}

_onEditItem (event) {
this.actor.items.get($(event.currentTarget).parents(".item-list__item").data("item-id")).sheet.render(true);
}

_onDestroyItem (event) {
let item = this.actor.items.get($(event.currentTarget).parents(".item-list__item").data("item-id"));
Dialog.confirm({
// TODO no render defaultYes rejectClose options
// TODO buttons default close
title: game.i18n.localize("UA.Delete" + item.type.charAt(0).toUpperCase() + item.type.slice(1)),
content: `<p>${game.i18n.format("UA.DeleteItem_Details", {
name: item.name
})}</p>`,
yes: () => {
this.actor.deleteEmbeddedDocuments("Item", [
item.id
]);
}
});
}

async _onRoll (event) {
event.preventDefault();
let modifier = 0;
if (event.which == 3 || event.shiftKey || event.ctrlKey || event.altKey) {
modifier = parseInt(await this._onModifyRoll());
if (isNaN(modifier)) {
return;
}
}
let dataset = event.currentTarget.dataset;
let roll = new Roll("1d100");
await roll.evaluate();
let rollResult = parseInt(roll.result);
let vs = game.i18n.localize("UA.Vs");
let rollTarget = parseInt(dataset["rollTarget"]) + modifier;
let rollType = dataset["rollType"];
let outcome = "";
switch (rollResult) {
case 1:
if (rollType != "objective") {
outcome = "Crit";
break;
}
case 100:
if (rollType != "objective") {
outcome = "Fumble";
break;
}
default:
if (rollType != "objective" && rollResult > 10) {
let tensDigit = Math.floor(rollResult / 10);
if (tensDigit === rollResult - (tensDigit * 10)) {
outcome = "Matched ";
}
}
outcome += rollResult <= rollTarget ? "Success" : "Failure";
}
outcome = game.i18n.localize("UA." + outcome.replace(/\s/g, ""));
let modifierString = modifier == 0 ? "" : (modifier > 0 ? " + " : " - ") + Math.abs(modifier) + `%`;
let content = "";
content += `<div class="dice-roll">`;
content += ` <div class="dice-result">`;
content += ` <h4 class="dice-total">${rollResult} <span class="vs">${vs}</span> ${rollTarget}</h4>`;
content += ` <div class="dice-tooltip">`;
content += ` <section class="tooltip-part">`;
content += ` <div class="dice">`;
content += ` <header class="part-header flexrow">`;
content += ` <span class="part-formula">1d100</span>`;
content += ` <span class="part-total">${rollResult}</span>`;
content += ` </header>`;
content += ` <ol class="dice-rolls">`;
content += ` <li class="roll die d100">${rollResult}</li>`;
content += ` </ol>`;
content += ` </div>`;
content += ` </section>`;
content += ` </div>`;
content += ` <div class="dice-formula">${outcome}</div>`;
content += ` </div>`;
content += `</div>`;
roll.toMessage({
content: content,
flavor: dataset["rollLabel"] + modifierString
});
}

async _onModifyRoll () {
let modifier = false;
await Dialog.confirm({
title: game.i18n.localize("UA.ModifyRoll"),
content: `<p>${game.i18n.localize("UA.ModifyRoll_Details")}: <input type="number" style="max-width: 80px; text-align: center" data-dtype="Number" value="0" min="0" max="100">%</p>`,
yes: (prompt) => {
modifier = prompt.find("input")[0].value;
}
});
return modifier;
}
}
168 changes: 4 additions & 164 deletions module/actor/cabal-sheet.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export default class UACabalSheet extends ActorSheet
import UABaseActorSheet from "./base-actor-sheet.js";

export default class UACabalSheet extends UABaseActorSheet
{
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
Expand All @@ -7,169 +9,7 @@ export default class UACabalSheet extends ActorSheet
"sheet",
"cabal"
],
height: 600,
tabs: [{
navSelector: ".tab-buttons",
contentSelector: ".tab-panels",
initial: "main"
}],
width: 800
});
}

get template() {
if (game.user.isGM || !this.actor.limited) {
return "systems/unknownarmies/template/actor/cabal-sheet.hbs";
} else {
return "systems/unknownarmies/template/actor/limited-cabal-sheet.hbs";
}
}

async getData (options) {
let data = await super.getData(options);
data.enrichedPublicNotes = await TextEditor.enrichHTML(this.object.system.notes.public, {
async: true
});
data.enrichedPrivateNotes = await TextEditor.enrichHTML(this.object.system.notes.private, {
async: true
});
return data;
}

activateListeners (html) {
super.activateListeners(html);
html.find("input").on("keydown", this._onInputKeydown.bind(this));
let showImage = html.find("[data-action='show-image']");
showImage.on("click", this._onShowImage.bind(this));
showImage.prop("disabled", false);
html.find("[data-action='create-item']").on("click", this._onCreateItem.bind(this));
html.find("[data-action='edit-item']").on("click", this._onEditItem.bind(this));
html.find("[data-action='destroy-item']").on("click", this._onDestroyItem.bind(this));
html.find("[data-action='roll']").on("click contextmenu", this._onRoll.bind(this));
html.find(".editor-content--extra-small").parent().addClass("editor--extra-small");
}

_onInputKeydown (event) {
if (event.keyCode === 13) {
event.preventDefault();
super.submit();
$(event.currentTarget)[0].blur();
}
}

_onShowImage (event) {
event.preventDefault();
new ImagePopout(this.actor.img, {
title: this.actor.name
}).render(true);
}

_onCreateItem (event) {
let type = $(event.currentTarget).data("item-type");
this.actor.createEmbeddedDocuments("Item", [{
name: game.i18n.localize("UA.New" + type.charAt(0).toUpperCase() + type.slice(1)),
type: type
}]).then(item => {
item[0].sheet.render(true);
});
}

_onEditItem (event) {
this.actor.items.get($(event.currentTarget).parents(".item-list__item").data("item-id")).sheet.render(true);
}

_onDestroyItem (event) {
let item = this.actor.items.get($(event.currentTarget).parents(".item-list__item").data("item-id"));
let type = item.type.charAt(0).toUpperCase() + item.type.slice(1);
Dialog.confirm({
// TODO no render defaultYes rejectClose options
// TODO buttons default close
title: game.i18n.localize("UA.Delete" + type),
content: `<p>${game.i18n.format("UA.DeleteItem_Details", {
name: item.name
})}</p>`,
yes: () => {
this.actor.deleteEmbeddedDocuments("Item", [
item.id
]);
}
});
}

async _onRoll (event) {
event.preventDefault();
let modifier = 0;
if (event.which == 3 || event.shiftKey || event.ctrlKey || event.altKey) {
modifier = parseInt(await this._onModifyRoll());
if (isNaN(modifier)) {
return;
}
}
let dataset = event.currentTarget.dataset;
let roll = new Roll("1d100");
await roll.evaluate();
let rollResult = parseInt(roll.result);
let vs = game.i18n.localize("UA.Vs");
let rollTarget = parseInt(dataset["rollTarget"]) + modifier;
let rollType = dataset["rollType"];
let outcome = "";
switch (rollResult) {
case 1:
if (rollType != "objective") {
outcome = "Crit";
break;
}
case 100:
if (rollType != "objective") {
outcome = "Fumble";
break;
}
default:
if (rollType != "objective" && rollResult > 10) {
let tensDigit = Math.floor(rollResult / 10);
if (tensDigit === rollResult - (tensDigit * 10)) {
outcome = "Matched ";
}
}
outcome += rollResult <= rollTarget ? "Success" : "Failure";
}
outcome = game.i18n.localize("UA." + outcome.replace(/\s/g, ""));
let modifierString = modifier == 0 ? "" : (modifier > 0 ? " + " : " - ") + Math.abs(modifier) + `%`;
let content = "";
content += `<div class="dice-roll">`;
content += ` <div class="dice-result">`;
content += ` <h4 class="dice-total">${rollResult} <span class="vs">${vs}</span> ${rollTarget}</h4>`;
content += ` <div class="dice-tooltip">`;
content += ` <section class="tooltip-part">`;
content += ` <div class="dice">`;
content += ` <header class="part-header flexrow">`;
content += ` <span class="part-formula">1d100</span>`;
content += ` <span class="part-total">${rollResult}</span>`;
content += ` </header>`;
content += ` <ol class="dice-rolls">`;
content += ` <li class="roll die d100">${rollResult}</li>`;
content += ` </ol>`;
content += ` </div>`;
content += ` </section>`;
content += ` </div>`;
content += ` <div class="dice-formula">${outcome}</div>`;
content += ` </div>`;
content += `</div>`;
roll.toMessage({
content: content,
flavor: dataset["rollLabel"] + modifierString
});
}

async _onModifyRoll () {
let modifier = false;
await Dialog.confirm({
title: game.i18n.localize("UA.ModifyRoll"),
content: `<p>${game.i18n.localize("UA.ModifyRoll_Details")}: <input type="number" style="max-width: 80px; text-align: center" data-dtype="Number" value="0" min="0" max="100">%</p>`,
yes: (prompt) => {
modifier = prompt.find("input")[0].value;
}
height: 600
});
return modifier;
}
}
Loading

0 comments on commit 6ff5423

Please sign in to comment.