Migrate to FoundryVTT v13 AppV2 +
│ DataModels │ │ - Reorganize DataModels into src/module/models/ (one .mjs per type) │ - Create AppV2 actor/item sheets (HandlebarsApplicationMixin)…
This commit is contained in:
68
.github/copilot-instructions.md
vendored
Normal file
68
.github/copilot-instructions.md
vendored
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# Copilot Instructions for foundryvtt-mgt2
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
This is a [Foundry VTT](https://foundryvtt.com) game system implementing Mongoose Publishing Traveller 2nd Edition (MGT2). It runs entirely in the browser within the FoundryVTT platform — there is no Node.js runtime or backend server to develop against.
|
||||||
|
|
||||||
|
The distributed entry point is `mgt2.bundle.js` (pre-bundled from `src/`). CSS is compiled from `src/sass/` to `styles/mgt2.min.css`. No build tooling (package.json, webpack, etc.) is committed to the repo, so bundling is done externally.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Entry Point & Initialization
|
||||||
|
|
||||||
|
`src/module/core.js` is the main module. It runs in the FoundryVTT `init` hook and:
|
||||||
|
- Registers all Actor/Item document classes
|
||||||
|
- Registers all TypeDataModel schemas (`datamodels.js`)
|
||||||
|
- Registers sheets (actor and item)
|
||||||
|
- Preloads Handlebars templates
|
||||||
|
|
||||||
|
### Document Classes
|
||||||
|
|
||||||
|
| Class | File | Purpose |
|
||||||
|
|---|---|---|
|
||||||
|
| `TravellerActor` | `actors/actor.js` | Extends `Actor`; delegates character logic to `ActorCharacter` |
|
||||||
|
| `ActorCharacter` | `actors/character.js` | Static methods for character-specific actor logic |
|
||||||
|
| `TravellerItem` | `item.js` | Extends `Item` |
|
||||||
|
| `MGT2Combatant` | `actors/actor.js` | Extends `Combatant` |
|
||||||
|
|
||||||
|
### Sheets
|
||||||
|
|
||||||
|
- **`TravellerActorSheet`** (`actors/character-sheet.js`) — character sheet. Uses `templates/actors/actor-sheet.html`. `getData()` returns `context.data` (not the full context).
|
||||||
|
- **`TravellerItemSheet`** (`item-sheet.js`) — item sheet. Template is dynamically resolved as `templates/items/{item.type}-sheet.html`.
|
||||||
|
- **`VehiculeSheet`** (`actors/vehicule-sheet.js`) — vehicle actor sheet.
|
||||||
|
|
||||||
|
### Data Models
|
||||||
|
|
||||||
|
All schemas are TypeDataModels defined in `src/module/datamodels.js`. Actor types: `character`, `vehicule`. Item types: `contact`, `career`, `disease`, `item`, `equipment`, `talent`, `armor`, `weapon`, `computer`, `container`, `species`.
|
||||||
|
|
||||||
|
The `CharacterData` model uses a helper `createCharacteristicField()` for the 12 characteristics (strength, dexterity, endurance, intellect, education, social, morale, luck, sanity, charm, psionic, other). Each characteristic has `.value`, `.max`, and `.dm` fields.
|
||||||
|
|
||||||
|
### Config Constants
|
||||||
|
|
||||||
|
`src/module/config.js` exports `MGT2` — a set of frozen objects mapping internal keys to i18n strings (e.g., `MGT2.Difficulty.Average`). Accessible at runtime via `CONFIG.MGT2`.
|
||||||
|
|
||||||
|
### Templates
|
||||||
|
|
||||||
|
Handlebars templates live in `templates/`. Paths always use the FoundryVTT-relative prefix `systems/mgt2/templates/...`. Partial templates (used across sheets) live in `templates/items/parts/`.
|
||||||
|
|
||||||
|
### Styles & Theming
|
||||||
|
|
||||||
|
SASS source is in `src/sass/`. The active theme is a CSS class applied to every sheet element — e.g. `["mgt2", game.settings.get("mgt2", "theme"), "sheet", ...]`. Available themes: `black-and-red`, `mwamba`, `blue`.
|
||||||
|
|
||||||
|
### Localization
|
||||||
|
|
||||||
|
All user-facing strings go through `game.i18n.localize()`. Keys follow the pattern `MGT2.Section.Key`. String definitions are in `lang/en.json` and `lang/fr.json`.
|
||||||
|
|
||||||
|
### Chat Cards
|
||||||
|
|
||||||
|
`ChatHelper` (`chatHelper.js`) hooks into `renderChatMessage` to attach button listeners. Chat card templates are in `templates/chat/`.
|
||||||
|
|
||||||
|
## Key Conventions
|
||||||
|
|
||||||
|
- **`getData()` returns `context.data`** — the character sheet's `getData()` calls `super.getData()` then returns `context.data`, not `context` itself. Keep this pattern for character sheet overrides.
|
||||||
|
- **Actor logic delegation** — `TravellerActor` is thin; type-specific logic lives in static methods on `ActorCharacter`. Follow this pattern for new actor types.
|
||||||
|
- **Settings keys** — always namespaced as `game.settings.get("mgt2", "settingName")`. Settings are registered in `settings.js`.
|
||||||
|
- **`vehicule` spelling** — the actor type and related files use the French spelling `vehicule` (not `vehicle`). Do not rename.
|
||||||
|
- **Template paths** — always use the full FoundryVTT path `systems/mgt2/templates/...` in JS; never relative paths.
|
||||||
|
- **i18n keys in config** — `config.js` stores i18n key strings (not translated text). Actual translation happens at render time via `game.i18n.localize()`.
|
||||||
|
- **`life` is the primary token attribute** — configured in `system.json` as `primaryTokenAttribute: "life"`.
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -28,3 +28,4 @@
|
|||||||
.history/
|
.history/
|
||||||
|
|
||||||
mgt2.zip
|
mgt2.zip
|
||||||
|
assets/regles/
|
||||||
|
|||||||
BIN
assets/regles/traveller_regle_v2_1_81-87_creatures.pdf
Normal file
BIN
assets/regles/traveller_regle_v2_1_81-87_creatures.pdf
Normal file
Binary file not shown.
446
mgt2.bundle.js
446
mgt2.bundle.js
@@ -695,12 +695,11 @@ class ActorCharacter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (recalculEncumbrance || recalculWeight) {
|
if (recalculEncumbrance || recalculWeight) {
|
||||||
const cloneActor = foundry.utils.deepClone($this);
|
const updateData = {};
|
||||||
|
|
||||||
await this.recalculateArmor($this, cloneActor);
|
this.recalculateArmor($this, updateData);
|
||||||
|
|
||||||
if (recalculEncumbrance) {
|
if (recalculEncumbrance) {
|
||||||
//console.log("recalculEncumbrance");
|
|
||||||
const str = $this.system.characteristics.strength.value;
|
const str = $this.system.characteristics.strength.value;
|
||||||
const end = $this.system.characteristics.endurance.value;
|
const end = $this.system.characteristics.endurance.value;
|
||||||
let sumSkill = 0;
|
let sumSkill = 0;
|
||||||
@@ -708,19 +707,21 @@ class ActorCharacter {
|
|||||||
let normal = str + end + sumSkill;
|
let normal = str + end + sumSkill;
|
||||||
let heavy = normal * 2;
|
let heavy = normal * 2;
|
||||||
|
|
||||||
cloneActor.system.states.encumbrance = $this.system.inventory.weight > normal;
|
updateData["system.states.encumbrance"] = $this.system.inventory.weight > normal;
|
||||||
cloneActor.system.encumbrance.normal = normal;
|
updateData["system.inventory.encumbrance.normal"] = normal;
|
||||||
cloneActor.system.encumbrance.heavy = heavy;
|
updateData["system.inventory.encumbrance.heavy"] = heavy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recalculWeight)
|
if (recalculWeight)
|
||||||
await this.recalculateWeight($this, cloneActor);
|
await this.recalculateWeight($this, updateData);
|
||||||
|
else if (Object.keys(updateData).length > 0)
|
||||||
|
await $this.update(updateData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async recalculateArmor($this, cloneActor) {
|
static recalculateArmor($this, updateData) {
|
||||||
if (cloneActor === null || cloneActor === undefined)
|
if (updateData === null || updateData === undefined)
|
||||||
cloneActor = foundry.utils.deepClone($this);
|
updateData = {};
|
||||||
|
|
||||||
let armor = 0;
|
let armor = 0;
|
||||||
for (let item of $this.items) {
|
for (let item of $this.items) {
|
||||||
@@ -731,18 +732,18 @@ class ActorCharacter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cloneActor.system.inventory.armor = armor;
|
updateData["system.inventory.armor"] = armor;
|
||||||
|
return updateData;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async recalculateWeight($this, cloneActor) {
|
static async recalculateWeight($this, updateData) {
|
||||||
|
|
||||||
if (cloneActor === null || cloneActor === undefined)
|
if (updateData === null || updateData === undefined)
|
||||||
cloneActor = foundry.utils.deepClone($this);
|
updateData = {};
|
||||||
|
|
||||||
let updatedContainers = [];
|
let updatedContainers = [];
|
||||||
let containerChanges = {};
|
let containerChanges = {};
|
||||||
|
|
||||||
//console.log("recalculWeight");
|
|
||||||
let containers = [];
|
let containers = [];
|
||||||
|
|
||||||
// List all containers
|
// List all containers
|
||||||
@@ -791,19 +792,16 @@ class ActorCharacter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//cloneActor.system.inventory.weight = onHandWeight.toFixed(1);
|
|
||||||
|
|
||||||
// Check containers new weight
|
// Check containers new weight
|
||||||
for (let container of containers) {
|
for (let container of containers) {
|
||||||
let newWeight = containerChanges[container._id].weight;
|
let newWeight = containerChanges[container._id].weight;
|
||||||
let newCount = containerChanges[container._id].count;
|
let newCount = containerChanges[container._id].count;
|
||||||
if (container.system.weight !== newWeight || container.system.count !== newCount) {
|
if (container.system.weight !== newWeight || container.system.count !== newCount) {
|
||||||
//const cloneContainer = foundry.utils.deepClone();
|
updatedContainers.push({
|
||||||
const cloneContainer = foundry.utils.deepClone($this.getEmbeddedDocument("Item", container._id));
|
_id: container._id,
|
||||||
//foundry.utils.setProperty(cloneContainer, "system.weight", newWeight);
|
"system.weight": newWeight,
|
||||||
cloneContainer.system.weight = newWeight;
|
"system.count": newCount,
|
||||||
cloneContainer.system.count = newCount;
|
});
|
||||||
updatedContainers.push(cloneContainer);
|
|
||||||
|
|
||||||
if (container.system.onHand === true &&
|
if (container.system.onHand === true &&
|
||||||
(container.system.weight > 0 || container.system.weightless !== true)) {
|
(container.system.weight > 0 || container.system.weightless !== true)) {
|
||||||
@@ -812,11 +810,10 @@ class ActorCharacter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cloneActor.system.inventory.weight = onHandWeight;
|
updateData["system.inventory.weight"] = onHandWeight;
|
||||||
cloneActor.system.states.encumbrance = onHandWeight > $this.system.inventory.encumbrance.normal;
|
updateData["system.states.encumbrance"] = onHandWeight > $this.system.inventory.encumbrance.normal;
|
||||||
|
|
||||||
|
await $this.update(updateData);
|
||||||
await $this.update(cloneActor);
|
|
||||||
|
|
||||||
if (updatedContainers.length > 0) {
|
if (updatedContainers.length > 0) {
|
||||||
await $this.updateEmbeddedDocuments('Item', updatedContainers);
|
await $this.updateEmbeddedDocuments('Item', updatedContainers);
|
||||||
@@ -1198,7 +1195,7 @@ class MGT2ActorSheet extends HandlebarsApplicationMixin$1(foundry.applications.s
|
|||||||
return this._sheetMode === this.constructor.SHEET_MODES.EDIT;
|
return this._sheetMode === this.constructor.SHEET_MODES.EDIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
tabGroups = { primary: "stats" }
|
tabGroups = { sidebar: "health" }
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
async _prepareContext() {
|
async _prepareContext() {
|
||||||
@@ -1226,6 +1223,9 @@ class MGT2ActorSheet extends HandlebarsApplicationMixin$1(foundry.applications.s
|
|||||||
/** @override */
|
/** @override */
|
||||||
_onRender(context, options) {
|
_onRender(context, options) {
|
||||||
super._onRender(context, options);
|
super._onRender(context, options);
|
||||||
|
// Inject theme class dynamically (can't use game.settings in static DEFAULT_OPTIONS)
|
||||||
|
const theme = game.settings.get("mgt2", "theme");
|
||||||
|
if (theme) this.element.classList.add(theme);
|
||||||
this._activateTabGroups();
|
this._activateTabGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1493,17 +1493,15 @@ class MGT2Helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RollPromptDialog extends Dialog {
|
const { DialogV2: DialogV2$1 } = foundry.applications.api;
|
||||||
constructor(dialogData = {}, options = {}) {
|
const { renderTemplate: renderTemplate$1 } = foundry.applications.handlebars;
|
||||||
super(dialogData, options);
|
const { FormDataExtended: FormDataExtended$1 } = foundry.applications.ux;
|
||||||
this.options.classes = ["mgt2", game.settings.get("mgt2", "theme"), "sheet", "dialog"];
|
|
||||||
}
|
|
||||||
|
|
||||||
static async create(options) {
|
class RollPromptHelper {
|
||||||
|
|
||||||
const htmlContent = await renderTemplate('systems/mgt2/templates/roll-prompt.html', {
|
static async roll(options) {
|
||||||
|
const htmlContent = await renderTemplate$1('systems/mgt2/templates/roll-prompt.html', {
|
||||||
config: CONFIG.MGT2,
|
config: CONFIG.MGT2,
|
||||||
//formula: formula,
|
|
||||||
characteristics: options.characteristics,
|
characteristics: options.characteristics,
|
||||||
characteristic: options.characteristic,
|
characteristic: options.characteristic,
|
||||||
skills: options.skills,
|
skills: options.skills,
|
||||||
@@ -1513,241 +1511,116 @@ class RollPromptDialog extends Dialog {
|
|||||||
difficulty: options.difficulty
|
difficulty: options.difficulty
|
||||||
});
|
});
|
||||||
|
|
||||||
const results = new Promise(resolve => {
|
game.settings.get("mgt2", "theme");
|
||||||
new this({
|
|
||||||
title: options.title,
|
return await DialogV2$1.wait({
|
||||||
|
window: { title: options.title ?? options.rollTypeName ?? game.i18n.localize("MGT2.RollPrompt.Roll") },
|
||||||
content: htmlContent,
|
content: htmlContent,
|
||||||
buttons: {
|
rejectClose: false,
|
||||||
boon: {
|
buttons: [
|
||||||
|
{
|
||||||
|
action: "boon",
|
||||||
label: game.i18n.localize("MGT2.RollPrompt.Boon"),
|
label: game.i18n.localize("MGT2.RollPrompt.Boon"),
|
||||||
callback: (html) => {
|
callback: (event, button, dialog) => {
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
const formData = new FormDataExtended$1(dialog.element.querySelector('form')).object;
|
||||||
formData.diceModifier = "dl";
|
formData.diceModifier = "dl";
|
||||||
resolve(formData);
|
return formData;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
submit: {
|
{
|
||||||
|
action: "submit",
|
||||||
label: game.i18n.localize("MGT2.RollPrompt.Roll"),
|
label: game.i18n.localize("MGT2.RollPrompt.Roll"),
|
||||||
icon: '<i class="fa-solid fa-dice"></i>',
|
icon: '<i class="fa-solid fa-dice"></i>',
|
||||||
callback: (html) => {
|
default: true,
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
callback: (event, button, dialog) => {
|
||||||
resolve(formData);
|
return new FormDataExtended$1(dialog.element.querySelector('form')).object;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
bane: {
|
action: "bane",
|
||||||
label: game.i18n.localize("MGT2.RollPrompt.Bane"),
|
label: game.i18n.localize("MGT2.RollPrompt.Bane"),
|
||||||
//icon: '<i class="fa-solid fa-dice"></i>',
|
callback: (event, button, dialog) => {
|
||||||
callback: (html) => {
|
const formData = new FormDataExtended$1(dialog.element.querySelector('form')).object;
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
|
||||||
formData.diceModifier = "dh";
|
formData.diceModifier = "dh";
|
||||||
resolve(formData);
|
return formData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
//close: () => { resolve(false) }
|
|
||||||
}).render(true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//console.log(Promise.resolve(results));
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RollPromptHelper {
|
const { DialogV2 } = foundry.applications.api;
|
||||||
|
const { renderTemplate } = foundry.applications.handlebars;
|
||||||
|
const { FormDataExtended } = foundry.applications.ux;
|
||||||
|
|
||||||
static async roll(options) {
|
async function _dialogWithForm(title, templatePath, templateData) {
|
||||||
return await RollPromptDialog.create(options);
|
const htmlContent = await renderTemplate(templatePath, templateData);
|
||||||
}
|
game.settings.get("mgt2", "theme");
|
||||||
|
return await DialogV2.wait({
|
||||||
static async promptForFruitTraits() {
|
window: { title },
|
||||||
const htmlContent = await renderTemplate('systems/mgt2/templateschat/chat/roll-prompt.html');
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const dialog = new Dialog({
|
|
||||||
title: "Fruit Traits",
|
|
||||||
content: htmlContent,
|
content: htmlContent,
|
||||||
buttons: {
|
rejectClose: false,
|
||||||
submit: {
|
buttons: [
|
||||||
label: "Roll",
|
{
|
||||||
icon: '<i class="fa-solid fa-dice"></i>',
|
action: "submit",
|
||||||
callback: (html) => {
|
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form'))
|
|
||||||
.toObject();
|
|
||||||
|
|
||||||
//verifyFruitInputs(formData);
|
|
||||||
|
|
||||||
resolve(formData);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
skip: {
|
|
||||||
label: "Cancel",
|
|
||||||
callback: () => resolve(null),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
render: (html) => {
|
|
||||||
//html.on('click', 'button[data-preset]', handleFruitPreset);
|
|
||||||
},
|
|
||||||
close: () => {
|
|
||||||
reject('User closed dialog without making a selection.');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
dialog.render(true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class EditorFullViewDialog extends Dialog {
|
|
||||||
constructor(dialogData = {}, options = {}) {
|
|
||||||
super(dialogData, options);
|
|
||||||
this.options.classes = ["mgt2", game.settings.get("mgt2", "theme"), "sheet"];
|
|
||||||
this.options.resizable = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async create(title, html) {
|
|
||||||
const htmlContent = await renderTemplate("systems/mgt2/templates/editor-fullview.html", {
|
|
||||||
config: CONFIG.MGT2,
|
|
||||||
html: html
|
|
||||||
});
|
|
||||||
|
|
||||||
const results = new Promise(resolve => {
|
|
||||||
new this({
|
|
||||||
title: title,
|
|
||||||
content: htmlContent,
|
|
||||||
buttons: {
|
|
||||||
//close: { label: game.i18n.localize("MGT2.Close") }
|
|
||||||
}
|
|
||||||
}).render(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ActorConfigDialog extends Dialog {
|
|
||||||
constructor(dialogData = {}, options = {}) {
|
|
||||||
super(dialogData, options);
|
|
||||||
this.options.classes = ["mgt2", game.settings.get("mgt2", "theme"), "sheet"];
|
|
||||||
}
|
|
||||||
|
|
||||||
static async create(system) {
|
|
||||||
const htmlContent = await renderTemplate("systems/mgt2/templates/actors/actor-config-sheet.html", {
|
|
||||||
config: CONFIG.MGT2,
|
|
||||||
system: system
|
|
||||||
});
|
|
||||||
|
|
||||||
const results = new Promise(resolve => {
|
|
||||||
new this({
|
|
||||||
title: "Configuration",
|
|
||||||
content: htmlContent,
|
|
||||||
buttons: {
|
|
||||||
submit: {
|
|
||||||
label: game.i18n.localize("MGT2.Save"),
|
label: game.i18n.localize("MGT2.Save"),
|
||||||
icon: '<i class="fa-solid fa-floppy-disk"></i>',
|
icon: '<i class="fa-solid fa-floppy-disk"></i>',
|
||||||
callback: (html) => {
|
default: true,
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
callback: (event, button, dialog) => {
|
||||||
resolve(formData);
|
return new FormDataExtended(dialog.element.querySelector('form')).object;
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).render(true);
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ActorCharacteristicDialog extends Dialog {
|
|
||||||
// https://foundryvtt.wiki/en/development/api/dialog
|
|
||||||
constructor(dialogData = {}, options = {}) {
|
|
||||||
super(dialogData, options);
|
|
||||||
this.options.classes = ["mgt2", game.settings.get("mgt2", "theme"), "sheet"];
|
|
||||||
}
|
|
||||||
|
|
||||||
static async create(name, show, showMax, showAll = false) {
|
|
||||||
const htmlContent = await renderTemplate("systems/mgt2/templates/actors/actor-config-characteristic-sheet.html", {
|
|
||||||
name: name,
|
|
||||||
show: show,
|
|
||||||
showMax: showMax,
|
|
||||||
showAll: showAll
|
|
||||||
});
|
|
||||||
|
|
||||||
const results = new Promise(resolve => {
|
|
||||||
new this({
|
|
||||||
title: "Configuration: " + name,
|
|
||||||
content: htmlContent,
|
|
||||||
buttons: {
|
|
||||||
submit: {
|
|
||||||
label: game.i18n.localize("MGT2.Save"),
|
|
||||||
icon: '<i class="fa-solid fa-floppy-disk"></i>',
|
|
||||||
callback: (html) => {
|
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
|
||||||
resolve(formData);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).render(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TraitEditDialog extends Dialog {
|
|
||||||
constructor(dialogData = {}, options = {}) {
|
|
||||||
super(dialogData, options);
|
|
||||||
this.options.classes = ["mgt2", game.settings.get("mgt2", "theme"), "sheet"];
|
|
||||||
}
|
|
||||||
|
|
||||||
static async create(data) {
|
|
||||||
const htmlContent = await renderTemplate("systems/mgt2/templates/actors/trait-sheet.html", {
|
|
||||||
config: CONFIG.MGT2,
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
const title = data.hasOwnProperty("name") && data.name !== undefined ? data.name : game.i18n.localize("MGT2.Actor.EditTrait");
|
|
||||||
const results = new Promise(resolve => {
|
|
||||||
new this({
|
|
||||||
title: title,
|
|
||||||
content: htmlContent,
|
|
||||||
buttons: {
|
|
||||||
submit: {
|
|
||||||
label: game.i18n.localize("MGT2.Save"),
|
|
||||||
icon: '<i class="fa-solid fa-floppy-disk"></i>',
|
|
||||||
callback: (html) => {
|
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
|
||||||
resolve(formData);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
//cancel: { label: "Cancel" }
|
|
||||||
}
|
|
||||||
// close: (html) => {
|
|
||||||
// console.log("This always is logged no matter which option is chosen");
|
|
||||||
// const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
|
||||||
// resolve(formData);
|
|
||||||
// }
|
|
||||||
}).render(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CharacterPrompts {
|
class CharacterPrompts {
|
||||||
|
|
||||||
static async openConfig(system) {
|
static async openConfig(system) {
|
||||||
return await ActorConfigDialog.create(system);
|
return _dialogWithForm(
|
||||||
|
"Configuration",
|
||||||
|
"systems/mgt2/templates/actors/actor-config-sheet.html",
|
||||||
|
{ config: CONFIG.MGT2, system }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async openCharacteristic(name, hide, showMax, showAll = false) {
|
static async openCharacteristic(name, show, showMax, showAll = false) {
|
||||||
return await ActorCharacteristicDialog.create(name, hide, showMax, showAll);
|
return _dialogWithForm(
|
||||||
|
"Configuration: " + name,
|
||||||
|
"systems/mgt2/templates/actors/actor-config-characteristic-sheet.html",
|
||||||
|
{ name, show, showMax, showAll }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async openTraitEdit(data) {
|
static async openTraitEdit(data) {
|
||||||
return await TraitEditDialog.create(data);
|
const title = data.name ?? game.i18n.localize("MGT2.Actor.EditTrait");
|
||||||
|
return _dialogWithForm(
|
||||||
|
title,
|
||||||
|
"systems/mgt2/templates/actors/trait-sheet.html",
|
||||||
|
{ config: CONFIG.MGT2, data }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async openEditorFullView(title, html) {
|
static async openEditorFullView(title, html) {
|
||||||
return await EditorFullViewDialog.create(title, html);
|
const htmlContent = await renderTemplate("systems/mgt2/templates/editor-fullview.html", {
|
||||||
|
config: CONFIG.MGT2,
|
||||||
|
html
|
||||||
|
});
|
||||||
|
game.settings.get("mgt2", "theme");
|
||||||
|
await DialogV2.wait({
|
||||||
|
window: { title },
|
||||||
|
content: htmlContent,
|
||||||
|
rejectClose: false,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
action: "close",
|
||||||
|
label: game.i18n.localize("MGT2.Close") || "Fermer",
|
||||||
|
default: true,
|
||||||
|
callback: () => null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1792,7 +1665,7 @@ class TravellerCharacterSheet extends MGT2ActorSheet {
|
|||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
tabGroups = {
|
tabGroups = {
|
||||||
primary: "inventory",
|
sidebar: "inventory",
|
||||||
characteristics: "core",
|
characteristics: "core",
|
||||||
inventory: "onhand",
|
inventory: "onhand",
|
||||||
}
|
}
|
||||||
@@ -2468,7 +2341,7 @@ class TravellerCharacterSheet extends MGT2ActorSheet {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let roll = await new Roll(rollFormula, this.actor.getRollData()).roll({ async: true, rollMode: userRollData.rollMode });
|
let roll = await new Roll(rollFormula, this.actor.getRollData()).roll({ rollMode: userRollData.rollMode });
|
||||||
|
|
||||||
if (isInitiative && this.token?.combatant) {
|
if (isInitiative && this.token?.combatant) {
|
||||||
await this.token.combatant.update({ initiative: roll.total });
|
await this.token.combatant.update({ initiative: roll.total });
|
||||||
@@ -2480,7 +2353,6 @@ class TravellerCharacterSheet extends MGT2ActorSheet {
|
|||||||
formula: roll._formula,
|
formula: roll._formula,
|
||||||
tooltip: await roll.getTooltip(),
|
tooltip: await roll.getTooltip(),
|
||||||
total: Math.round(roll.total * 100) / 100,
|
total: Math.round(roll.total * 100) / 100,
|
||||||
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
|
|
||||||
showButtons: true,
|
showButtons: true,
|
||||||
showLifeButtons: false,
|
showLifeButtons: false,
|
||||||
showRollRequest: false,
|
showRollRequest: false,
|
||||||
@@ -2500,7 +2372,7 @@ class TravellerCharacterSheet extends MGT2ActorSheet {
|
|||||||
chatData.rollFailure = true;
|
chatData.rollFailure = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const html = await renderTemplate("systems/mgt2/templates/chat/roll.html", chatData);
|
const html = await foundry.applications.handlebars.renderTemplate("systems/mgt2/templates/chat/roll.html", chatData);
|
||||||
chatData.content = html;
|
chatData.content = html;
|
||||||
|
|
||||||
let flags = null;
|
let flags = null;
|
||||||
@@ -2640,12 +2512,14 @@ class TravellerItemSheet extends HandlebarsApplicationMixin(foundry.applications
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @override */
|
/** Dynamic PARTS: template resolved per item type */
|
||||||
static PARTS = {
|
get PARTS() {
|
||||||
|
const type = this.document?.type ?? "item";
|
||||||
|
return {
|
||||||
sheet: {
|
sheet: {
|
||||||
// template is dynamic — resolved in _prepareContext / _renderHTML
|
template: `systems/mgt2/templates/items/${type}-sheet.html`,
|
||||||
template: "",
|
|
||||||
},
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resolve template dynamically based on item type */
|
/** Resolve template dynamically based on item type */
|
||||||
@@ -2699,7 +2573,7 @@ class TravellerItemSheet extends HandlebarsApplicationMixin(foundry.applications
|
|||||||
systemFields: item.system.schema.fields,
|
systemFields: item.system.schema.fields,
|
||||||
isEditable: this.isEditable,
|
isEditable: this.isEditable,
|
||||||
isGM: game.user.isGM,
|
isGM: game.user.isGM,
|
||||||
config: CONFIG,
|
config: CONFIG.MGT2,
|
||||||
settings: settings,
|
settings: settings,
|
||||||
containers: containers,
|
containers: containers,
|
||||||
computers: computers,
|
computers: computers,
|
||||||
@@ -2713,13 +2587,16 @@ class TravellerItemSheet extends HandlebarsApplicationMixin(foundry.applications
|
|||||||
/** @override — resolve the per-type template before rendering */
|
/** @override — resolve the per-type template before rendering */
|
||||||
async _renderHTML(context, options) {
|
async _renderHTML(context, options) {
|
||||||
const templatePath = `systems/mgt2/templates/items/${this.document.type}-sheet.html`;
|
const templatePath = `systems/mgt2/templates/items/${this.document.type}-sheet.html`;
|
||||||
const html = await renderTemplate(templatePath, context);
|
const html = await foundry.applications.handlebars.renderTemplate(templatePath, context);
|
||||||
return { sheet: html };
|
return { sheet: html };
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @override — put rendered HTML into the window content */
|
/** @override — put rendered HTML into the window content */
|
||||||
_replaceHTML(result, content, options) {
|
_replaceHTML(result, content, options) {
|
||||||
content.innerHTML = result.sheet;
|
content.innerHTML = result.sheet;
|
||||||
|
// Inject theme class dynamically (can't use game.settings in static DEFAULT_OPTIONS)
|
||||||
|
const theme = game.settings.get("mgt2", "theme");
|
||||||
|
if (theme) this.element.classList.add(theme);
|
||||||
this._activateTabGroups();
|
this._activateTabGroups();
|
||||||
this._bindItemEvents();
|
this._bindItemEvents();
|
||||||
}
|
}
|
||||||
@@ -2878,6 +2755,17 @@ class TravellerItemSheet extends HandlebarsApplicationMixin(foundry.applications
|
|||||||
const preloadHandlebarsTemplates = async function() {
|
const preloadHandlebarsTemplates = async function() {
|
||||||
|
|
||||||
const templatePaths = [
|
const templatePaths = [
|
||||||
|
"systems/mgt2/templates/items/armor-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/career-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/computer-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/contact-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/container-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/disease-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/equipment-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/item-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/species-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/talent-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/weapon-sheet.html",
|
||||||
"systems/mgt2/templates/items/parts/sheet-configuration.html",
|
"systems/mgt2/templates/items/parts/sheet-configuration.html",
|
||||||
"systems/mgt2/templates/items/parts/sheet-physical-item.html",
|
"systems/mgt2/templates/items/parts/sheet-physical-item.html",
|
||||||
"systems/mgt2/templates/roll-prompt.html",
|
"systems/mgt2/templates/roll-prompt.html",
|
||||||
@@ -2887,7 +2775,6 @@ const preloadHandlebarsTemplates = async function() {
|
|||||||
"systems/mgt2/templates/actors/actor-config-characteristic-sheet.html",
|
"systems/mgt2/templates/actors/actor-config-characteristic-sheet.html",
|
||||||
"systems/mgt2/templates/actors/trait-sheet.html",
|
"systems/mgt2/templates/actors/trait-sheet.html",
|
||||||
"systems/mgt2/templates/editor-fullview.html"
|
"systems/mgt2/templates/editor-fullview.html"
|
||||||
//"systems/mgt2/templates/actors/parts/actor-characteristic.html"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
return loadTemplates(templatePaths);
|
return loadTemplates(templatePaths);
|
||||||
@@ -2895,43 +2782,33 @@ const preloadHandlebarsTemplates = async function() {
|
|||||||
|
|
||||||
class ChatHelper {
|
class ChatHelper {
|
||||||
|
|
||||||
|
static setupCardListeners(message, element, messageData) {
|
||||||
// _injectContent(message, type, html) {
|
if (!message || !element) {
|
||||||
|
|
||||||
// _setupCardListeners(message, html);
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
static setupCardListeners(message, html, messageData) {
|
|
||||||
if (!message || !html) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// if (SettingsUtility.getSettingValue(SETTING_NAMES.MANUAL_DAMAGE_MODE) > 0) {
|
element.querySelectorAll('button[data-action="rollDamage"]').forEach(el => {
|
||||||
// html.find('.card-buttons').find(`[data-action='rsr-${ROLL_TYPE.DAMAGE}']`).click(async event => {
|
el.addEventListener('click', async event => {
|
||||||
// await _processDamageButtonEvent(message, event);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
html.find('button[data-action="rollDamage"]').click(async event => {
|
|
||||||
//ui.notifications.warn("rollDamage");
|
|
||||||
await this._processRollDamageButtonEvent(message, event);
|
await this._processRollDamageButtonEvent(message, event);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
html.find('button[data-action="damage"]').click(async event => {
|
element.querySelectorAll('button[data-action="damage"]').forEach(el => {
|
||||||
//ui.notifications.warn("damage");
|
el.addEventListener('click', async event => {
|
||||||
await this._applyChatCardDamage(message, event);
|
await this._applyChatCardDamage(message, event);
|
||||||
//await _processApplyButtonEvent(message, event);
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('button[data-action="healing"]').click(async event => {
|
element.querySelectorAll('button[data-action="healing"]').forEach(el => {
|
||||||
|
el.addEventListener('click', async event => {
|
||||||
ui.notifications.warn("healing");
|
ui.notifications.warn("healing");
|
||||||
//await _processApplyTotalButtonEvent(message, event);
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('button[data-index]').click(async event => {
|
element.querySelectorAll('button[data-index]').forEach(el => {
|
||||||
|
el.addEventListener('click', async event => {
|
||||||
await this._processRollButtonEvent(message, event);
|
await this._processRollButtonEvent(message, event);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static async _processRollButtonEvent(message, event) {
|
static async _processRollButtonEvent(message, event) {
|
||||||
@@ -2940,8 +2817,7 @@ class ChatHelper {
|
|||||||
let buttons = message.flags.mgt2.buttons;
|
let buttons = message.flags.mgt2.buttons;
|
||||||
const index = event.target.dataset.index;
|
const index = event.target.dataset.index;
|
||||||
const button = buttons[index];
|
const button = buttons[index];
|
||||||
let roll = await new Roll(button.formula, {}).roll({ async: true });
|
let roll = await new Roll(button.formula, {}).roll();
|
||||||
//console.log(message);
|
|
||||||
|
|
||||||
const chatData = {
|
const chatData = {
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
@@ -2949,15 +2825,11 @@ class ChatHelper {
|
|||||||
formula: roll._formula,
|
formula: roll._formula,
|
||||||
tooltip: await roll.getTooltip(),
|
tooltip: await roll.getTooltip(),
|
||||||
total: Math.round(roll.total * 100) / 100,
|
total: Math.round(roll.total * 100) / 100,
|
||||||
//formula: isPrivate ? "???" : roll._formula,
|
|
||||||
//tooltip: isPrivate ? "" : await roll.getTooltip(),
|
|
||||||
//total: isPrivate ? "?" : Math.round(roll.total * 100) / 100,
|
|
||||||
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
|
|
||||||
rollObjectName: button.message.objectName,
|
rollObjectName: button.message.objectName,
|
||||||
rollMessage: MGT2Helper.format(button.message.flavor, Math.round(roll.total * 100) / 100),
|
rollMessage: MGT2Helper.format(button.message.flavor, Math.round(roll.total * 100) / 100),
|
||||||
};
|
};
|
||||||
|
|
||||||
const html = await renderTemplate("systems/mgt2/templates/chat/roll.html", chatData);
|
const html = await foundry.applications.handlebars.renderTemplate("systems/mgt2/templates/chat/roll.html", chatData);
|
||||||
chatData.content = html;
|
chatData.content = html;
|
||||||
return roll.toMessage(chatData);
|
return roll.toMessage(chatData);
|
||||||
}
|
}
|
||||||
@@ -2967,7 +2839,7 @@ class ChatHelper {
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
let rollFormula = message.flags.mgt2.damage.formula;
|
let rollFormula = message.flags.mgt2.damage.formula;
|
||||||
|
|
||||||
let roll = await new Roll(rollFormula, {}).roll({ async: true });
|
let roll = await new Roll(rollFormula, {}).roll();
|
||||||
|
|
||||||
let speaker;
|
let speaker;
|
||||||
let selectTokens = canvas.tokens.controlled;
|
let selectTokens = canvas.tokens.controlled;
|
||||||
@@ -2985,30 +2857,18 @@ class ChatHelper {
|
|||||||
formula: roll._formula,
|
formula: roll._formula,
|
||||||
tooltip: await roll.getTooltip(),
|
tooltip: await roll.getTooltip(),
|
||||||
total: Math.round(roll.total * 100) / 100,
|
total: Math.round(roll.total * 100) / 100,
|
||||||
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
|
|
||||||
showButtons: true,
|
showButtons: true,
|
||||||
hasDamage: true,
|
hasDamage: true,
|
||||||
rollTypeName: rollTypeName,
|
rollTypeName: rollTypeName,
|
||||||
rollObjectName: message.flags.mgt2.damage.rollObjectName
|
rollObjectName: message.flags.mgt2.damage.rollObjectName
|
||||||
};
|
};
|
||||||
|
|
||||||
const html = await renderTemplate("systems/mgt2/templates/chat/roll.html", chatData);
|
const html = await foundry.applications.handlebars.renderTemplate("systems/mgt2/templates/chat/roll.html", chatData);
|
||||||
chatData.content = html;
|
chatData.content = html;
|
||||||
|
|
||||||
return roll.toMessage(chatData);
|
return roll.toMessage(chatData);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _processDamageButtonEvent(message, event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
//message.flags[MODULE_SHORT].manualDamage = false
|
|
||||||
//message.flags[MODULE_SHORT].renderDamage = true;
|
|
||||||
// current user/actor
|
|
||||||
|
|
||||||
await ItemUtility.runItemAction(null, message, ROLL_TYPE.DAMAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static _applyChatCardDamage(message, event) {
|
static _applyChatCardDamage(message, event) {
|
||||||
const roll = message.rolls[0];
|
const roll = message.rolls[0];
|
||||||
return Promise.all(canvas.tokens.controlled.map(t => {
|
return Promise.all(canvas.tokens.controlled.map(t => {
|
||||||
@@ -3193,8 +3053,8 @@ Hooks.once("init", async function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Hooks.on("renderChatMessage", (message, html, messageData) => {
|
Hooks.on("renderChatMessageHTML", (message, element, messageData) => {
|
||||||
ChatHelper.setupCardListeners(message, html, messageData);
|
ChatHelper.setupCardListeners(message, element, messageData);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Preload template partials
|
// Preload template partials
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,153 +1,73 @@
|
|||||||
class EditorFullViewDialog extends Dialog {
|
const { DialogV2 } = foundry.applications.api;
|
||||||
constructor(dialogData = {}, options = {}) {
|
const { renderTemplate } = foundry.applications.handlebars;
|
||||||
super(dialogData, options);
|
const { FormDataExtended } = foundry.applications.ux;
|
||||||
this.options.classes = ["mgt2", game.settings.get("mgt2", "theme"), "sheet"];
|
|
||||||
this.options.resizable = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async create(title, html) {
|
async function _dialogWithForm(title, templatePath, templateData) {
|
||||||
const htmlContent = await renderTemplate("systems/mgt2/templates/editor-fullview.html", {
|
const htmlContent = await renderTemplate(templatePath, templateData);
|
||||||
config: CONFIG.MGT2,
|
const theme = game.settings.get("mgt2", "theme");
|
||||||
html: html
|
return await DialogV2.wait({
|
||||||
});
|
window: { title },
|
||||||
|
|
||||||
const results = new Promise(resolve => {
|
|
||||||
new this({
|
|
||||||
title: title,
|
|
||||||
content: htmlContent,
|
content: htmlContent,
|
||||||
buttons: {
|
rejectClose: false,
|
||||||
//close: { label: game.i18n.localize("MGT2.Close") }
|
buttons: [
|
||||||
}
|
{
|
||||||
}).render(true);
|
action: "submit",
|
||||||
});
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ActorConfigDialog extends Dialog {
|
|
||||||
constructor(dialogData = {}, options = {}) {
|
|
||||||
super(dialogData, options);
|
|
||||||
this.options.classes = ["mgt2", game.settings.get("mgt2", "theme"), "sheet"];
|
|
||||||
}
|
|
||||||
|
|
||||||
static async create(system) {
|
|
||||||
const htmlContent = await renderTemplate("systems/mgt2/templates/actors/actor-config-sheet.html", {
|
|
||||||
config: CONFIG.MGT2,
|
|
||||||
system: system
|
|
||||||
});
|
|
||||||
|
|
||||||
const results = new Promise(resolve => {
|
|
||||||
new this({
|
|
||||||
title: "Configuration",
|
|
||||||
content: htmlContent,
|
|
||||||
buttons: {
|
|
||||||
submit: {
|
|
||||||
label: game.i18n.localize("MGT2.Save"),
|
label: game.i18n.localize("MGT2.Save"),
|
||||||
icon: '<i class="fa-solid fa-floppy-disk"></i>',
|
icon: '<i class="fa-solid fa-floppy-disk"></i>',
|
||||||
callback: (html) => {
|
default: true,
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
callback: (event, button, dialog) => {
|
||||||
resolve(formData);
|
return new FormDataExtended(dialog.element.querySelector('form')).object;
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).render(true);
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ActorCharacteristicDialog extends Dialog {
|
|
||||||
// https://foundryvtt.wiki/en/development/api/dialog
|
|
||||||
constructor(dialogData = {}, options = {}) {
|
|
||||||
super(dialogData, options);
|
|
||||||
this.options.classes = ["mgt2", game.settings.get("mgt2", "theme"), "sheet"];
|
|
||||||
}
|
|
||||||
|
|
||||||
static async create(name, show, showMax, showAll = false) {
|
|
||||||
const htmlContent = await renderTemplate("systems/mgt2/templates/actors/actor-config-characteristic-sheet.html", {
|
|
||||||
name: name,
|
|
||||||
show: show,
|
|
||||||
showMax: showMax,
|
|
||||||
showAll: showAll
|
|
||||||
});
|
|
||||||
|
|
||||||
const results = new Promise(resolve => {
|
|
||||||
new this({
|
|
||||||
title: "Configuration: " + name,
|
|
||||||
content: htmlContent,
|
|
||||||
buttons: {
|
|
||||||
submit: {
|
|
||||||
label: game.i18n.localize("MGT2.Save"),
|
|
||||||
icon: '<i class="fa-solid fa-floppy-disk"></i>',
|
|
||||||
callback: (html) => {
|
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
|
||||||
resolve(formData);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).render(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TraitEditDialog extends Dialog {
|
|
||||||
constructor(dialogData = {}, options = {}) {
|
|
||||||
super(dialogData, options);
|
|
||||||
this.options.classes = ["mgt2", game.settings.get("mgt2", "theme"), "sheet"];
|
|
||||||
}
|
|
||||||
|
|
||||||
static async create(data) {
|
|
||||||
const htmlContent = await renderTemplate("systems/mgt2/templates/actors/trait-sheet.html", {
|
|
||||||
config: CONFIG.MGT2,
|
|
||||||
data: data
|
|
||||||
});
|
|
||||||
const title = data.hasOwnProperty("name") && data.name !== undefined ? data.name : game.i18n.localize("MGT2.Actor.EditTrait");
|
|
||||||
const results = new Promise(resolve => {
|
|
||||||
new this({
|
|
||||||
title: title,
|
|
||||||
content: htmlContent,
|
|
||||||
buttons: {
|
|
||||||
submit: {
|
|
||||||
label: game.i18n.localize("MGT2.Save"),
|
|
||||||
icon: '<i class="fa-solid fa-floppy-disk"></i>',
|
|
||||||
callback: (html) => {
|
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
|
||||||
resolve(formData);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
//cancel: { label: "Cancel" }
|
|
||||||
}
|
|
||||||
// close: (html) => {
|
|
||||||
// console.log("This always is logged no matter which option is chosen");
|
|
||||||
// const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
|
||||||
// resolve(formData);
|
|
||||||
// }
|
|
||||||
}).render(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CharacterPrompts {
|
export class CharacterPrompts {
|
||||||
|
|
||||||
static async openConfig(system) {
|
static async openConfig(system) {
|
||||||
return await ActorConfigDialog.create(system);
|
return _dialogWithForm(
|
||||||
|
"Configuration",
|
||||||
|
"systems/mgt2/templates/actors/actor-config-sheet.html",
|
||||||
|
{ config: CONFIG.MGT2, system }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async openCharacteristic(name, hide, showMax, showAll = false) {
|
static async openCharacteristic(name, show, showMax, showAll = false) {
|
||||||
return await ActorCharacteristicDialog.create(name, hide, showMax, showAll);
|
return _dialogWithForm(
|
||||||
|
"Configuration: " + name,
|
||||||
|
"systems/mgt2/templates/actors/actor-config-characteristic-sheet.html",
|
||||||
|
{ name, show, showMax, showAll }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async openTraitEdit(data) {
|
static async openTraitEdit(data) {
|
||||||
return await TraitEditDialog.create(data);
|
const title = data.name ?? game.i18n.localize("MGT2.Actor.EditTrait");
|
||||||
|
return _dialogWithForm(
|
||||||
|
title,
|
||||||
|
"systems/mgt2/templates/actors/trait-sheet.html",
|
||||||
|
{ config: CONFIG.MGT2, data }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async openEditorFullView(title, html) {
|
static async openEditorFullView(title, html) {
|
||||||
return await EditorFullViewDialog.create(title, html);
|
const htmlContent = await renderTemplate("systems/mgt2/templates/editor-fullview.html", {
|
||||||
|
config: CONFIG.MGT2,
|
||||||
|
html
|
||||||
|
});
|
||||||
|
const theme = game.settings.get("mgt2", "theme");
|
||||||
|
await DialogV2.wait({
|
||||||
|
window: { title },
|
||||||
|
content: htmlContent,
|
||||||
|
rejectClose: false,
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
action: "close",
|
||||||
|
label: game.i18n.localize("MGT2.Close") || "Fermer",
|
||||||
|
default: true,
|
||||||
|
callback: () => null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,12 +138,11 @@ export class ActorCharacter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (recalculEncumbrance || recalculWeight) {
|
if (recalculEncumbrance || recalculWeight) {
|
||||||
const cloneActor = foundry.utils.deepClone($this);
|
const updateData = {};
|
||||||
|
|
||||||
await this.recalculateArmor($this, cloneActor);
|
this.recalculateArmor($this, updateData);
|
||||||
|
|
||||||
if (recalculEncumbrance) {
|
if (recalculEncumbrance) {
|
||||||
//console.log("recalculEncumbrance");
|
|
||||||
const str = $this.system.characteristics.strength.value;
|
const str = $this.system.characteristics.strength.value;
|
||||||
const end = $this.system.characteristics.endurance.value;
|
const end = $this.system.characteristics.endurance.value;
|
||||||
let sumSkill = 0;
|
let sumSkill = 0;
|
||||||
@@ -151,19 +150,21 @@ export class ActorCharacter {
|
|||||||
let normal = str + end + sumSkill;
|
let normal = str + end + sumSkill;
|
||||||
let heavy = normal * 2;
|
let heavy = normal * 2;
|
||||||
|
|
||||||
cloneActor.system.states.encumbrance = $this.system.inventory.weight > normal;
|
updateData["system.states.encumbrance"] = $this.system.inventory.weight > normal;
|
||||||
cloneActor.system.encumbrance.normal = normal;
|
updateData["system.inventory.encumbrance.normal"] = normal;
|
||||||
cloneActor.system.encumbrance.heavy = heavy;
|
updateData["system.inventory.encumbrance.heavy"] = heavy;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recalculWeight)
|
if (recalculWeight)
|
||||||
await this.recalculateWeight($this, cloneActor);
|
await this.recalculateWeight($this, updateData);
|
||||||
|
else if (Object.keys(updateData).length > 0)
|
||||||
|
await $this.update(updateData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async recalculateArmor($this, cloneActor) {
|
static recalculateArmor($this, updateData) {
|
||||||
if (cloneActor === null || cloneActor === undefined)
|
if (updateData === null || updateData === undefined)
|
||||||
cloneActor = foundry.utils.deepClone($this);
|
updateData = {};
|
||||||
|
|
||||||
let armor = 0;
|
let armor = 0;
|
||||||
for (let item of $this.items) {
|
for (let item of $this.items) {
|
||||||
@@ -174,18 +175,18 @@ export class ActorCharacter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cloneActor.system.inventory.armor = armor;
|
updateData["system.inventory.armor"] = armor;
|
||||||
|
return updateData;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async recalculateWeight($this, cloneActor) {
|
static async recalculateWeight($this, updateData) {
|
||||||
|
|
||||||
if (cloneActor === null || cloneActor === undefined)
|
if (updateData === null || updateData === undefined)
|
||||||
cloneActor = foundry.utils.deepClone($this);
|
updateData = {};
|
||||||
|
|
||||||
let updatedContainers = [];
|
let updatedContainers = [];
|
||||||
let containerChanges = {};
|
let containerChanges = {};
|
||||||
|
|
||||||
//console.log("recalculWeight");
|
|
||||||
let containers = [];
|
let containers = [];
|
||||||
|
|
||||||
// List all containers
|
// List all containers
|
||||||
@@ -205,7 +206,7 @@ export class ActorCharacter {
|
|||||||
|
|
||||||
let itemWeight = 0;
|
let itemWeight = 0;
|
||||||
if (item.system.hasOwnProperty("weight")) {
|
if (item.system.hasOwnProperty("weight")) {
|
||||||
let itemQty = item.system.quantity
|
let itemQty = item.system.quantity;
|
||||||
if (!isNaN(itemQty) && itemQty > 0) {
|
if (!isNaN(itemQty) && itemQty > 0) {
|
||||||
itemWeight = item.system.weight;
|
itemWeight = item.system.weight;
|
||||||
if (itemWeight > 0) {
|
if (itemWeight > 0) {
|
||||||
@@ -234,19 +235,16 @@ export class ActorCharacter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//cloneActor.system.inventory.weight = onHandWeight.toFixed(1);
|
|
||||||
|
|
||||||
// Check containers new weight
|
// Check containers new weight
|
||||||
for (let container of containers) {
|
for (let container of containers) {
|
||||||
let newWeight = containerChanges[container._id].weight;
|
let newWeight = containerChanges[container._id].weight;
|
||||||
let newCount = containerChanges[container._id].count;
|
let newCount = containerChanges[container._id].count;
|
||||||
if (container.system.weight !== newWeight || container.system.count !== newCount) {
|
if (container.system.weight !== newWeight || container.system.count !== newCount) {
|
||||||
//const cloneContainer = foundry.utils.deepClone();
|
updatedContainers.push({
|
||||||
const cloneContainer = foundry.utils.deepClone($this.getEmbeddedDocument("Item", container._id));
|
_id: container._id,
|
||||||
//foundry.utils.setProperty(cloneContainer, "system.weight", newWeight);
|
"system.weight": newWeight,
|
||||||
cloneContainer.system.weight = newWeight;
|
"system.count": newCount,
|
||||||
cloneContainer.system.count = newCount;
|
});
|
||||||
updatedContainers.push(cloneContainer);
|
|
||||||
|
|
||||||
if (container.system.onHand === true &&
|
if (container.system.onHand === true &&
|
||||||
(container.system.weight > 0 || container.system.weightless !== true)) {
|
(container.system.weight > 0 || container.system.weightless !== true)) {
|
||||||
@@ -255,11 +253,10 @@ export class ActorCharacter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cloneActor.system.inventory.weight = onHandWeight;
|
updateData["system.inventory.weight"] = onHandWeight;
|
||||||
cloneActor.system.states.encumbrance = onHandWeight > $this.system.inventory.encumbrance.normal;
|
updateData["system.states.encumbrance"] = onHandWeight > $this.system.inventory.encumbrance.normal;
|
||||||
|
|
||||||
|
await $this.update(updateData);
|
||||||
await $this.update(cloneActor);
|
|
||||||
|
|
||||||
if (updatedContainers.length > 0) {
|
if (updatedContainers.length > 0) {
|
||||||
await $this.updateEmbeddedDocuments('Item', updatedContainers);
|
await $this.updateEmbeddedDocuments('Item', updatedContainers);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ export default class MGT2ActorSheet extends HandlebarsApplicationMixin(foundry.a
|
|||||||
return this._sheetMode === this.constructor.SHEET_MODES.EDIT;
|
return this._sheetMode === this.constructor.SHEET_MODES.EDIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
tabGroups = { primary: "stats" }
|
tabGroups = { sidebar: "health" }
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
async _prepareContext() {
|
async _prepareContext() {
|
||||||
@@ -66,6 +66,9 @@ export default class MGT2ActorSheet extends HandlebarsApplicationMixin(foundry.a
|
|||||||
/** @override */
|
/** @override */
|
||||||
_onRender(context, options) {
|
_onRender(context, options) {
|
||||||
super._onRender(context, options);
|
super._onRender(context, options);
|
||||||
|
// Inject theme class dynamically (can't use game.settings in static DEFAULT_OPTIONS)
|
||||||
|
const theme = game.settings.get("mgt2", "theme");
|
||||||
|
if (theme) this.element.classList.add(theme);
|
||||||
this._activateTabGroups();
|
this._activateTabGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export default class TravellerCharacterSheet extends MGT2ActorSheet {
|
|||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
tabGroups = {
|
tabGroups = {
|
||||||
primary: "inventory",
|
sidebar: "inventory",
|
||||||
characteristics: "core",
|
characteristics: "core",
|
||||||
inventory: "onhand",
|
inventory: "onhand",
|
||||||
}
|
}
|
||||||
@@ -721,7 +721,7 @@ export default class TravellerCharacterSheet extends MGT2ActorSheet {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let roll = await new Roll(rollFormula, this.actor.getRollData()).roll({ async: true, rollMode: userRollData.rollMode });
|
let roll = await new Roll(rollFormula, this.actor.getRollData()).roll({ rollMode: userRollData.rollMode });
|
||||||
|
|
||||||
if (isInitiative && this.token?.combatant) {
|
if (isInitiative && this.token?.combatant) {
|
||||||
await this.token.combatant.update({ initiative: roll.total });
|
await this.token.combatant.update({ initiative: roll.total });
|
||||||
@@ -733,7 +733,6 @@ export default class TravellerCharacterSheet extends MGT2ActorSheet {
|
|||||||
formula: roll._formula,
|
formula: roll._formula,
|
||||||
tooltip: await roll.getTooltip(),
|
tooltip: await roll.getTooltip(),
|
||||||
total: Math.round(roll.total * 100) / 100,
|
total: Math.round(roll.total * 100) / 100,
|
||||||
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
|
|
||||||
showButtons: true,
|
showButtons: true,
|
||||||
showLifeButtons: false,
|
showLifeButtons: false,
|
||||||
showRollRequest: false,
|
showRollRequest: false,
|
||||||
@@ -753,7 +752,7 @@ export default class TravellerCharacterSheet extends MGT2ActorSheet {
|
|||||||
chatData.rollFailure = true;
|
chatData.rollFailure = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const html = await renderTemplate("systems/mgt2/templates/chat/roll.html", chatData);
|
const html = await foundry.applications.handlebars.renderTemplate("systems/mgt2/templates/chat/roll.html", chatData);
|
||||||
chatData.content = html;
|
chatData.content = html;
|
||||||
|
|
||||||
let flags = null;
|
let flags = null;
|
||||||
|
|||||||
@@ -22,12 +22,14 @@ export default class TravellerItemSheet extends HandlebarsApplicationMixin(found
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @override */
|
/** Dynamic PARTS: template resolved per item type */
|
||||||
static PARTS = {
|
get PARTS() {
|
||||||
|
const type = this.document?.type ?? "item";
|
||||||
|
return {
|
||||||
sheet: {
|
sheet: {
|
||||||
// template is dynamic — resolved in _prepareContext / _renderHTML
|
template: `systems/mgt2/templates/items/${type}-sheet.html`,
|
||||||
template: "",
|
|
||||||
},
|
},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resolve template dynamically based on item type */
|
/** Resolve template dynamically based on item type */
|
||||||
@@ -81,7 +83,7 @@ export default class TravellerItemSheet extends HandlebarsApplicationMixin(found
|
|||||||
systemFields: item.system.schema.fields,
|
systemFields: item.system.schema.fields,
|
||||||
isEditable: this.isEditable,
|
isEditable: this.isEditable,
|
||||||
isGM: game.user.isGM,
|
isGM: game.user.isGM,
|
||||||
config: CONFIG,
|
config: CONFIG.MGT2,
|
||||||
settings: settings,
|
settings: settings,
|
||||||
containers: containers,
|
containers: containers,
|
||||||
computers: computers,
|
computers: computers,
|
||||||
@@ -95,13 +97,16 @@ export default class TravellerItemSheet extends HandlebarsApplicationMixin(found
|
|||||||
/** @override — resolve the per-type template before rendering */
|
/** @override — resolve the per-type template before rendering */
|
||||||
async _renderHTML(context, options) {
|
async _renderHTML(context, options) {
|
||||||
const templatePath = `systems/mgt2/templates/items/${this.document.type}-sheet.html`;
|
const templatePath = `systems/mgt2/templates/items/${this.document.type}-sheet.html`;
|
||||||
const html = await renderTemplate(templatePath, context);
|
const html = await foundry.applications.handlebars.renderTemplate(templatePath, context);
|
||||||
return { sheet: html };
|
return { sheet: html };
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @override — put rendered HTML into the window content */
|
/** @override — put rendered HTML into the window content */
|
||||||
_replaceHTML(result, content, options) {
|
_replaceHTML(result, content, options) {
|
||||||
content.innerHTML = result.sheet;
|
content.innerHTML = result.sheet;
|
||||||
|
// Inject theme class dynamically (can't use game.settings in static DEFAULT_OPTIONS)
|
||||||
|
const theme = game.settings.get("mgt2", "theme");
|
||||||
|
if (theme) this.element.classList.add(theme);
|
||||||
this._activateTabGroups();
|
this._activateTabGroups();
|
||||||
this._bindItemEvents();
|
this._bindItemEvents();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,43 +2,33 @@ import { MGT2Helper } from "./helper.js";
|
|||||||
|
|
||||||
export class ChatHelper {
|
export class ChatHelper {
|
||||||
|
|
||||||
|
static setupCardListeners(message, element, messageData) {
|
||||||
// _injectContent(message, type, html) {
|
if (!message || !element) {
|
||||||
|
|
||||||
// _setupCardListeners(message, html);
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
static setupCardListeners(message, html, messageData) {
|
|
||||||
if (!message || !html) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// if (SettingsUtility.getSettingValue(SETTING_NAMES.MANUAL_DAMAGE_MODE) > 0) {
|
element.querySelectorAll('button[data-action="rollDamage"]').forEach(el => {
|
||||||
// html.find('.card-buttons').find(`[data-action='rsr-${ROLL_TYPE.DAMAGE}']`).click(async event => {
|
el.addEventListener('click', async event => {
|
||||||
// await _processDamageButtonEvent(message, event);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
html.find('button[data-action="rollDamage"]').click(async event => {
|
|
||||||
//ui.notifications.warn("rollDamage");
|
|
||||||
await this._processRollDamageButtonEvent(message, event);
|
await this._processRollDamageButtonEvent(message, event);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
html.find('button[data-action="damage"]').click(async event => {
|
element.querySelectorAll('button[data-action="damage"]').forEach(el => {
|
||||||
//ui.notifications.warn("damage");
|
el.addEventListener('click', async event => {
|
||||||
await this._applyChatCardDamage(message, event);
|
await this._applyChatCardDamage(message, event);
|
||||||
//await _processApplyButtonEvent(message, event);
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('button[data-action="healing"]').click(async event => {
|
element.querySelectorAll('button[data-action="healing"]').forEach(el => {
|
||||||
|
el.addEventListener('click', async event => {
|
||||||
ui.notifications.warn("healing");
|
ui.notifications.warn("healing");
|
||||||
//await _processApplyTotalButtonEvent(message, event);
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
html.find('button[data-index]').click(async event => {
|
element.querySelectorAll('button[data-index]').forEach(el => {
|
||||||
|
el.addEventListener('click', async event => {
|
||||||
await this._processRollButtonEvent(message, event);
|
await this._processRollButtonEvent(message, event);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static async _processRollButtonEvent(message, event) {
|
static async _processRollButtonEvent(message, event) {
|
||||||
@@ -47,8 +37,7 @@ export class ChatHelper {
|
|||||||
let buttons = message.flags.mgt2.buttons;
|
let buttons = message.flags.mgt2.buttons;
|
||||||
const index = event.target.dataset.index;
|
const index = event.target.dataset.index;
|
||||||
const button = buttons[index];
|
const button = buttons[index];
|
||||||
let roll = await new Roll(button.formula, {}).roll({ async: true });
|
let roll = await new Roll(button.formula, {}).roll();
|
||||||
//console.log(message);
|
|
||||||
|
|
||||||
const chatData = {
|
const chatData = {
|
||||||
user: game.user.id,
|
user: game.user.id,
|
||||||
@@ -56,15 +45,11 @@ export class ChatHelper {
|
|||||||
formula: roll._formula,
|
formula: roll._formula,
|
||||||
tooltip: await roll.getTooltip(),
|
tooltip: await roll.getTooltip(),
|
||||||
total: Math.round(roll.total * 100) / 100,
|
total: Math.round(roll.total * 100) / 100,
|
||||||
//formula: isPrivate ? "???" : roll._formula,
|
|
||||||
//tooltip: isPrivate ? "" : await roll.getTooltip(),
|
|
||||||
//total: isPrivate ? "?" : Math.round(roll.total * 100) / 100,
|
|
||||||
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
|
|
||||||
rollObjectName: button.message.objectName,
|
rollObjectName: button.message.objectName,
|
||||||
rollMessage: MGT2Helper.format(button.message.flavor, Math.round(roll.total * 100) / 100),
|
rollMessage: MGT2Helper.format(button.message.flavor, Math.round(roll.total * 100) / 100),
|
||||||
};
|
};
|
||||||
|
|
||||||
const html = await renderTemplate("systems/mgt2/templates/chat/roll.html", chatData);
|
const html = await foundry.applications.handlebars.renderTemplate("systems/mgt2/templates/chat/roll.html", chatData);
|
||||||
chatData.content = html;
|
chatData.content = html;
|
||||||
return roll.toMessage(chatData);
|
return roll.toMessage(chatData);
|
||||||
}
|
}
|
||||||
@@ -74,7 +59,7 @@ export class ChatHelper {
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
let rollFormula = message.flags.mgt2.damage.formula;
|
let rollFormula = message.flags.mgt2.damage.formula;
|
||||||
|
|
||||||
let roll = await new Roll(rollFormula, {}).roll({ async: true });
|
let roll = await new Roll(rollFormula, {}).roll();
|
||||||
|
|
||||||
let speaker;
|
let speaker;
|
||||||
let selectTokens = canvas.tokens.controlled;
|
let selectTokens = canvas.tokens.controlled;
|
||||||
@@ -92,30 +77,18 @@ export class ChatHelper {
|
|||||||
formula: roll._formula,
|
formula: roll._formula,
|
||||||
tooltip: await roll.getTooltip(),
|
tooltip: await roll.getTooltip(),
|
||||||
total: Math.round(roll.total * 100) / 100,
|
total: Math.round(roll.total * 100) / 100,
|
||||||
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
|
|
||||||
showButtons: true,
|
showButtons: true,
|
||||||
hasDamage: true,
|
hasDamage: true,
|
||||||
rollTypeName: rollTypeName,
|
rollTypeName: rollTypeName,
|
||||||
rollObjectName: message.flags.mgt2.damage.rollObjectName
|
rollObjectName: message.flags.mgt2.damage.rollObjectName
|
||||||
};
|
};
|
||||||
|
|
||||||
const html = await renderTemplate("systems/mgt2/templates/chat/roll.html", chatData);
|
const html = await foundry.applications.handlebars.renderTemplate("systems/mgt2/templates/chat/roll.html", chatData);
|
||||||
chatData.content = html;
|
chatData.content = html;
|
||||||
|
|
||||||
return roll.toMessage(chatData);
|
return roll.toMessage(chatData);
|
||||||
}
|
}
|
||||||
|
|
||||||
async _processDamageButtonEvent(message, event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
//message.flags[MODULE_SHORT].manualDamage = false
|
|
||||||
//message.flags[MODULE_SHORT].renderDamage = true;
|
|
||||||
// current user/actor
|
|
||||||
|
|
||||||
await ItemUtility.runItemAction(null, message, ROLL_TYPE.DAMAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static _applyChatCardDamage(message, event) {
|
static _applyChatCardDamage(message, event) {
|
||||||
const roll = message.rolls[0];
|
const roll = message.rolls[0];
|
||||||
return Promise.all(canvas.tokens.controlled.map(t => {
|
return Promise.all(canvas.tokens.controlled.map(t => {
|
||||||
|
|||||||
@@ -115,8 +115,8 @@ Hooks.once("init", async function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Hooks.on("renderChatMessage", (message, html, messageData) => {
|
Hooks.on("renderChatMessageHTML", (message, element, messageData) => {
|
||||||
ChatHelper.setupCardListeners(message, html, messageData);
|
ChatHelper.setupCardListeners(message, element, messageData);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Preload template partials
|
// Preload template partials
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
class RollPromptDialog extends Dialog {
|
const { DialogV2 } = foundry.applications.api;
|
||||||
constructor(dialogData = {}, options = {}) {
|
const { renderTemplate } = foundry.applications.handlebars;
|
||||||
super(dialogData, options);
|
const { FormDataExtended } = foundry.applications.ux;
|
||||||
this.options.classes = ["mgt2", game.settings.get("mgt2", "theme"), "sheet", "dialog"];
|
|
||||||
}
|
|
||||||
|
|
||||||
static async create(options) {
|
export class RollPromptHelper {
|
||||||
|
|
||||||
|
static async roll(options) {
|
||||||
const htmlContent = await renderTemplate('systems/mgt2/templates/roll-prompt.html', {
|
const htmlContent = await renderTemplate('systems/mgt2/templates/roll-prompt.html', {
|
||||||
config: CONFIG.MGT2,
|
config: CONFIG.MGT2,
|
||||||
//formula: formula,
|
|
||||||
characteristics: options.characteristics,
|
characteristics: options.characteristics,
|
||||||
characteristic: options.characteristic,
|
characteristic: options.characteristic,
|
||||||
skills: options.skills,
|
skills: options.skills,
|
||||||
@@ -18,86 +16,41 @@ class RollPromptDialog extends Dialog {
|
|||||||
difficulty: options.difficulty
|
difficulty: options.difficulty
|
||||||
});
|
});
|
||||||
|
|
||||||
const results = new Promise(resolve => {
|
const theme = game.settings.get("mgt2", "theme");
|
||||||
new this({
|
|
||||||
title: options.title,
|
return await DialogV2.wait({
|
||||||
|
window: { title: options.title ?? options.rollTypeName ?? game.i18n.localize("MGT2.RollPrompt.Roll") },
|
||||||
content: htmlContent,
|
content: htmlContent,
|
||||||
buttons: {
|
rejectClose: false,
|
||||||
boon: {
|
buttons: [
|
||||||
|
{
|
||||||
|
action: "boon",
|
||||||
label: game.i18n.localize("MGT2.RollPrompt.Boon"),
|
label: game.i18n.localize("MGT2.RollPrompt.Boon"),
|
||||||
callback: (html) => {
|
callback: (event, button, dialog) => {
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
const formData = new FormDataExtended(dialog.element.querySelector('form')).object;
|
||||||
formData.diceModifier = "dl";
|
formData.diceModifier = "dl";
|
||||||
resolve(formData);
|
return formData;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
submit: {
|
{
|
||||||
|
action: "submit",
|
||||||
label: game.i18n.localize("MGT2.RollPrompt.Roll"),
|
label: game.i18n.localize("MGT2.RollPrompt.Roll"),
|
||||||
icon: '<i class="fa-solid fa-dice"></i>',
|
icon: '<i class="fa-solid fa-dice"></i>',
|
||||||
callback: (html) => {
|
default: true,
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
callback: (event, button, dialog) => {
|
||||||
resolve(formData);
|
return new FormDataExtended(dialog.element.querySelector('form')).object;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
bane: {
|
action: "bane",
|
||||||
label: game.i18n.localize("MGT2.RollPrompt.Bane"),
|
label: game.i18n.localize("MGT2.RollPrompt.Bane"),
|
||||||
//icon: '<i class="fa-solid fa-dice"></i>',
|
callback: (event, button, dialog) => {
|
||||||
callback: (html) => {
|
const formData = new FormDataExtended(dialog.element.querySelector('form')).object;
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form')).object;
|
|
||||||
formData.diceModifier = "dh";
|
formData.diceModifier = "dh";
|
||||||
resolve(formData);
|
return formData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
//close: () => { resolve(false) }
|
|
||||||
}).render(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
//console.log(Promise.resolve(results));
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class RollPromptHelper {
|
|
||||||
|
|
||||||
static async roll(options) {
|
|
||||||
return await RollPromptDialog.create(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
static async promptForFruitTraits() {
|
|
||||||
const htmlContent = await renderTemplate('systems/mgt2/templateschat/chat/roll-prompt.html');
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const dialog = new Dialog({
|
|
||||||
title: "Fruit Traits",
|
|
||||||
content: htmlContent,
|
|
||||||
buttons: {
|
|
||||||
submit: {
|
|
||||||
label: "Roll",
|
|
||||||
icon: '<i class="fa-solid fa-dice"></i>',
|
|
||||||
callback: (html) => {
|
|
||||||
const formData = new FormDataExtended(html[0].querySelector('form'))
|
|
||||||
.toObject();
|
|
||||||
|
|
||||||
//verifyFruitInputs(formData);
|
|
||||||
|
|
||||||
resolve(formData);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
skip: {
|
|
||||||
label: "Cancel",
|
|
||||||
callback: () => resolve(null),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
render: (html) => {
|
|
||||||
//html.on('click', 'button[data-preset]', handleFruitPreset);
|
|
||||||
},
|
|
||||||
close: () => {
|
|
||||||
reject('User closed dialog without making a selection.');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
dialog.render(true);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,17 @@
|
|||||||
export const preloadHandlebarsTemplates = async function() {
|
export const preloadHandlebarsTemplates = async function() {
|
||||||
|
|
||||||
const templatePaths = [
|
const templatePaths = [
|
||||||
|
"systems/mgt2/templates/items/armor-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/career-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/computer-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/contact-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/container-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/disease-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/equipment-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/item-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/species-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/talent-sheet.html",
|
||||||
|
"systems/mgt2/templates/items/weapon-sheet.html",
|
||||||
"systems/mgt2/templates/items/parts/sheet-configuration.html",
|
"systems/mgt2/templates/items/parts/sheet-configuration.html",
|
||||||
"systems/mgt2/templates/items/parts/sheet-physical-item.html",
|
"systems/mgt2/templates/items/parts/sheet-physical-item.html",
|
||||||
"systems/mgt2/templates/roll-prompt.html",
|
"systems/mgt2/templates/roll-prompt.html",
|
||||||
@@ -15,7 +26,6 @@ export const preloadHandlebarsTemplates = async function() {
|
|||||||
"systems/mgt2/templates/actors/actor-config-characteristic-sheet.html",
|
"systems/mgt2/templates/actors/actor-config-characteristic-sheet.html",
|
||||||
"systems/mgt2/templates/actors/trait-sheet.html",
|
"systems/mgt2/templates/actors/trait-sheet.html",
|
||||||
"systems/mgt2/templates/editor-fullview.html"
|
"systems/mgt2/templates/editor-fullview.html"
|
||||||
//"systems/mgt2/templates/actors/parts/actor-characteristic.html"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
return loadTemplates(templatePaths);
|
return loadTemplates(templatePaths);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
&.window-title
|
&.window-title
|
||||||
font-weight: bold
|
font-weight: bold
|
||||||
text-transform: uppercase
|
text-transform: uppercase
|
||||||
&.window-app
|
&.sheet
|
||||||
.window-content
|
.window-content
|
||||||
background: var(--mgt2-bgcolor-form)
|
background: var(--mgt2-bgcolor-form)
|
||||||
padding: 0
|
padding: 0
|
||||||
|
|||||||
1026
styles/mgt2.min.css
vendored
1026
styles/mgt2.min.css
vendored
File diff suppressed because one or more lines are too long
1
styles/mgt2.min.css.map
Normal file
1
styles/mgt2.min.css.map
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"sourceRoot":"","sources":["../src/sass/utils/_typography.sass","../src/sass/utils/_colors.sass","../src/sass/utils/_global.sass","../src/sass/utils/_window.sass","../src/sass/utils/_flex.sass","../src/sass/components/_forms.sass","../src/sass/components/_dialog.sass","../src/sass/components/_character.sass","../src/sass/components/_item.sass","../src/sass/components/_chat-sidebar.sass","../src/sass/components/_tabs.sass","../src/sass/components/_tab-sidebar.sass","../src/sass/components/_tables.sass"],"names":[],"mappings":"AAAQ,sMACA,qGACA,0HCGR,eACI,2BACA,0BACA,8BACA,qCACA,gCACA,oCACA,8BACA,sBACA,2BACA,4BACA,iCACA,4BACA,2BACA,8BACA,0BACA,6BACA,kCACA,mCACA,kCAEJ,QACI,2BACA,0BACA,8BACA,qCACA,gCACA,oCACA,8BACA,sBACA,2BACA,4BACA,iCACA,4BACA,2BACA,8BACA,0BACA,6BACA,kCAEJ,MACI,2BACA,0BACA,8BACA,qCACA,gCACA,oCACA,8BACA,sBACA,2BACA,4BACA,iCACA,4BACA,2BACA,8BACA,0BACA,6BACA,kCC9DJ,QACC,yBAED,OACC,UAED,OACC,UAED,OACC,UAED,OACC,UAED,OACC,UAED,MACC,YAED,MACC,WAGA,cACC,iBAED,aACC,WAED,YACC,kBAED,yBACC,eAED,YACC,gBCnCC,iCACC,gCACA,6CAED,4BACC,iBACA,yBAEF,4BACC,oCACA,UAGF,uBACC,UChBD,gBACC,uBACA,yBACD,qBACC,eACD,qBACC,eACD,qBACC,eACD,qBACC,eACD,qBACC,eACD,qBACC,eACD,qBACC,eCfA,qBACC,8BACA,2CACA,gCACA,eACA,kBAEF,0DAGC,aACA,gBAED,sBACC,qBACA,sBACA,uBACA,oBAED,cACC,gCACA,uCACA,eACA,0CACA,iBACA,iBACA,kBACA,iBACA,yBAED,oBACC,aACA,mBACA,iBACA,mBACA,8BAGA,yBACC,yBACA,gBACA,eACA,0CACA,yBAED,kBACC,2CACA,eACD,uBACC,2CACA,eACA,YACA,gBACA,0CACA,oBACA,UACD,4BACC,2CACA,YACA,eACA,gBACA,0CAEF,cACC,aAED,cACC,gBACA,2CACA,YAED,kBACC,kBACA,sBAGA,0BACC,aACA,mBACA,mBACA,gCACC,mBClFH,qBACC,gCACA,wDCFD,4BACC,YAEF,SACC,eACA,uBACA,mBACA,WACC,kBAGD,uBACC,iBACA,YACA,cACA,kBAED,8BACC,gCACA,uCACA,8BACA,kBACA,eACA,iBACA,yBAED,0BACC,aACA,mBACA,mBACA,uBACA,kBAED,6BACC,aACA,mBACA,mBACA,uBACA,iBAIC,oCACC,gBACA,gBAEH,4BACC,0CACA,iBACA,gBACA,kBACA,kBACA,kBAEC,mCACC,WACA,kBACA,OAED,iDACC,aACA,eACA,kBACA,QACA,MAGA,uDACC,cAEJ,4BACC,kCACA,kBACA,iBACA,gBACA,aACA,YACA,sBACA,YACA,aACA,2fAED,yBACC,2BACA,+BACA,kBACA,eACA,aACA,cACA,UACA,aACA,YACA,SACA,kBACA,QACA,wCACA,kBACA,iBACA,+BACC,aACA,gBAGD,sCACC,aACA,gBAEF,qBACC,aACA,mBACA,iBACA,uBACA,uBACA,mBACA,eACA,sBACA,2fACA,2BACC,qBACA,WACA,+BACA,kBACA,iBACA,WACA,YACA,YACA,aACA,iCACC,aACA,gBACD,uCACC,gBACD,sCACC,iBACF,0BACC,iBACA,gBACH,wCAEC,2CAEA,aACC,gBACA,SACA,UACA,gBACC,qBACA,iCACA,8CACA,gBACA,kBACA,kBACC,aACA,8BACC,eAED,wBACC,qBAEL,kBACC,aACA,eACA,iBACA,mBACA,iBACA,YACA,cACA,2BACA,uBACD,sBACC,iBACA,YACA,cACA,kBACD,mBACC,cACA,SACA,UACA,gBACA,kDACA,sBACC,WACA,SACA,UACA,sCACD,yBACC,cACA,YACA,iBACA,0CACA,sBACA,gBACA,sBACA,+BACC,sBACH,uBACC,aACA,sBACA,iBACA,2BACA,8BACC,gBACA,yBACA,iBACA,gCACC,oBACH,gBACC,aACA,mBACA,yBACA,iBACA,qBACC,WAGF,OACC,YACA,aACA,mBACA,uBACA,mBACA,WACC,eACF,kBACC,SACA,UACA,gBACA,aACA,sBACA,2BACA,uBACA,WACA,YACA,qBACC,aACA,SACA,UACA,cACA,8BACA,mBACA,WACA,gBACA,mBAEF,oBACC,gDAED,mBACC,+CACA,iBAED,gBACC,YACA,gBACA,aACA,mBACA,WACA,2BACA,uBACA,0BAED,cACC,SACA,gCACA,6CACA,WACA,cACA,cACA,8BACA,mBACA,eACA,YACA,cACA,aACA,mBCnRD,WACC,aACA,iBACA,mBACD,kBACC,aACA,6CACA,UACA,cACA,mBACA,cACA,wBACC,mBACA,0BACA,gBACA,eACA,mBACA,uCACA,kBACA,yBACF,mBACC,eACA,mBACD,iBACC,aACA,aACA,aAEC,iCACC,YACA,aACH,mCAEC,8BACA,2CACA,cACA,WACA,eCrCD,mCAEC,0BACA,6CACA,kBACA,8BAMD,0BAEC,sBACD,cACC,aACA,uBACA,mBACA,iBACA,cACA,eAEC,uBACC,iBACA,UACA,SACH,WACC,aACA,sBACD,iBACC,mBACA,eACA,8BACA,aACD,gBACC,eACA,yBACA,cACD,kBACC,gBACA,iBACD,cACC,iBACA,iBACA,yBACA,gBACA,kBC5CC,0BACC,gCACA,uCACA,kBACA,gBACA,eACA,iBACA,yBACA,6BACA,mBACA,0CAEC,iCACC,kBACA,cACA,mCACC,mBAGD,wCACC,WACA,kBACA,kCACA,kDACA,oBAEA,+CACC,mBACA,sDACA,uDACA,wDACA,6BACJ,kCACC,gCACA,qBACA,iBACA,mBAGJ,wBACC,yBAED,QACC,iBACA,YACA,aACA,2BACA,oBACD,YACC,gBACA,YACD,SACC,YACA,sBACA,gBACC,wBCvDA,2BACC,cAEF,mCACC,kBACA,UACA,UACA,aACA,sBACA,WACA,yCACC,YACA,kBACA,aACA,oBACA,mBACA,qBACA,uCACA,gCACA,+BACA,eACA,0BACA,cACA,gDACC,iBACA,SACA,uCACA,uDACC,iBACA,6BACF,gDACC,WACA,kBACA,aACA,2CACA,oBACD,2CACC,kBCvCJ,oBACC,qBACA,iBAEC,uCACC,mBAEH,iBACC,aACA,wBACA,WACA,cACD,WACC,aACA,qBACA,WACA,kBACA,uBACA,mBACC,6CACA,mBACA,6BACC,yBACA,eACA,yCACC,iBACA,eACA,mBACA,2CACC,mBAEF,qCACC,6CACA,gCAED,qCACC,0CACA,kCAED,gCACC,iBACA,2CACC,kBAEH,+BACC,uCACH,gBACC,kBACD,UACC,aACA,YACA,eACA,iBACA,mBACA,gCACA,2BACA,uBACA,iBACA,wBACC,sBACA,kBAEC,2CACC,mBACH,YACC,WACD,uBACC,mBAIC,6BACC,2CAGD,6BACC,6CACJ,cACC,gDACA,+BACA,wBACC,eACA,iBACA,oCACC,kBACD,0BACC,iBACH,iBACC,uBACA,kBACD,eACC,qBACD,gBACC,sBACD,wBACC,8BACD,YACC,gBACD,YACC,cACD,aACC,eACD,aACC,gBACD,aACC,gBACD,aACC,eACD,aACC,eACD,aACC,eACD,aACC,eACD,aACC,eACD,aACC,eACD,aACC,eACD,aACC,eACD,aACC,eACD,kBACC,eACA,YACA,eACA,gBACA,kBAGC,2BACC,oCAEA,kCACC,6BACJ,iBACC,gBACA,eACA,cACA,qBACA,gCACD,mBACC,aACA,wBACA,OACA,6BACC,cACA,oDACF,8DAEC,gBAGC,qCACC,eAGD,gDACC,kBACH,cACC,kBACA,UACA,eACA,YACA,yBACA,iCACA,yBACA,gBACA,kBACA","file":"mgt2.min.css"}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<form class="{{cssClass}} flexcol" autocomplete="off" style="align-content: flex-start;align-items: baseline;overflow: hidden;height: 100%;">
|
<div class="{{cssClass}} flexcol" style="align-content: flex-start;align-items: baseline;overflow: hidden;height: 100%;">
|
||||||
<nav class="sheet-sidebar tabs" data-group="sidebar">
|
<nav class="sheet-sidebar tabs" data-group="sidebar">
|
||||||
<!-- <a class="item tab-select" data-tab="personal" title="Personal"><i class="fa-solid fa-id-card"></i></a> -->
|
<!-- <a class="item tab-select" data-tab="personal" title="Personal"><i class="fa-solid fa-id-card"></i></a> -->
|
||||||
<a class="item tab-select" data-tab="health" title="{{ localize 'MGT2.Actor.Health' }}"><i class="fa-solid fa-heart-pulse"></i></a>
|
<a class="item tab-select" data-tab="health" title="{{ localize 'MGT2.Actor.Health' }}"><i class="fa-solid fa-heart-pulse"></i></a>
|
||||||
@@ -745,4 +745,4 @@
|
|||||||
<div><a name="config" title="Config" style="margin-right: 0.5rem;"><i class="fa-solid fa-gear"></i></a></div>
|
<div><a name="config" title="Config" style="margin-right: 0.5rem;"><i class="fa-solid fa-gear"></i></a></div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<form class="{{cssClass}} itemsheet" autocomplete="off">
|
<div class="{{cssClass}} itemsheet">
|
||||||
<div class="itemsheet-header">
|
<div class="itemsheet-header">
|
||||||
<label>{{localize 'MGT2.TYPES.Item.armor'}}</label>
|
<label>{{localize 'MGT2.TYPES.Item.armor'}}</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -71,4 +71,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<form class="{{cssClass}} itemsheet" autocomplete="off">
|
<div class="{{cssClass}} itemsheet">
|
||||||
<div class="itemsheet-header"><label class="upcase">{{ localize 'MGT2.Items.Career' }}</label></div>
|
<div class="itemsheet-header"><label class="upcase">{{ localize 'MGT2.Items.Career' }}</label></div>
|
||||||
<div class="itemsheet-panel">
|
<div class="itemsheet-panel">
|
||||||
<div class="itemsheet-maincol">
|
<div class="itemsheet-maincol">
|
||||||
@@ -47,4 +47,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<form class="{{cssClass}} itemsheet" autocomplete="off">
|
<div class="{{cssClass}} itemsheet">
|
||||||
<div class="itemsheet-header">
|
<div class="itemsheet-header">
|
||||||
<label>{{localize 'MGT2.EquipmentSubType.computer'}}</label>
|
<label>{{localize 'MGT2.EquipmentSubType.computer'}}</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -62,4 +62,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<form class="{{cssClass}} itemsheet" autocomplete="off">
|
<div class="{{cssClass}} itemsheet">
|
||||||
<div class="itemsheet-header"><label class="upcase">{{ localize 'MGT2.Items.Contact' }}</label></div>
|
<div class="itemsheet-header"><label class="upcase">{{ localize 'MGT2.Items.Contact' }}</label></div>
|
||||||
<div class="itemsheet-panel">
|
<div class="itemsheet-panel">
|
||||||
<div class="itemsheet-maincol">
|
<div class="itemsheet-maincol">
|
||||||
@@ -81,4 +81,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<form class="{{cssClass}} itemsheet" autocomplete="off">
|
<div class="{{cssClass}} itemsheet">
|
||||||
<div class="itemsheet-header"><label class="upcase">{{ localize 'MGT2.Items.Container' }}</label></div>
|
<div class="itemsheet-header"><label class="upcase">{{ localize 'MGT2.Items.Container' }}</label></div>
|
||||||
<div class="itemsheet-panel">
|
<div class="itemsheet-panel">
|
||||||
<div class="itemsheet-maincol">
|
<div class="itemsheet-maincol">
|
||||||
@@ -52,4 +52,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<form class="{{cssClass}} itemsheet" autocomplete="off">
|
<div class="{{cssClass}} itemsheet">
|
||||||
<div class="itemsheet-header">
|
<div class="itemsheet-header">
|
||||||
{{#if (eq system.subType "disease")}}
|
{{#if (eq system.subType "disease")}}
|
||||||
<label>{{localize 'MGT2.DiseaseSubType.disease'}}</label>
|
<label>{{localize 'MGT2.DiseaseSubType.disease'}}</label>
|
||||||
@@ -42,4 +42,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<form class="{{cssClass}} itemsheet" autocomplete="off">
|
<div class="{{cssClass}} itemsheet">
|
||||||
<div class="itemsheet-header">
|
<div class="itemsheet-header">
|
||||||
{{#if (eq system.subType "augment")}}
|
{{#if (eq system.subType "augment")}}
|
||||||
<label>{{localize 'MGT2.EquipmentSubType.augment'}}</label>
|
<label>{{localize 'MGT2.EquipmentSubType.augment'}}</label>
|
||||||
@@ -54,4 +54,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<form class="{{cssClass}} itemsheet" autocomplete="off">
|
<div class="{{cssClass}} itemsheet">
|
||||||
<div class="itemsheet-header">
|
<div class="itemsheet-header">
|
||||||
{{#if (eq system.subType "loot")}}
|
{{#if (eq system.subType "loot")}}
|
||||||
<label>{{localize 'MGT2.ItemSubType.loot'}}</label>
|
<label>{{localize 'MGT2.ItemSubType.loot'}}</label>
|
||||||
@@ -57,4 +57,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<form class="{{cssClass}} itemsheet" autocomplete="off">
|
<div class="{{cssClass}} itemsheet">
|
||||||
<div class="itemsheet-header"><label>{{ localize 'MGT2.Specie' }}</label></div>
|
<div class="itemsheet-header"><label>{{ localize 'MGT2.Specie' }}</label></div>
|
||||||
<div class="itemsheet-panel">
|
<div class="itemsheet-panel">
|
||||||
<div class="itemsheet-maincol">
|
<div class="itemsheet-maincol">
|
||||||
@@ -67,4 +67,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<form class="{{cssClass}} flexrow itemsheet" autocomplete="off">
|
<div class="{{cssClass}} flexrow itemsheet">
|
||||||
<div class="itemsheet-header">
|
<div class="itemsheet-header">
|
||||||
{{#if (eq system.subType "skill")}}
|
{{#if (eq system.subType "skill")}}
|
||||||
<label>{{localize 'MGT2.TalentSubType.skill'}}</label>
|
<label>{{localize 'MGT2.TalentSubType.skill'}}</label>
|
||||||
@@ -76,4 +76,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<form class="{{cssClass}} itemsheet" autocomplete="off">
|
<div class="{{cssClass}} itemsheet">
|
||||||
<div class="itemsheet-header"><label class="upcase">{{ localize 'MGT2.Items.Weapon' }}</label></div>
|
<div class="itemsheet-header"><label class="upcase">{{ localize 'MGT2.Items.Weapon' }}</label></div>
|
||||||
<div class="itemsheet-panel">
|
<div class="itemsheet-panel">
|
||||||
<div class="itemsheet-maincol">
|
<div class="itemsheet-maincol">
|
||||||
@@ -86,4 +86,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
@@ -2,14 +2,14 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>{{ localize 'MGT2.RollPrompt.CharacteristicDM' }}</label>
|
<label>{{ localize 'MGT2.RollPrompt.CharacteristicDM' }}</label>
|
||||||
<select name="characteristic">
|
<select name="characteristic">
|
||||||
{{selectOptions characteristics selected=characteristic nameAttr="_id" labelAttr="name"}}
|
{{selectOptions characteristics selected=characteristic valueAttr="_id" labelAttr="name"}}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>{{ localize 'MGT2.RollPrompt.SkillDM' }}</label>
|
<label>{{ localize 'MGT2.RollPrompt.SkillDM' }}</label>
|
||||||
<select name="skill">
|
<select name="skill">
|
||||||
<option></option>
|
<option></option>
|
||||||
{{selectOptions skills selected=skill nameAttr="_id" labelAttr="name"}}
|
{{selectOptions skills selected=skill valueAttr="_id" labelAttr="name"}}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|||||||
Reference in New Issue
Block a user